From 8c611753789534760b3ad79af89c1764f2571e38 Mon Sep 17 00:00:00 2001 From: cedrick mandocdoc Date: Sat, 14 Apr 2018 12:44:54 +0800 Subject: [PATCH 1/5] wip for cms initial page --- package-lock.json | 479 +----------------- src/client/app/app-routing.module.ts | 1 + src/client/app/app.component.ts | 20 +- .../cms/cms-footer/cms-footer.component.html | 11 + .../cms/cms-footer/cms-footer.component.scss | 13 + .../cms/cms-footer/cms-footer.component.ts | 14 + .../cms/cms-header/cms-header.component.html | 1 + .../cms/cms-header/cms-header.component.scss | 8 + .../cms/cms-header/cms-header.component.ts | 14 + src/client/app/cms/cms-routing.module.ts | 23 + .../cms-sidenav/cms-sidenav.component.html | 8 + .../cms-sidenav/cms-sidenav.component.scss | 26 + .../cms/cms-sidenav/cms-sidenav.component.ts | 22 + src/client/app/cms/cms.component.html | 12 + src/client/app/cms/cms.component.scss | 19 + src/client/app/cms/cms.component.ts | 13 + src/client/app/cms/cms.module.ts | 26 + src/client/app/core/services/user.service.ts | 1 + .../app/public/login/login.component.ts | 2 +- src/server/app.module.ts | 26 +- src/server/app/core/index.ts | 3 + .../middlewares/access-token.middleware.ts | 23 + src/server/app/users/user.controller.test.ts | 7 +- src/server/app/users/user.controller.ts | 9 +- src/server/app/users/user.service.ts | 6 + 25 files changed, 317 insertions(+), 470 deletions(-) create mode 100644 src/client/app/cms/cms-footer/cms-footer.component.html create mode 100644 src/client/app/cms/cms-footer/cms-footer.component.scss create mode 100644 src/client/app/cms/cms-footer/cms-footer.component.ts create mode 100644 src/client/app/cms/cms-header/cms-header.component.html create mode 100644 src/client/app/cms/cms-header/cms-header.component.scss create mode 100644 src/client/app/cms/cms-header/cms-header.component.ts create mode 100644 src/client/app/cms/cms-routing.module.ts create mode 100644 src/client/app/cms/cms-sidenav/cms-sidenav.component.html create mode 100644 src/client/app/cms/cms-sidenav/cms-sidenav.component.scss create mode 100644 src/client/app/cms/cms-sidenav/cms-sidenav.component.ts create mode 100644 src/client/app/cms/cms.component.html create mode 100644 src/client/app/cms/cms.component.scss create mode 100644 src/client/app/cms/cms.component.ts create mode 100644 src/client/app/cms/cms.module.ts create mode 100644 src/server/app/core/middlewares/access-token.middleware.ts diff --git a/package-lock.json b/package-lock.json index 5b6ea9e..5e2a7d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "gauntlet", - "version": "0.0.1", + "version": "0.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -277,21 +277,6 @@ "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", "dev": true }, - "@types/babel-types": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.1.tgz", - "integrity": "sha512-EkcOk09rjhivbovP8WreGRbXW20YRfe/qdgXOGq3it3u3aAOWDRNsQhL/XPAWFF7zhZZ+uR+nT+3b+TCkIap1w==", - "dev": true - }, - "@types/babylon": { - "version": "6.16.2", - "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.2.tgz", - "integrity": "sha512-+Jty46mPaWe1VAyZbfvgJM4BAdklLWxrT5tc/RjvCgLrtk6gzRY6AOnoWFv4p6hVxhJshDdr2hGVn56alBp97Q==", - "dev": true, - "requires": { - "@types/babel-types": "7.0.1" - } - }, "@types/bcrypt": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-1.0.0.tgz", @@ -716,12 +701,6 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true - }, "asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", @@ -1850,7 +1829,8 @@ "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==" + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true }, "binary-extensions": { "version": "1.11.0", @@ -2329,6 +2309,7 @@ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, + "optional": true, "requires": { "align-text": "0.1.4", "lazy-cache": "1.0.4" @@ -2373,15 +2354,6 @@ } } }, - "character-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", - "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=", - "dev": true, - "requires": { - "is-regex": "1.0.4" - } - }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", @@ -3000,26 +2972,6 @@ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, - "constantinople": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz", - "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==", - "dev": true, - "requires": { - "@types/babel-types": "7.0.1", - "@types/babylon": "6.16.2", - "babel-types": "6.26.0", - "babylon": "6.18.0" - }, - "dependencies": { - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true - } - } - }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -3224,17 +3176,6 @@ "source-list-map": "2.0.0" } }, - "css-loading": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/css-loading/-/css-loading-1.4.0.tgz", - "integrity": "sha1-RekjVnRcjtBrVhDYwXxfX7orUsU=" - }, - "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", - "dev": true - }, "css-select": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", @@ -3258,27 +3199,6 @@ "regexpu-core": "1.0.0" } }, - "css-to-string-loader": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/css-to-string-loader/-/css-to-string-loader-0.1.3.tgz", - "integrity": "sha1-yTcXXy7Hg5aa7+FKT7oFX3tPlWI=", - "requires": { - "loader-utils": "0.2.17" - }, - "dependencies": { - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } - } - } - }, "css-what": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", @@ -3588,12 +3508,6 @@ "randombytes": "2.0.6" } }, - "doctypes": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", - "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=", - "dev": true - }, "dom-converter": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", @@ -3794,7 +3708,8 @@ "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=" + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true }, "encodeurl": { "version": "1.0.2", @@ -3951,11 +3866,6 @@ } } }, - "es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" - }, "es6-symbol": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", @@ -6976,24 +6886,6 @@ "is-primitive": "2.0.0" } }, - "is-expression": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz", - "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=", - "dev": true, - "requires": { - "acorn": "4.0.13", - "object-assign": "4.1.1" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } - } - }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -8231,12 +8123,6 @@ "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=" }, - "js-stringify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", - "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds=", - "dev": true - }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", @@ -8498,7 +8384,8 @@ "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true }, "jsonify": { "version": "0.0.0", @@ -8547,16 +8434,6 @@ "verror": "1.10.0" } }, - "jstransformer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=", - "dev": true, - "requires": { - "is-promise": "2.1.0", - "promise": "7.3.1" - } - }, "jwa": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz", @@ -8597,7 +8474,8 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true + "dev": true, + "optional": true }, "lcid": { "version": "1.0.0", @@ -10161,6 +10039,11 @@ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", "dev": true }, + "normalize-scss": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/normalize-scss/-/normalize-scss-7.0.1.tgz", + "integrity": "sha512-qj16bWnYs+9/ac29IgGjySg4R5qQTp1lXfm7ApFOZNVBYFY8RZ3f8+XQNDDLHeDtI3Ba7Jj4+LuPgz9v/fne2A==" + }, "normalize-url": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", @@ -11525,15 +11408,6 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "requires": { - "asap": "2.0.6" - } - }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -11573,204 +11447,6 @@ "randombytes": "2.0.6" } }, - "pug": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.3.tgz", - "integrity": "sha1-ccuoJTfJWl6rftBGluQiH1Oqh44=", - "dev": true, - "requires": { - "pug-code-gen": "2.0.1", - "pug-filters": "3.1.0", - "pug-lexer": "4.0.0", - "pug-linker": "3.0.5", - "pug-load": "2.0.11", - "pug-parser": "5.0.0", - "pug-runtime": "2.0.4", - "pug-strip-comments": "1.0.3" - } - }, - "pug-attrs": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.3.tgz", - "integrity": "sha1-owlflw5kFR972tlX7vVftdeQXRU=", - "dev": true, - "requires": { - "constantinople": "3.1.2", - "js-stringify": "1.0.2", - "pug-runtime": "2.0.4" - } - }, - "pug-code-gen": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.1.tgz", - "integrity": "sha1-CVHsgyJddNjPxHan+Zolm199BQw=", - "dev": true, - "requires": { - "constantinople": "3.1.2", - "doctypes": "1.1.0", - "js-stringify": "1.0.2", - "pug-attrs": "2.0.3", - "pug-error": "1.3.2", - "pug-runtime": "2.0.4", - "void-elements": "2.0.1", - "with": "5.1.1" - } - }, - "pug-error": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.2.tgz", - "integrity": "sha1-U659nSm7A89WRJOgJhCfVMR/XyY=", - "dev": true - }, - "pug-filters": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.0.tgz", - "integrity": "sha1-JxZVVbwEwjbkqisDZiRt+gIbYm4=", - "dev": true, - "requires": { - "clean-css": "4.1.11", - "constantinople": "3.1.2", - "jstransformer": "1.0.0", - "pug-error": "1.3.2", - "pug-walk": "1.1.7", - "resolve": "1.5.0", - "uglify-js": "2.8.29" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - } - }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - } - } - } - }, - "pug-html-loader": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/pug-html-loader/-/pug-html-loader-1.1.5.tgz", - "integrity": "sha512-EOcLK0z0vJ1fSXsDypqL8SsPXVaevS9Oy8JA1RpYYkgAOV9qJXCSedvMYw499hSXxmoXAXIV1qEF2fNFBTwyEQ==", - "dev": true, - "requires": { - "loader-utils": "0.2.17", - "pug": "2.0.3" - }, - "dependencies": { - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } - } - } - }, - "pug-lexer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.0.0.tgz", - "integrity": "sha1-IQwYRX7y4XYCQnQMXmR715TOwng=", - "dev": true, - "requires": { - "character-parser": "2.2.0", - "is-expression": "3.0.0", - "pug-error": "1.3.2" - } - }, - "pug-linker": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.5.tgz", - "integrity": "sha1-npp65ABWgtAn3uuWsAD4juuDoC8=", - "dev": true, - "requires": { - "pug-error": "1.3.2", - "pug-walk": "1.1.7" - } - }, - "pug-load": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.11.tgz", - "integrity": "sha1-5kjlftET/iwfRdV4WOorrWvAFSc=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "pug-walk": "1.1.7" - } - }, - "pug-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.0.tgz", - "integrity": "sha1-45Stmz/KkxI5QK/4hcBuRKt+aOQ=", - "dev": true, - "requires": { - "pug-error": "1.3.2", - "token-stream": "0.0.1" - } - }, - "pug-runtime": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.4.tgz", - "integrity": "sha1-4XjhvaaKsujArPybztLFT9iM61g=", - "dev": true - }, - "pug-strip-comments": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.3.tgz", - "integrity": "sha1-8VWVkiBu3G+FMQ2s9K+0igJa9Z8=", - "dev": true, - "requires": { - "pug-error": "1.3.2" - } - }, - "pug-walk": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.7.tgz", - "integrity": "sha1-wA1cUSi6xYBr7BXSt+fNq+QlMfM=", - "dev": true - }, "pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", @@ -12374,6 +12050,7 @@ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, + "optional": true, "requires": { "align-text": "0.1.4" } @@ -13609,82 +13286,6 @@ "schema-utils": "0.4.5" } }, - "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", - "dev": true, - "requires": { - "css-parse": "1.7.0", - "debug": "3.1.0", - "glob": "7.0.6", - "mkdirp": "0.5.1", - "sax": "0.5.8", - "source-map": "0.1.43" - }, - "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", - "dev": true - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "stylus-relative-loader": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/stylus-relative-loader/-/stylus-relative-loader-3.4.0.tgz", - "integrity": "sha1-D1p09UMHPOdcF+AemRoQeGTLReI=", - "requires": { - "debug": "2.6.9", - "es6-promise": "3.3.1", - "loader-utils": "0.2.17" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } - } - } - }, "superagent": { "version": "3.8.2", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.2.tgz", @@ -14155,12 +13756,6 @@ "repeat-string": "1.6.1" } }, - "token-stream": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz", - "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=", - "dev": true - }, "toposort": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz", @@ -14825,12 +14420,6 @@ "indexof": "0.0.1" } }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, "w3c-hr-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", @@ -15303,42 +14892,8 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, - "with": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz", - "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=", "dev": true, - "requires": { - "acorn": "3.3.0", - "acorn-globals": "3.1.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - }, - "acorn-globals": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", - "dev": true, - "requires": { - "acorn": "4.0.13" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } - } - } - } + "optional": true }, "wordwrap": { "version": "0.0.3", diff --git a/src/client/app/app-routing.module.ts b/src/client/app/app-routing.module.ts index de26408..a303707 100644 --- a/src/client/app/app-routing.module.ts +++ b/src/client/app/app-routing.module.ts @@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: '', loadChildren: './public/public.module#PublicModule' }, + { path: 'cms', loadChildren: './cms/cms.module#CmsModule' }, { path: '**', redirectTo: '' } ]; diff --git a/src/client/app/app.component.ts b/src/client/app/app.component.ts index 74336cf..4150469 100644 --- a/src/client/app/app.component.ts +++ b/src/client/app/app.component.ts @@ -1,5 +1,9 @@ import { Component, OnInit } from '@angular/core'; +import { UserService } from './core'; + +import { User } from '../../common/entities'; + @Component({ selector: 'app', templateUrl: 'app.component.html' @@ -7,7 +11,19 @@ import { Component, OnInit } from '@angular/core'; export class AppComponent implements OnInit { - constructor() {} + constructor( + private userService: UserService + ) {} + + public ngOnInit() { + this.getMe(); + } + + private getMe() { + this.userService.getMe().subscribe((user: User) => { + + }, (error: Error) => { - public ngOnInit() {} + }); + } } diff --git a/src/client/app/cms/cms-footer/cms-footer.component.html b/src/client/app/cms/cms-footer/cms-footer.component.html new file mode 100644 index 0000000..92f0e91 --- /dev/null +++ b/src/client/app/cms/cms-footer/cms-footer.component.html @@ -0,0 +1,11 @@ + + \ No newline at end of file diff --git a/src/client/app/cms/cms-footer/cms-footer.component.scss b/src/client/app/cms/cms-footer/cms-footer.component.scss new file mode 100644 index 0000000..63103c2 --- /dev/null +++ b/src/client/app/cms/cms-footer/cms-footer.component.scss @@ -0,0 +1,13 @@ +@import '../../../stylesheets/palette.scss'; + +section.footer { + padding: 20px; + color: white; + background-color: $primary-color; +} + +section.footer-credit { + padding: 20px; + color: white; + background-color: $primary-color-dark; +} diff --git a/src/client/app/cms/cms-footer/cms-footer.component.ts b/src/client/app/cms/cms-footer/cms-footer.component.ts new file mode 100644 index 0000000..d8a475b --- /dev/null +++ b/src/client/app/cms/cms-footer/cms-footer.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'cms-footer', + templateUrl: 'cms-footer.component.html', + styleUrls: ['cms-footer.component.scss'] +}) + +export class CmsFooterComponent implements OnInit { + + public constructor() { } + + public ngOnInit() { } +} diff --git a/src/client/app/cms/cms-header/cms-header.component.html b/src/client/app/cms/cms-header/cms-header.component.html new file mode 100644 index 0000000..68adf2e --- /dev/null +++ b/src/client/app/cms/cms-header/cms-header.component.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/src/client/app/cms/cms-header/cms-header.component.scss b/src/client/app/cms/cms-header/cms-header.component.scss new file mode 100644 index 0000000..c4f038c --- /dev/null +++ b/src/client/app/cms/cms-header/cms-header.component.scss @@ -0,0 +1,8 @@ +@import '../../../stylesheets/palette.scss'; + +header { + display: block; + width: 100%; + height: 70px; + background-color: $primary-color; +} diff --git a/src/client/app/cms/cms-header/cms-header.component.ts b/src/client/app/cms/cms-header/cms-header.component.ts new file mode 100644 index 0000000..f165510 --- /dev/null +++ b/src/client/app/cms/cms-header/cms-header.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'cms-header', + templateUrl: 'cms-header.component.html', + styleUrls: ['cms-header.component.scss'] +}) + +export class CmsHeaderComponent implements OnInit { + + public constructor() { } + + public ngOnInit() { } +} diff --git a/src/client/app/cms/cms-routing.module.ts b/src/client/app/cms/cms-routing.module.ts new file mode 100644 index 0000000..1408970 --- /dev/null +++ b/src/client/app/cms/cms-routing.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { CmsComponent } from './cms.component'; + +const routes: Routes = [ + { + path: '', + component: CmsComponent, + children: [ + ] + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class CmsRoutingModule { } + +export const routedComponents = [ + CmsComponent +]; diff --git a/src/client/app/cms/cms-sidenav/cms-sidenav.component.html b/src/client/app/cms/cms-sidenav/cms-sidenav.component.html new file mode 100644 index 0000000..4e03837 --- /dev/null +++ b/src/client/app/cms/cms-sidenav/cms-sidenav.component.html @@ -0,0 +1,8 @@ + + + Home + Logout + \ No newline at end of file diff --git a/src/client/app/cms/cms-sidenav/cms-sidenav.component.scss b/src/client/app/cms/cms-sidenav/cms-sidenav.component.scss new file mode 100644 index 0000000..99d6a10 --- /dev/null +++ b/src/client/app/cms/cms-sidenav/cms-sidenav.component.scss @@ -0,0 +1,26 @@ +@import '../../../stylesheets/palette.scss'; + +.logo { + position: relative; + width: 100%; + height: 240px; + background-color: $primary-color; + + p { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: white; + } +} + +mat-list { + a { + text-decoration: none; + cursor: pointer; + } + a.active, a:hover { + background-color: rgba($color: #000000, $alpha: 0.2); + } +} \ No newline at end of file diff --git a/src/client/app/cms/cms-sidenav/cms-sidenav.component.ts b/src/client/app/cms/cms-sidenav/cms-sidenav.component.ts new file mode 100644 index 0000000..644a550 --- /dev/null +++ b/src/client/app/cms/cms-sidenav/cms-sidenav.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit } from '@angular/core'; + +import { UserService } from '../../core'; + +@Component({ + selector: 'cms-sidenav', + templateUrl: 'cms-sidenav.component.html', + styleUrls: ['cms-sidenav.component.scss'] +}) + +export class CmsSidenavComponent implements OnInit { + + public constructor( + private userService: UserService + ) { } + + public ngOnInit() { } + + public onClickLogout() { + this.userService.logout(); + } +} diff --git a/src/client/app/cms/cms.component.html b/src/client/app/cms/cms.component.html new file mode 100644 index 0000000..5f90dea --- /dev/null +++ b/src/client/app/cms/cms.component.html @@ -0,0 +1,12 @@ + + + + + + +
+ +
+ +
+
diff --git a/src/client/app/cms/cms.component.scss b/src/client/app/cms/cms.component.scss new file mode 100644 index 0000000..2d6ca92 --- /dev/null +++ b/src/client/app/cms/cms.component.scss @@ -0,0 +1,19 @@ +.sidenav-container { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background: white; +} + +mat-sidenav { + width: 240px; + box-shadow: 3px 0 6px rgba(0, 0, 0, 0.3); +} + +section.cms-container { + width: 90%; + min-height: 100vh; + margin: 0 auto; +} \ No newline at end of file diff --git a/src/client/app/cms/cms.component.ts b/src/client/app/cms/cms.component.ts new file mode 100644 index 0000000..c64688d --- /dev/null +++ b/src/client/app/cms/cms.component.ts @@ -0,0 +1,13 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'cms', + templateUrl: 'cms.component.html', + styleUrls: ['cms.component.scss'] +}) +export class CmsComponent implements OnInit { + + public constructor() { } + + public ngOnInit() { } +} diff --git a/src/client/app/cms/cms.module.ts b/src/client/app/cms/cms.module.ts new file mode 100644 index 0000000..f9469e6 --- /dev/null +++ b/src/client/app/cms/cms.module.ts @@ -0,0 +1,26 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; + +import { SharedModule } from '../shared'; + +import { CmsRoutingModule, routedComponents } from './cms-routing.module'; + +import { CmsFooterComponent } from './cms-footer/cms-footer.component'; +import { CmsHeaderComponent } from './cms-header/cms-header.component'; +import { CmsSidenavComponent } from './cms-sidenav/cms-sidenav.component'; + +@NgModule({ + imports: [ + SharedModule, + CmsRoutingModule + ], + exports: [], + declarations: [ + routedComponents, + CmsFooterComponent, + CmsHeaderComponent, + CmsSidenavComponent + ], + providers: [] +}) +export class CmsModule { } diff --git a/src/client/app/core/services/user.service.ts b/src/client/app/core/services/user.service.ts index 97a7af2..c4a02e4 100644 --- a/src/client/app/core/services/user.service.ts +++ b/src/client/app/core/services/user.service.ts @@ -51,6 +51,7 @@ export class UserService { public getMe(): Observable { return this.apiService.get(`/users/me`) .do((user: User) => { + console.log('current user', user); this.currentUserSource.next(user); }, (error: Error) => { this.currentUserSource.next(null); diff --git a/src/client/app/public/login/login.component.ts b/src/client/app/public/login/login.component.ts index c48d97b..494a765 100644 --- a/src/client/app/public/login/login.component.ts +++ b/src/client/app/public/login/login.component.ts @@ -39,7 +39,7 @@ export class LoginComponent implements OnInit { private login(data: {email: string, password: string}) { this.userService.login(data).subscribe((data) => { - this.router.navigateByUrl('/'); + this.router.navigateByUrl('/cms'); this.dialogService.openAlertDialog({ title: 'Success', content: 'You are now login' diff --git a/src/server/app.module.ts b/src/server/app.module.ts index 70180a1..fc86349 100644 --- a/src/server/app.module.ts +++ b/src/server/app.module.ts @@ -1,4 +1,6 @@ -import { Module } from '@nestjs/common'; +import { MiddlewaresConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; + +import { AccessTokenMiddleware } from './app/core/middlewares/access-token.middleware'; import { UserModule } from './app/users'; @@ -8,4 +10,24 @@ import { UserModule } from './app/users'; ], components: [] }) -export class AppModule {} +export class AppModule implements NestModule { + + public configure(consumer: MiddlewaresConsumer) { + consumer + // .apply((req, res, next) => { + // console.log('asdsa111d'); + // next(); + // }) + .apply([ + (req, res, next) => { + console.log('test'); + next(); + }, + AccessTokenMiddleware + ]) + .forRoutes({ + path: '*', + method: RequestMethod.ALL + }); + } +} diff --git a/src/server/app/core/index.ts b/src/server/app/core/index.ts index b8c90b4..2f150ff 100644 --- a/src/server/app/core/index.ts +++ b/src/server/app/core/index.ts @@ -4,3 +4,6 @@ export * from './core.module'; // core services export * from './services/bcrypt.service'; export * from './services/jsonwebtoken.service'; + +// core middlewares +// export * from './middlewares/access-token.middleware'; diff --git a/src/server/app/core/middlewares/access-token.middleware.ts b/src/server/app/core/middlewares/access-token.middleware.ts new file mode 100644 index 0000000..cae1035 --- /dev/null +++ b/src/server/app/core/middlewares/access-token.middleware.ts @@ -0,0 +1,23 @@ +import { ExpressMiddleware, Middleware, NestMiddleware } from '@nestjs/common'; +import { JsonWebTokenService } from '..'; + +@Middleware() +export class AccessTokenMiddleware implements NestMiddleware { + + constructor( + private jwtService: JsonWebTokenService + ) { } + + public resolve(...args: any[]): ExpressMiddleware { + return (request, response, next) => { + const headers = request.headers; + const accessToken = headers.accessToken || headers['x-access-token']; + console.log(accessToken); + const user = this.jwtService.verify(accessToken); + if (user) { + request.user = user; + } + next(); + }; + } +} diff --git a/src/server/app/users/user.controller.test.ts b/src/server/app/users/user.controller.test.ts index 8fdb34b..a7bd581 100644 --- a/src/server/app/users/user.controller.test.ts +++ b/src/server/app/users/user.controller.test.ts @@ -5,9 +5,10 @@ import { INestApplication } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { expect } from 'chai'; +import { AppModule } from '../../app.module'; import { setupNestApplication } from '../../setup'; import { DatabaseModule, DatabaseService } from '../database'; -import { UserModule } from './user.module'; +// import { UserModule } from './user.module'; describe('UserController', () => { const expressServer = express(); @@ -18,7 +19,9 @@ describe('UserController', () => { beforeAll(async () => { const module = await Test.createTestingModule({ - imports: [ UserModule ] + imports: [ + AppModule + ] }).compile(); app = await module.createNestApplication(expressServer); diff --git a/src/server/app/users/user.controller.ts b/src/server/app/users/user.controller.ts index 8132e95..555ac90 100644 --- a/src/server/app/users/user.controller.ts +++ b/src/server/app/users/user.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Get, Post } from '@nestjs/common'; +import { Body, Controller, Get, Param, Post } from '@nestjs/common'; import { User } from './user.entity'; import { UserService } from './user.service'; @@ -16,6 +16,13 @@ export class UserController { return this.userService.login({email, password}); } + @Get(':id') + public getUserById( + @Param('id') id: number + ): Promise { + return this.userService.getUserById(id); + } + @Get() public getUsers() { return this.userService.getUsers(); diff --git a/src/server/app/users/user.service.ts b/src/server/app/users/user.service.ts index b80fc5e..d738b46 100644 --- a/src/server/app/users/user.service.ts +++ b/src/server/app/users/user.service.ts @@ -30,6 +30,12 @@ export class UserService { return { user, token }; } + public getUserById(id: number): Promise { + return this.userRepository.findOneById(id, { + relations: ['roles'] + }); + } + public async getUsers() { return this.userRepository.getUsers({}); } From acfab1be0e1296a62c9f4e07392d4d2533c76041 Mon Sep 17 00:00:00 2001 From: cedrick mandocdoc Date: Mon, 16 Apr 2018 21:57:19 +0800 Subject: [PATCH 2/5] wip for current user in cms initial page --- src/client/app/core/services/api.service.ts | 2 +- src/server/app.module.ts | 3 ++- .../core/decorators/current-user.decorator.ts | 5 +++++ src/server/app/core/index.ts | 3 +++ .../middlewares/access-token.middleware.ts | 10 ++-------- .../app/core/services/jsonwebtoken.service.ts | 7 ++++++- src/server/app/users/user.controller.test.ts | 20 ++++++++++++++++++- src/server/app/users/user.controller.ts | 12 ++++++----- 8 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 src/server/app/core/decorators/current-user.decorator.ts diff --git a/src/client/app/core/services/api.service.ts b/src/client/app/core/services/api.service.ts index 63aecc1..854a499 100644 --- a/src/client/app/core/services/api.service.ts +++ b/src/client/app/core/services/api.service.ts @@ -78,7 +78,7 @@ export class ApiService { }; if (this.accessToken) { - headers.Authorization = this.accessToken; + headers['X-Access-Token'] = this.accessToken; } return headers; diff --git a/src/server/app.module.ts b/src/server/app.module.ts index 6a74741..a112b22 100644 --- a/src/server/app.module.ts +++ b/src/server/app.module.ts @@ -1,11 +1,12 @@ import { MiddlewaresConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; -import { AccessTokenMiddleware, VersionMiddleware } from './app/core'; +import { AccessTokenMiddleware, CoreModule, VersionMiddleware } from './app/core'; import { UserModule } from './app/users'; @Module({ imports: [ + CoreModule, UserModule ], components: [] diff --git a/src/server/app/core/decorators/current-user.decorator.ts b/src/server/app/core/decorators/current-user.decorator.ts new file mode 100644 index 0000000..ac1ac43 --- /dev/null +++ b/src/server/app/core/decorators/current-user.decorator.ts @@ -0,0 +1,5 @@ +import { createRouteParamDecorator } from '@nestjs/common'; + +export const CurrentUser = createRouteParamDecorator((data, request) => { + return request.user; +}); diff --git a/src/server/app/core/index.ts b/src/server/app/core/index.ts index 09bf14e..62da94b 100644 --- a/src/server/app/core/index.ts +++ b/src/server/app/core/index.ts @@ -5,6 +5,9 @@ export * from './core.module'; export * from './services/bcrypt.service'; export * from './services/jsonwebtoken.service'; +// core decorators +export * from './decorators/current-user.decorator'; + // core middlewares export * from './middlewares/access-token.middleware'; export * from './middlewares/version-middleware'; diff --git a/src/server/app/core/middlewares/access-token.middleware.ts b/src/server/app/core/middlewares/access-token.middleware.ts index cae1035..a6a32e6 100644 --- a/src/server/app/core/middlewares/access-token.middleware.ts +++ b/src/server/app/core/middlewares/access-token.middleware.ts @@ -1,5 +1,5 @@ import { ExpressMiddleware, Middleware, NestMiddleware } from '@nestjs/common'; -import { JsonWebTokenService } from '..'; +import { JsonWebTokenService } from '../services/jsonwebtoken.service'; @Middleware() export class AccessTokenMiddleware implements NestMiddleware { @@ -10,13 +10,7 @@ export class AccessTokenMiddleware implements NestMiddleware { public resolve(...args: any[]): ExpressMiddleware { return (request, response, next) => { - const headers = request.headers; - const accessToken = headers.accessToken || headers['x-access-token']; - console.log(accessToken); - const user = this.jwtService.verify(accessToken); - if (user) { - request.user = user; - } + request.user = this.jwtService.verify(request.headers['X-Access-Token']); next(); }; } diff --git a/src/server/app/core/services/jsonwebtoken.service.ts b/src/server/app/core/services/jsonwebtoken.service.ts index 88edf6b..8ddf6e6 100644 --- a/src/server/app/core/services/jsonwebtoken.service.ts +++ b/src/server/app/core/services/jsonwebtoken.service.ts @@ -9,6 +9,11 @@ export class JsonWebTokenService { } public verify(token: any) { - return verify(token, 'secret'); + try { + const data = verify(token, 'secret'); + return data; + } catch (error) { + return; + } } } diff --git a/src/server/app/users/user.controller.test.ts b/src/server/app/users/user.controller.test.ts index a7bd581..7377354 100644 --- a/src/server/app/users/user.controller.test.ts +++ b/src/server/app/users/user.controller.test.ts @@ -8,13 +8,15 @@ import { expect } from 'chai'; import { AppModule } from '../../app.module'; import { setupNestApplication } from '../../setup'; import { DatabaseModule, DatabaseService } from '../database'; -// import { UserModule } from './user.module'; +import { UserModule } from './user.module'; +import { UserService } from './user.service'; describe('UserController', () => { const expressServer = express(); const server: supertest.SuperTest = supertest(expressServer); let app: INestApplication; + let userService: UserService; let databaseService: DatabaseService; beforeAll(async () => { @@ -26,6 +28,7 @@ describe('UserController', () => { app = await module.createNestApplication(expressServer); databaseService = app.select(DatabaseModule).get(DatabaseService); + userService = app.select(UserModule).get(UserService); setupNestApplication(app); await app.init(); @@ -75,6 +78,21 @@ describe('UserController', () => { }); }); + describe('getMe', async () => { + it('should return current user', async () => { + const data = await userService.login({ + email: `admin@test.com`, + password: `test` + }); + const response = await server + .get('/api/users/me') + .set('X-Access-Token', data.token) + .expect(200); + expect(response.body).to.be.an('object'); + expect(response.body).to.have.property('id', data.user.id); + }); + }); + describe('getUsers', async () => { it('should return 200 /api/users', () => { return server diff --git a/src/server/app/users/user.controller.ts b/src/server/app/users/user.controller.ts index 555ac90..d82b3f3 100644 --- a/src/server/app/users/user.controller.ts +++ b/src/server/app/users/user.controller.ts @@ -1,4 +1,6 @@ -import { Body, Controller, Get, Param, Post } from '@nestjs/common'; +import { Body, Controller, Get, Post } from '@nestjs/common'; + +import { CurrentUser } from '../core'; import { User } from './user.entity'; import { UserService } from './user.service'; @@ -16,11 +18,11 @@ export class UserController { return this.userService.login({email, password}); } - @Get(':id') - public getUserById( - @Param('id') id: number + @Get('me') + public getMe( + @CurrentUser() currentUser: User ): Promise { - return this.userService.getUserById(id); + return this.userService.getUserById(currentUser.id); } @Get() From 2d5ef9d43c4da69f8e69fb2a1a7e761f70eba8b7 Mon Sep 17 00:00:00 2001 From: cmandocdoc Date: Tue, 17 Apr 2018 10:58:43 +0800 Subject: [PATCH 3/5] wip fix x-access-token header --- src/client/app/core/services/api.service.ts | 2 +- src/server/app/core/middlewares/access-token.middleware.ts | 2 +- src/server/app/users/user.controller.test.ts | 2 +- src/server/main.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/app/core/services/api.service.ts b/src/client/app/core/services/api.service.ts index 854a499..1d452ca 100644 --- a/src/client/app/core/services/api.service.ts +++ b/src/client/app/core/services/api.service.ts @@ -78,7 +78,7 @@ export class ApiService { }; if (this.accessToken) { - headers['X-Access-Token'] = this.accessToken; + headers['x-access-token'] = this.accessToken; } return headers; diff --git a/src/server/app/core/middlewares/access-token.middleware.ts b/src/server/app/core/middlewares/access-token.middleware.ts index a6a32e6..2784f2b 100644 --- a/src/server/app/core/middlewares/access-token.middleware.ts +++ b/src/server/app/core/middlewares/access-token.middleware.ts @@ -10,7 +10,7 @@ export class AccessTokenMiddleware implements NestMiddleware { public resolve(...args: any[]): ExpressMiddleware { return (request, response, next) => { - request.user = this.jwtService.verify(request.headers['X-Access-Token']); + request.user = this.jwtService.verify(request.headers['x-access-token']); next(); }; } diff --git a/src/server/app/users/user.controller.test.ts b/src/server/app/users/user.controller.test.ts index 7377354..f8fd2a8 100644 --- a/src/server/app/users/user.controller.test.ts +++ b/src/server/app/users/user.controller.test.ts @@ -86,7 +86,7 @@ describe('UserController', () => { }); const response = await server .get('/api/users/me') - .set('X-Access-Token', data.token) + .set('x-access-token', data.token) .expect(200); expect(response.body).to.be.an('object'); expect(response.body).to.have.property('id', data.user.id); diff --git a/src/server/main.ts b/src/server/main.ts index 8627dc6..daec0da 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -6,7 +6,7 @@ import { AppModule } from './app.module'; import { setupExpressApplication, setupNestApplication } from './setup'; async function bootstrap() { - const port = process.env.PORT || 3000; + const port = process.env.PORT || 8080; // create application instance const expressApplication = express(); From 89edcc139cae95925b4ff728b49a8a658c8867fe Mon Sep 17 00:00:00 2001 From: cedrick mandocdoc Date: Tue, 17 Apr 2018 19:32:06 +0800 Subject: [PATCH 4/5] add guards for access token in server --- src/server/app/core/guards/access-token.guard.ts | 10 ++++++++++ src/server/app/core/index.ts | 3 +++ src/server/app/users/user.controller.test.ts | 5 +++++ src/server/app/users/user.controller.ts | 5 +++-- src/server/setup.ts | 2 +- 5 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/server/app/core/guards/access-token.guard.ts diff --git a/src/server/app/core/guards/access-token.guard.ts b/src/server/app/core/guards/access-token.guard.ts new file mode 100644 index 0000000..7352d1a --- /dev/null +++ b/src/server/app/core/guards/access-token.guard.ts @@ -0,0 +1,10 @@ +import { CanActivate, ExecutionContext, Guard } from '@nestjs/common'; +import { Observable } from 'rxjs/Observable'; + +@Guard() +export class AccessTokenGuard implements CanActivate { + + public canActivate(request, context: ExecutionContext): boolean | Promise | Observable { + return request.user ? true : false; + } +} diff --git a/src/server/app/core/index.ts b/src/server/app/core/index.ts index 62da94b..691b62f 100644 --- a/src/server/app/core/index.ts +++ b/src/server/app/core/index.ts @@ -5,6 +5,9 @@ export * from './core.module'; export * from './services/bcrypt.service'; export * from './services/jsonwebtoken.service'; +// core guards +export * from './guards/access-token.guard'; + // core decorators export * from './decorators/current-user.decorator'; diff --git a/src/server/app/users/user.controller.test.ts b/src/server/app/users/user.controller.test.ts index f8fd2a8..1a027c6 100644 --- a/src/server/app/users/user.controller.test.ts +++ b/src/server/app/users/user.controller.test.ts @@ -79,6 +79,11 @@ describe('UserController', () => { }); describe('getMe', async () => { + it('should return 403 with no access token', async () => { + await server + .get('/api/users/me') + .expect(403); + }); it('should return current user', async () => { const data = await userService.login({ email: `admin@test.com`, diff --git a/src/server/app/users/user.controller.ts b/src/server/app/users/user.controller.ts index d82b3f3..d587055 100644 --- a/src/server/app/users/user.controller.ts +++ b/src/server/app/users/user.controller.ts @@ -1,6 +1,6 @@ -import { Body, Controller, Get, Post } from '@nestjs/common'; +import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common'; -import { CurrentUser } from '../core'; +import { AccessTokenGuard, CurrentUser } from '../core'; import { User } from './user.entity'; import { UserService } from './user.service'; @@ -19,6 +19,7 @@ export class UserController { } @Get('me') + @UseGuards(AccessTokenGuard) public getMe( @CurrentUser() currentUser: User ): Promise { diff --git a/src/server/setup.ts b/src/server/setup.ts index 945e510..8b188bc 100644 --- a/src/server/setup.ts +++ b/src/server/setup.ts @@ -10,7 +10,7 @@ export async function setupNestApplication(nestApplication: INestApplication) { export async function setupExpressApplication(expressApplication: Application) { expressApplication.use(express.static(resolve(__dirname, '../../dist/client'))); - expressApplication.get('*', (request: Request, response: Response) => { + expressApplication.get(/^((?!\/api).)*$/, (request: Request, response: Response) => { if (request.path.match(/\.(html|css|png|jpg|ttf|js|ico)$/)) { return response.status(404) .send('Not found'); From c1d9b837507b26ee04de465ccd731944f69996e0 Mon Sep 17 00:00:00 2001 From: cedrick mandocdoc Date: Tue, 17 Apr 2018 19:49:28 +0800 Subject: [PATCH 5/5] add current user guard in client --- src/client/app/cms/cms-routing.module.ts | 6 +++-- src/client/app/core/core.module.ts | 5 +++- .../app/core/guards/current-user.guard.ts | 24 +++++++++++++++++++ src/client/app/core/index.ts | 2 ++ 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/client/app/core/guards/current-user.guard.ts diff --git a/src/client/app/cms/cms-routing.module.ts b/src/client/app/cms/cms-routing.module.ts index 1408970..13db19a 100644 --- a/src/client/app/cms/cms-routing.module.ts +++ b/src/client/app/cms/cms-routing.module.ts @@ -1,14 +1,16 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { CurrentUserGuard } from '../core'; + import { CmsComponent } from './cms.component'; const routes: Routes = [ { path: '', component: CmsComponent, - children: [ - ] + canActivate: [CurrentUserGuard], + children: [] } ]; diff --git a/src/client/app/core/core.module.ts b/src/client/app/core/core.module.ts index aa1cf6d..6c04bc5 100644 --- a/src/client/app/core/core.module.ts +++ b/src/client/app/core/core.module.ts @@ -1,6 +1,8 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { CurrentUserGuard } from './guards/current-user.guard'; + import { ApiService } from './services/api.service'; import { UserService } from './services/user.service'; @@ -12,7 +14,8 @@ import { UserService } from './services/user.service'; declarations: [], providers: [ ApiService, - UserService + UserService, + CurrentUserGuard ] }) export class CoreModule { } diff --git a/src/client/app/core/guards/current-user.guard.ts b/src/client/app/core/guards/current-user.guard.ts new file mode 100644 index 0000000..aa384f9 --- /dev/null +++ b/src/client/app/core/guards/current-user.guard.ts @@ -0,0 +1,24 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; + +import { User } from '../../../../common/entities'; +import { UserService } from '../services/user.service'; + +@Injectable() +export class CurrentUserGuard implements CanActivate { + + public constructor( + private userService: UserService, + private router: Router + ) { } + + public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + return this.userService.currentUser$.map((user: User) => { + if (!user) { + this.router.navigate(['/']); + } + return !!user; + }) + .take(1); + } +} diff --git a/src/client/app/core/index.ts b/src/client/app/core/index.ts index 888fec5..3390847 100644 --- a/src/client/app/core/index.ts +++ b/src/client/app/core/index.ts @@ -1,6 +1,8 @@ // core modules export * from './core.module'; +export * from './guards/current-user.guard'; + // core services export * from './services/api.service'; export * from './services/user.service';