├── .editorconfig ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── angular.json ├── browserslist ├── e2e ├── app.e2e-spec.ts ├── app.po.ts └── tsconfig.e2e.json ├── karma.conf.js ├── package-lock.json ├── package.json ├── protractor.conf.js ├── server ├── config.js.example ├── dragons.json ├── package-lock.json ├── package.json └── server.js ├── src ├── app │ ├── api.service.ts │ ├── app-routing.module.ts │ ├── app.component.css │ ├── app.component.html │ ├── app.component.ts │ ├── app.module.ts │ ├── auth │ │ ├── auth.guard.ts │ │ ├── auth.service.ts │ │ └── secure.interceptor.ts │ └── pages │ │ ├── callback.component.ts │ │ ├── home │ │ ├── home.component.css │ │ ├── home.component.html │ │ └── home.component.ts │ │ └── profile │ │ ├── profile.component.css │ │ ├── profile.component.html │ │ └── profile.component.ts ├── assets │ └── .gitkeep ├── environments │ ├── environment.prod.ts │ └── environment.ts.example ├── favicon.ico ├── index.html ├── main.ts ├── polyfills.ts ├── styles.css ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── typings.d.ts ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | /node_modules 4 | /server/node_modules 5 | environment.ts 6 | config.js 7 | 8 | # compiled output 9 | /dist 10 | /tmp 11 | /out-tsc 12 | 13 | # dependencies 14 | /node_modules 15 | 16 | # IDEs and editors 17 | /.idea 18 | .project 19 | .classpath 20 | .c9/ 21 | *.launch 22 | .settings/ 23 | *.sublime-workspace 24 | 25 | # IDE - VSCode 26 | .vscode/* 27 | !.vscode/settings.json 28 | !.vscode/tasks.json 29 | !.vscode/launch.json 30 | !.vscode/extensions.json 31 | 32 | # misc 33 | /.sass-cache 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | npm-debug.log 38 | testem.log 39 | /typings 40 | 41 | # e2e 42 | /e2e/*.js 43 | /e2e/*.map 44 | 45 | # System Files 46 | .DS_Store 47 | Thumbs.db 48 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "editor.insertSpaces": true,"editor.tabSize": 2, 4 | "editor.detectIndentation": false 5 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Auth0 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular-auth0-aside 2 | 3 | This repository demonstrates the use of [Auth0](https://auth0.com) with [Angular](https://angular.io) (with the [@angular/cli](https://github.com/angular/angular-cli)) and a sample Node API with a protected route. 4 | 5 | ## Dependencies 6 | 7 | * [Node.js with npm](http://nodejs.org), Node >= 8, npm >= 5 8 | * [@angular/cli](https://github.com/angular/angular-cli), >= 8 9 | 10 | ## Auth0 Application Setup 11 | 12 | 1. Go to your [**Auth0 Dashboard: Applications**](https://manage.auth0.com/#/applications) section and click the "[+ Create Application](https://manage.auth0.com/#/applications/create)" button. 13 | 2. Name your new app and select "Single Page Web Applications". 14 | 3. In the **Settings** for your new Auth0 app, add `http://localhost:4200/callback` to the **Allowed Callback URLs**. 15 | 4. Add `http://localhost:4200` to both the **Allowed Web Origins** and **Allowed Logout URLs**. Click the "Save Changes" button. 16 | 5. If you'd like, you can [set up some social connections](https://manage.auth0.com/#/connections/social). You can then enable them for your app in the **Application** options under the **Connections** tab. The example shown in the screenshot above uses username/password database, Facebook, Google, and Twitter. 17 | 18 | > **Note:** Set up your own social keys and _do not_ leave social connections set to use Auth0 dev keys or you will encounter issues with token renewal. 19 | 20 | ## Auth0 API Setup 21 | 22 | 1. Go to [**APIs**](https://manage.auth0.com/#/apis) in your Auth0 dashboard and click on the "Create API" button. Enter a name for the API. Set the **Identifier** to your API endpoint URL. In this example, this is `http://localhost:3001/api/`. The **Signing Algorithm** should be `RS256`. 23 | 2. You can consult the Node.js example under the **Quick Start** tab in your new API's settings. We'll implement our Node API in this fashion, using [Express](https://expressjs.com/), [express-jwt](https://github.com/auth0/express-jwt), and [jwks-rsa](https://github.com/auth0/node-jwks-rsa). 24 | 25 | We're now ready to implement Auth0 authentication on both our Angular client and Node backend API. 26 | 27 | ## Installation 28 | 29 | Clone this project. From the root directory, run the following commands to install dependencies for the server and client-side: 30 | 31 | ``` 32 | $ npm install 33 | $ cd server 34 | $ npm install 35 | ``` 36 | 37 | 1. Open `server/config.js.example` and remove `.example` from the file name. Then replace `[YOUR_AUTH0_DOMAIN]` with your Auth0 domain. 38 | 2. Open `src/app/environments/environment.example` and remove `.example` from the file name. Then replace `[YOUR_CLIENT_ID]` and `[YOUR_AUTH0_DOMAIN]` with your Auth0 application's client ID and domain. 39 | 40 | ## Serving the project 41 | 42 | From the root of this project, run: 43 | 44 | ```bash 45 | $ npm start 46 | ``` 47 | 48 | This will concurrently serve the Angular and API servers. 49 | 50 | ## What is Auth0? 51 | 52 | Auth0 helps you to: 53 | 54 | * Add authentication with [multiple authentication sources](https://docs.auth0.com/identityproviders), either social like **Google, Facebook, Microsoft Account, LinkedIn, GitHub, Twitter, Box, Salesforce, amont others**, or enterprise identity systems like **Windows Azure AD, Google Apps, Active Directory, ADFS or any SAML Identity Provider**. 55 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. 56 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. 57 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. 58 | * Analytics of how, when and where users are logging in. 59 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). 60 | 61 | ## Create a Free Auth0 Account 62 | 63 | 1. Go to [Auth0](https://auth0.com) and click Sign Up. 64 | 2. Use Google, GitHub, or Microsoft Account to log in. 65 | 66 | ## Issue Reporting 67 | 68 | If you have found a bug or if you have a feature request, please report them at this repository issues section. Please do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/whitehat) details the procedure for disclosing security issues. 69 | 70 | ## Author 71 | 72 | [Auth0](auth0.com) 73 | 74 | ## License 75 | 76 | This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info. 77 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "angular-auth0-aside": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "architect": { 11 | "build": { 12 | "builder": "@angular-devkit/build-angular:browser", 13 | "options": { 14 | "outputPath": "dist", 15 | "index": "src/index.html", 16 | "main": "src/main.ts", 17 | "tsConfig": "src/tsconfig.app.json", 18 | "polyfills": "src/polyfills.ts", 19 | "assets": [ 20 | "src/assets", 21 | "src/favicon.ico" 22 | ], 23 | "styles": [ 24 | "src/styles.css" 25 | ], 26 | "scripts": [] 27 | }, 28 | "configurations": { 29 | "production": { 30 | "optimization": true, 31 | "outputHashing": "all", 32 | "sourceMap": false, 33 | "extractCss": true, 34 | "namedChunks": false, 35 | "aot": true, 36 | "extractLicenses": true, 37 | "vendorChunk": false, 38 | "buildOptimizer": true, 39 | "fileReplacements": [ 40 | { 41 | "replace": "src/environments/environment.ts", 42 | "with": "src/environments/environment.prod.ts" 43 | } 44 | ] 45 | } 46 | } 47 | }, 48 | "serve": { 49 | "builder": "@angular-devkit/build-angular:dev-server", 50 | "options": { 51 | "browserTarget": "angular-auth0-aside:build" 52 | }, 53 | "configurations": { 54 | "production": { 55 | "browserTarget": "angular-auth0-aside:build:production" 56 | } 57 | } 58 | }, 59 | "extract-i18n": { 60 | "builder": "@angular-devkit/build-angular:extract-i18n", 61 | "options": { 62 | "browserTarget": "angular-auth0-aside:build" 63 | } 64 | }, 65 | "test": { 66 | "builder": "@angular-devkit/build-angular:karma", 67 | "options": { 68 | "main": "src/test.ts", 69 | "karmaConfig": "./karma.conf.js", 70 | "polyfills": "src/polyfills.ts", 71 | "tsConfig": "src/tsconfig.spec.json", 72 | "scripts": [], 73 | "styles": [ 74 | "src/styles.css" 75 | ], 76 | "assets": [ 77 | "src/assets", 78 | "src/favicon.ico" 79 | ] 80 | } 81 | }, 82 | "lint": { 83 | "builder": "@angular-devkit/build-angular:tslint", 84 | "options": { 85 | "tsConfig": [ 86 | "src/tsconfig.app.json", 87 | "src/tsconfig.spec.json" 88 | ], 89 | "exclude": [] 90 | } 91 | } 92 | } 93 | }, 94 | "angular-auth0-aside-e2e": { 95 | "root": "", 96 | "sourceRoot": "", 97 | "projectType": "application", 98 | "architect": { 99 | "e2e": { 100 | "builder": "@angular-devkit/build-angular:protractor", 101 | "options": { 102 | "protractorConfig": "./protractor.conf.js", 103 | "devServerTarget": "angular-auth0-aside:serve" 104 | } 105 | }, 106 | "lint": { 107 | "builder": "@angular-devkit/build-angular:tslint", 108 | "options": { 109 | "tsConfig": [ 110 | "e2e/tsconfig.e2e.json" 111 | ], 112 | "exclude": [] 113 | } 114 | } 115 | } 116 | } 117 | }, 118 | "defaultProject": "angular-auth0-aside", 119 | "schematics": { 120 | "@schematics/angular:component": { 121 | "prefix": "app", 122 | "styleext": "css" 123 | }, 124 | "@schematics/angular:directive": { 125 | "prefix": "app" 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AngularAuth0AsidePage } from './app.po'; 2 | 3 | describe('angular-auth0-aside App', () => { 4 | let page: AngularAuth0AsidePage; 5 | 6 | beforeEach(() => { 7 | page = new AngularAuth0AsidePage(); 8 | }); 9 | 10 | it('should display message saying app works', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('app works!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, element, by } from 'protractor'; 2 | 3 | export class AngularAuth0AsidePage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types":[ 8 | "jasmine", 9 | "node" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/0.13/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | files: [ 19 | 20 | ], 21 | preprocessors: { 22 | 23 | }, 24 | mime: { 25 | 'text/x-typescript': ['ts','tsx'] 26 | }, 27 | coverageIstanbulReporter: { 28 | dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ], 29 | fixWebpackSourcePaths: true 30 | }, 31 | angularCli: { 32 | environment: 'dev' 33 | }, 34 | reporters: config.angularCli && config.angularCli.codeCoverage 35 | ? ['progress', 'coverage-istanbul'] 36 | : ['progress', 'kjhtml'], 37 | port: 9876, 38 | colors: true, 39 | logLevel: config.LOG_INFO, 40 | autoWatch: true, 41 | browsers: ['Chrome'], 42 | singleRun: false 43 | }); 44 | }; 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-auth0-aside", 3 | "version": "0.2.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "concurrently \"ng serve\" \"cd server && node server\"", 8 | "build": "ng build", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "8.0.0", 16 | "@angular/common": "8.0.0", 17 | "@angular/compiler": "8.0.0", 18 | "@angular/core": "8.0.0", 19 | "@angular/forms": "8.0.0", 20 | "@angular/platform-browser": "8.0.0", 21 | "@angular/platform-browser-dynamic": "8.0.0", 22 | "@angular/router": "8.0.0", 23 | "auth0-js": "^9.8.0", 24 | "core-js": "^2.4.1", 25 | "rxjs": "^6.5.2", 26 | "tslib": "^1.9.0", 27 | "zone.js": "~0.9.1" 28 | }, 29 | "devDependencies": { 30 | "@angular-devkit/build-angular": "~0.800.0", 31 | "@angular-devkit/core": "0.6.0", 32 | "@angular-devkit/schematics": "0.6.0", 33 | "@angular/cli": "8.0.1", 34 | "@angular/compiler-cli": "8.0.0", 35 | "@angular/language-service": "8.0.0", 36 | "@types/jasmine": "~2.5.53", 37 | "@types/jasminewd2": "~2.0.2", 38 | "@types/node": "~6.0.60", 39 | "ajv": "^6.1.1", 40 | "codelyzer": "^5.0.1", 41 | "concurrently": "^3.5.1", 42 | "jasmine-core": "~2.6.2", 43 | "jasmine-spec-reporter": "~4.1.0", 44 | "karma": "~1.7.0", 45 | "karma-chrome-launcher": "~2.1.1", 46 | "karma-cli": "~1.0.1", 47 | "karma-coverage-istanbul-reporter": "^1.2.1", 48 | "karma-jasmine": "~1.1.0", 49 | "karma-jasmine-html-reporter": "^0.2.2", 50 | "protractor": "^5.4.0", 51 | "ts-node": "~3.2.0", 52 | "tslint": "5.10.0", 53 | "typescript": "3.4.5" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | beforeLaunch: function() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | }, 27 | onPrepare() { 28 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /server/config.js.example: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | CLIENT_DOMAIN: '[YOUR_AUTH0_DOMAIN]', // e.g., 'you.auth0.com' 3 | AUTH0_AUDIENCE: 'http://localhost:3001/api/' 4 | }; 5 | -------------------------------------------------------------------------------- /server/dragons.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "name": "Drogon", 5 | "source": "A Song of Ice and Fire" 6 | }, 7 | { 8 | "id": 2, 9 | "name": "Viserion", 10 | "source": "A Song of Ice and Fire" 11 | }, 12 | { 13 | "id": 3, 14 | "name": "Rhaegal", 15 | "source": "A Song of Ice and Fire" 16 | }, 17 | { 18 | "id": 4, 19 | "name": "Falkor", 20 | "source": "The Neverending Story" 21 | }, 22 | { 23 | "id": 5, 24 | "name": "Smaug", 25 | "source": "The Hobbit" 26 | }, 27 | { 28 | "id": 6, 29 | "name": "Puff", 30 | "source": "Peter, Paul and Mary" 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeserver-dinos", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/body-parser": { 8 | "version": "1.17.0", 9 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz", 10 | "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==", 11 | "dev": true, 12 | "requires": { 13 | "@types/connect": "*", 14 | "@types/node": "*" 15 | } 16 | }, 17 | "@types/connect": { 18 | "version": "3.4.32", 19 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", 20 | "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", 21 | "dev": true, 22 | "requires": { 23 | "@types/node": "*" 24 | } 25 | }, 26 | "@types/events": { 27 | "version": "1.2.0", 28 | "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", 29 | "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", 30 | "dev": true 31 | }, 32 | "@types/express": { 33 | "version": "4.16.0", 34 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.16.0.tgz", 35 | "integrity": "sha512-TtPEYumsmSTtTetAPXlJVf3kEqb6wZK0bZojpJQrnD/djV4q1oB6QQ8aKvKqwNPACoe02GNiy5zDzcYivR5Z2w==", 36 | "dev": true, 37 | "requires": { 38 | "@types/body-parser": "*", 39 | "@types/express-serve-static-core": "*", 40 | "@types/serve-static": "*" 41 | } 42 | }, 43 | "@types/express-jwt": { 44 | "version": "0.0.34", 45 | "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.34.tgz", 46 | "integrity": "sha1-/b7kxq9cCiRu8qkz9VGZc8dxfwI=", 47 | "dev": true, 48 | "requires": { 49 | "@types/express": "*", 50 | "@types/express-unless": "*" 51 | } 52 | }, 53 | "@types/express-serve-static-core": { 54 | "version": "4.16.0", 55 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.0.tgz", 56 | "integrity": "sha512-lTeoCu5NxJU4OD9moCgm0ESZzweAx0YqsAcab6OB0EB3+As1OaHtKnaGJvcngQxYsi9UNv0abn4/DRavrRxt4w==", 57 | "dev": true, 58 | "requires": { 59 | "@types/events": "*", 60 | "@types/node": "*", 61 | "@types/range-parser": "*" 62 | } 63 | }, 64 | "@types/express-unless": { 65 | "version": "0.0.32", 66 | "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.0.32.tgz", 67 | "integrity": "sha512-6YpJyFNlDDnPnRjMOvJCoDYlSDDmG/OEEUsPk7yhNkL4G9hUYtgab6vi1CcWsGSSSM0CsvNlWTG+ywAGnvF03g==", 68 | "dev": true, 69 | "requires": { 70 | "@types/express": "*" 71 | } 72 | }, 73 | "@types/mime": { 74 | "version": "2.0.0", 75 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", 76 | "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==", 77 | "dev": true 78 | }, 79 | "@types/node": { 80 | "version": "10.7.1", 81 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.7.1.tgz", 82 | "integrity": "sha512-EGoI4ylB/lPOaqXqtzAyL8HcgOuCtH2hkEaLmkueOYufsTFWBn4VCvlCDC2HW8Q+9iF+QVC3sxjDKQYjHQeZ9w==", 83 | "dev": true 84 | }, 85 | "@types/range-parser": { 86 | "version": "1.2.2", 87 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.2.tgz", 88 | "integrity": "sha512-HtKGu+qG1NPvYe1z7ezLsyIaXYyi8SoAVqWDZgDQ8dLrsZvSzUNCwZyfX33uhWxL/SU0ZDQZ3nwZ0nimt507Kw==", 89 | "dev": true 90 | }, 91 | "@types/serve-static": { 92 | "version": "1.13.2", 93 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz", 94 | "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==", 95 | "dev": true, 96 | "requires": { 97 | "@types/express-serve-static-core": "*", 98 | "@types/mime": "*" 99 | } 100 | }, 101 | "accepts": { 102 | "version": "1.3.5", 103 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 104 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 105 | "dev": true, 106 | "requires": { 107 | "mime-types": "~2.1.18", 108 | "negotiator": "0.6.1" 109 | } 110 | }, 111 | "ajv": { 112 | "version": "5.5.2", 113 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 114 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 115 | "dev": true, 116 | "requires": { 117 | "co": "^4.6.0", 118 | "fast-deep-equal": "^1.0.0", 119 | "fast-json-stable-stringify": "^2.0.0", 120 | "json-schema-traverse": "^0.3.0" 121 | } 122 | }, 123 | "array-flatten": { 124 | "version": "1.1.1", 125 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 126 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", 127 | "dev": true 128 | }, 129 | "asn1": { 130 | "version": "0.2.4", 131 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 132 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 133 | "dev": true, 134 | "requires": { 135 | "safer-buffer": "~2.1.0" 136 | } 137 | }, 138 | "assert-plus": { 139 | "version": "1.0.0", 140 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 141 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 142 | "dev": true 143 | }, 144 | "async": { 145 | "version": "1.5.2", 146 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 147 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 148 | "dev": true 149 | }, 150 | "asynckit": { 151 | "version": "0.4.0", 152 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 153 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", 154 | "dev": true 155 | }, 156 | "aws-sign2": { 157 | "version": "0.7.0", 158 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 159 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", 160 | "dev": true 161 | }, 162 | "aws4": { 163 | "version": "1.8.0", 164 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 165 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", 166 | "dev": true 167 | }, 168 | "bcrypt-pbkdf": { 169 | "version": "1.0.2", 170 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 171 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 172 | "dev": true, 173 | "optional": true, 174 | "requires": { 175 | "tweetnacl": "^0.14.3" 176 | } 177 | }, 178 | "body-parser": { 179 | "version": "1.18.3", 180 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", 181 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", 182 | "dev": true, 183 | "requires": { 184 | "bytes": "3.0.0", 185 | "content-type": "~1.0.4", 186 | "debug": "2.6.9", 187 | "depd": "~1.1.2", 188 | "http-errors": "~1.6.3", 189 | "iconv-lite": "0.4.23", 190 | "on-finished": "~2.3.0", 191 | "qs": "6.5.2", 192 | "raw-body": "2.3.3", 193 | "type-is": "~1.6.16" 194 | } 195 | }, 196 | "buffer-equal-constant-time": { 197 | "version": "1.0.1", 198 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 199 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=", 200 | "dev": true 201 | }, 202 | "bytes": { 203 | "version": "3.0.0", 204 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 205 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", 206 | "dev": true 207 | }, 208 | "caseless": { 209 | "version": "0.12.0", 210 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 211 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", 212 | "dev": true 213 | }, 214 | "co": { 215 | "version": "4.6.0", 216 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 217 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 218 | "dev": true 219 | }, 220 | "combined-stream": { 221 | "version": "1.0.6", 222 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", 223 | "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", 224 | "dev": true, 225 | "requires": { 226 | "delayed-stream": "~1.0.0" 227 | } 228 | }, 229 | "content-disposition": { 230 | "version": "0.5.2", 231 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 232 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", 233 | "dev": true 234 | }, 235 | "content-type": { 236 | "version": "1.0.4", 237 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 238 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 239 | "dev": true 240 | }, 241 | "cookie": { 242 | "version": "0.3.1", 243 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 244 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", 245 | "dev": true 246 | }, 247 | "cookie-signature": { 248 | "version": "1.0.6", 249 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 250 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", 251 | "dev": true 252 | }, 253 | "core-util-is": { 254 | "version": "1.0.2", 255 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 256 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 257 | "dev": true 258 | }, 259 | "cors": { 260 | "version": "2.8.4", 261 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", 262 | "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", 263 | "dev": true, 264 | "requires": { 265 | "object-assign": "^4", 266 | "vary": "^1" 267 | } 268 | }, 269 | "dashdash": { 270 | "version": "1.14.1", 271 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 272 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 273 | "dev": true, 274 | "requires": { 275 | "assert-plus": "^1.0.0" 276 | } 277 | }, 278 | "debug": { 279 | "version": "2.6.9", 280 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 281 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 282 | "dev": true, 283 | "requires": { 284 | "ms": "2.0.0" 285 | } 286 | }, 287 | "delayed-stream": { 288 | "version": "1.0.0", 289 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 290 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 291 | "dev": true 292 | }, 293 | "depd": { 294 | "version": "1.1.2", 295 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 296 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 297 | "dev": true 298 | }, 299 | "destroy": { 300 | "version": "1.0.4", 301 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 302 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", 303 | "dev": true 304 | }, 305 | "ecc-jsbn": { 306 | "version": "0.1.2", 307 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 308 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 309 | "dev": true, 310 | "optional": true, 311 | "requires": { 312 | "jsbn": "~0.1.0", 313 | "safer-buffer": "^2.1.0" 314 | } 315 | }, 316 | "ecdsa-sig-formatter": { 317 | "version": "1.0.10", 318 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", 319 | "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", 320 | "dev": true, 321 | "requires": { 322 | "safe-buffer": "^5.0.1" 323 | } 324 | }, 325 | "ee-first": { 326 | "version": "1.1.1", 327 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 328 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", 329 | "dev": true 330 | }, 331 | "encodeurl": { 332 | "version": "1.0.2", 333 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 334 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 335 | "dev": true 336 | }, 337 | "escape-html": { 338 | "version": "1.0.3", 339 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 340 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", 341 | "dev": true 342 | }, 343 | "etag": { 344 | "version": "1.8.1", 345 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 346 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 347 | "dev": true 348 | }, 349 | "express": { 350 | "version": "4.16.3", 351 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", 352 | "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", 353 | "dev": true, 354 | "requires": { 355 | "accepts": "~1.3.5", 356 | "array-flatten": "1.1.1", 357 | "body-parser": "1.18.2", 358 | "content-disposition": "0.5.2", 359 | "content-type": "~1.0.4", 360 | "cookie": "0.3.1", 361 | "cookie-signature": "1.0.6", 362 | "debug": "2.6.9", 363 | "depd": "~1.1.2", 364 | "encodeurl": "~1.0.2", 365 | "escape-html": "~1.0.3", 366 | "etag": "~1.8.1", 367 | "finalhandler": "1.1.1", 368 | "fresh": "0.5.2", 369 | "merge-descriptors": "1.0.1", 370 | "methods": "~1.1.2", 371 | "on-finished": "~2.3.0", 372 | "parseurl": "~1.3.2", 373 | "path-to-regexp": "0.1.7", 374 | "proxy-addr": "~2.0.3", 375 | "qs": "6.5.1", 376 | "range-parser": "~1.2.0", 377 | "safe-buffer": "5.1.1", 378 | "send": "0.16.2", 379 | "serve-static": "1.13.2", 380 | "setprototypeof": "1.1.0", 381 | "statuses": "~1.4.0", 382 | "type-is": "~1.6.16", 383 | "utils-merge": "1.0.1", 384 | "vary": "~1.1.2" 385 | }, 386 | "dependencies": { 387 | "body-parser": { 388 | "version": "1.18.2", 389 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", 390 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", 391 | "dev": true, 392 | "requires": { 393 | "bytes": "3.0.0", 394 | "content-type": "~1.0.4", 395 | "debug": "2.6.9", 396 | "depd": "~1.1.1", 397 | "http-errors": "~1.6.2", 398 | "iconv-lite": "0.4.19", 399 | "on-finished": "~2.3.0", 400 | "qs": "6.5.1", 401 | "raw-body": "2.3.2", 402 | "type-is": "~1.6.15" 403 | } 404 | }, 405 | "iconv-lite": { 406 | "version": "0.4.19", 407 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 408 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", 409 | "dev": true 410 | }, 411 | "qs": { 412 | "version": "6.5.1", 413 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 414 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", 415 | "dev": true 416 | }, 417 | "raw-body": { 418 | "version": "2.3.2", 419 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", 420 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", 421 | "dev": true, 422 | "requires": { 423 | "bytes": "3.0.0", 424 | "http-errors": "1.6.2", 425 | "iconv-lite": "0.4.19", 426 | "unpipe": "1.0.0" 427 | }, 428 | "dependencies": { 429 | "depd": { 430 | "version": "1.1.1", 431 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 432 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", 433 | "dev": true 434 | }, 435 | "http-errors": { 436 | "version": "1.6.2", 437 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 438 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 439 | "dev": true, 440 | "requires": { 441 | "depd": "1.1.1", 442 | "inherits": "2.0.3", 443 | "setprototypeof": "1.0.3", 444 | "statuses": ">= 1.3.1 < 2" 445 | } 446 | }, 447 | "setprototypeof": { 448 | "version": "1.0.3", 449 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 450 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", 451 | "dev": true 452 | } 453 | } 454 | }, 455 | "statuses": { 456 | "version": "1.4.0", 457 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 458 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", 459 | "dev": true 460 | } 461 | } 462 | }, 463 | "express-jwt": { 464 | "version": "5.3.1", 465 | "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.1.tgz", 466 | "integrity": "sha512-1C9RNq0wMp/JvsH/qZMlg3SIPvKu14YkZ4YYv7gJQ1Vq+Dv8LH9tLKenS5vMNth45gTlEUGx+ycp9IHIlaHP/g==", 467 | "dev": true, 468 | "requires": { 469 | "async": "^1.5.0", 470 | "express-unless": "^0.3.0", 471 | "jsonwebtoken": "^8.1.0", 472 | "lodash.set": "^4.0.0" 473 | } 474 | }, 475 | "express-unless": { 476 | "version": "0.3.1", 477 | "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", 478 | "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=", 479 | "dev": true 480 | }, 481 | "extend": { 482 | "version": "3.0.2", 483 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 484 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", 485 | "dev": true 486 | }, 487 | "extsprintf": { 488 | "version": "1.3.0", 489 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 490 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", 491 | "dev": true 492 | }, 493 | "fast-deep-equal": { 494 | "version": "1.1.0", 495 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 496 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", 497 | "dev": true 498 | }, 499 | "fast-json-stable-stringify": { 500 | "version": "2.0.0", 501 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 502 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 503 | "dev": true 504 | }, 505 | "finalhandler": { 506 | "version": "1.1.1", 507 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 508 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 509 | "dev": true, 510 | "requires": { 511 | "debug": "2.6.9", 512 | "encodeurl": "~1.0.2", 513 | "escape-html": "~1.0.3", 514 | "on-finished": "~2.3.0", 515 | "parseurl": "~1.3.2", 516 | "statuses": "~1.4.0", 517 | "unpipe": "~1.0.0" 518 | }, 519 | "dependencies": { 520 | "statuses": { 521 | "version": "1.4.0", 522 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 523 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", 524 | "dev": true 525 | } 526 | } 527 | }, 528 | "forever-agent": { 529 | "version": "0.6.1", 530 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 531 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 532 | "dev": true 533 | }, 534 | "form-data": { 535 | "version": "2.3.2", 536 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", 537 | "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", 538 | "dev": true, 539 | "requires": { 540 | "asynckit": "^0.4.0", 541 | "combined-stream": "1.0.6", 542 | "mime-types": "^2.1.12" 543 | } 544 | }, 545 | "forwarded": { 546 | "version": "0.1.2", 547 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 548 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", 549 | "dev": true 550 | }, 551 | "fresh": { 552 | "version": "0.5.2", 553 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 554 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 555 | "dev": true 556 | }, 557 | "getpass": { 558 | "version": "0.1.7", 559 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 560 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 561 | "dev": true, 562 | "requires": { 563 | "assert-plus": "^1.0.0" 564 | } 565 | }, 566 | "har-schema": { 567 | "version": "2.0.0", 568 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 569 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", 570 | "dev": true 571 | }, 572 | "har-validator": { 573 | "version": "5.1.0", 574 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", 575 | "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", 576 | "dev": true, 577 | "requires": { 578 | "ajv": "^5.3.0", 579 | "har-schema": "^2.0.0" 580 | } 581 | }, 582 | "http-errors": { 583 | "version": "1.6.3", 584 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 585 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 586 | "dev": true, 587 | "requires": { 588 | "depd": "~1.1.2", 589 | "inherits": "2.0.3", 590 | "setprototypeof": "1.1.0", 591 | "statuses": ">= 1.4.0 < 2" 592 | } 593 | }, 594 | "http-signature": { 595 | "version": "1.2.0", 596 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 597 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 598 | "dev": true, 599 | "requires": { 600 | "assert-plus": "^1.0.0", 601 | "jsprim": "^1.2.2", 602 | "sshpk": "^1.7.0" 603 | } 604 | }, 605 | "iconv-lite": { 606 | "version": "0.4.23", 607 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 608 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 609 | "dev": true, 610 | "requires": { 611 | "safer-buffer": ">= 2.1.2 < 3" 612 | } 613 | }, 614 | "inherits": { 615 | "version": "2.0.3", 616 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 617 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 618 | "dev": true 619 | }, 620 | "ipaddr.js": { 621 | "version": "1.8.0", 622 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", 623 | "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", 624 | "dev": true 625 | }, 626 | "is-typedarray": { 627 | "version": "1.0.0", 628 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 629 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 630 | "dev": true 631 | }, 632 | "isstream": { 633 | "version": "0.1.2", 634 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 635 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 636 | "dev": true 637 | }, 638 | "jsbn": { 639 | "version": "0.1.1", 640 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 641 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 642 | "dev": true, 643 | "optional": true 644 | }, 645 | "json-schema": { 646 | "version": "0.2.3", 647 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 648 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 649 | "dev": true 650 | }, 651 | "json-schema-traverse": { 652 | "version": "0.3.1", 653 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 654 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", 655 | "dev": true 656 | }, 657 | "json-stringify-safe": { 658 | "version": "5.0.1", 659 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 660 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 661 | "dev": true 662 | }, 663 | "jsonwebtoken": { 664 | "version": "8.3.0", 665 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", 666 | "integrity": "sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag==", 667 | "dev": true, 668 | "requires": { 669 | "jws": "^3.1.5", 670 | "lodash.includes": "^4.3.0", 671 | "lodash.isboolean": "^3.0.3", 672 | "lodash.isinteger": "^4.0.4", 673 | "lodash.isnumber": "^3.0.3", 674 | "lodash.isplainobject": "^4.0.6", 675 | "lodash.isstring": "^4.0.1", 676 | "lodash.once": "^4.0.0", 677 | "ms": "^2.1.1" 678 | }, 679 | "dependencies": { 680 | "ms": { 681 | "version": "2.1.1", 682 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 683 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 684 | "dev": true 685 | } 686 | } 687 | }, 688 | "jsprim": { 689 | "version": "1.4.1", 690 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 691 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 692 | "dev": true, 693 | "requires": { 694 | "assert-plus": "1.0.0", 695 | "extsprintf": "1.3.0", 696 | "json-schema": "0.2.3", 697 | "verror": "1.10.0" 698 | } 699 | }, 700 | "jwa": { 701 | "version": "1.1.6", 702 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz", 703 | "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==", 704 | "dev": true, 705 | "requires": { 706 | "buffer-equal-constant-time": "1.0.1", 707 | "ecdsa-sig-formatter": "1.0.10", 708 | "safe-buffer": "^5.0.1" 709 | } 710 | }, 711 | "jwks-rsa": { 712 | "version": "1.3.0", 713 | "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.3.0.tgz", 714 | "integrity": "sha512-9q+d5VffK/FvFAjuXoddrq7zQybFSINV4mcwJJExGKXGyjWWpTt3vsn/aX33aB0heY02LK0qSyicdtRK0gVTig==", 715 | "dev": true, 716 | "requires": { 717 | "@types/express-jwt": "0.0.34", 718 | "debug": "^2.2.0", 719 | "limiter": "^1.1.0", 720 | "lru-memoizer": "^1.6.0", 721 | "ms": "^2.0.0", 722 | "request": "^2.73.0" 723 | } 724 | }, 725 | "jws": { 726 | "version": "3.1.5", 727 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", 728 | "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==", 729 | "dev": true, 730 | "requires": { 731 | "jwa": "^1.1.5", 732 | "safe-buffer": "^5.0.1" 733 | } 734 | }, 735 | "limiter": { 736 | "version": "1.1.3", 737 | "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.3.tgz", 738 | "integrity": "sha512-zrycnIMsLw/3ZxTbW7HCez56rcFGecWTx5OZNplzcXUUmJLmoYArC6qdJzmAN5BWiNXGcpjhF9RQ1HSv5zebEw==", 739 | "dev": true 740 | }, 741 | "lock": { 742 | "version": "0.1.4", 743 | "resolved": "https://registry.npmjs.org/lock/-/lock-0.1.4.tgz", 744 | "integrity": "sha1-/sfervF+fDoKVeHaBCgD4l2RdF0=", 745 | "dev": true 746 | }, 747 | "lodash": { 748 | "version": "4.17.10", 749 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", 750 | "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", 751 | "dev": true 752 | }, 753 | "lodash.includes": { 754 | "version": "4.3.0", 755 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 756 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=", 757 | "dev": true 758 | }, 759 | "lodash.isboolean": { 760 | "version": "3.0.3", 761 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 762 | "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=", 763 | "dev": true 764 | }, 765 | "lodash.isinteger": { 766 | "version": "4.0.4", 767 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 768 | "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=", 769 | "dev": true 770 | }, 771 | "lodash.isnumber": { 772 | "version": "3.0.3", 773 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 774 | "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=", 775 | "dev": true 776 | }, 777 | "lodash.isplainobject": { 778 | "version": "4.0.6", 779 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 780 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", 781 | "dev": true 782 | }, 783 | "lodash.isstring": { 784 | "version": "4.0.1", 785 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 786 | "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", 787 | "dev": true 788 | }, 789 | "lodash.once": { 790 | "version": "4.1.1", 791 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 792 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", 793 | "dev": true 794 | }, 795 | "lodash.set": { 796 | "version": "4.3.2", 797 | "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", 798 | "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", 799 | "dev": true 800 | }, 801 | "lru-cache": { 802 | "version": "4.0.2", 803 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", 804 | "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", 805 | "dev": true, 806 | "requires": { 807 | "pseudomap": "^1.0.1", 808 | "yallist": "^2.0.0" 809 | } 810 | }, 811 | "lru-memoizer": { 812 | "version": "1.12.0", 813 | "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-1.12.0.tgz", 814 | "integrity": "sha1-7+ZXBsyKnMZT+A8NWm6jitlQ41I=", 815 | "dev": true, 816 | "requires": { 817 | "lock": "~0.1.2", 818 | "lodash": "^4.17.4", 819 | "lru-cache": "~4.0.0", 820 | "very-fast-args": "^1.1.0" 821 | } 822 | }, 823 | "media-typer": { 824 | "version": "0.3.0", 825 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 826 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 827 | "dev": true 828 | }, 829 | "merge-descriptors": { 830 | "version": "1.0.1", 831 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 832 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 833 | "dev": true 834 | }, 835 | "methods": { 836 | "version": "1.1.2", 837 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 838 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 839 | "dev": true 840 | }, 841 | "mime": { 842 | "version": "1.4.1", 843 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 844 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", 845 | "dev": true 846 | }, 847 | "mime-db": { 848 | "version": "1.36.0", 849 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz", 850 | "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==", 851 | "dev": true 852 | }, 853 | "mime-types": { 854 | "version": "2.1.20", 855 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz", 856 | "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==", 857 | "dev": true, 858 | "requires": { 859 | "mime-db": "~1.36.0" 860 | } 861 | }, 862 | "ms": { 863 | "version": "2.0.0", 864 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 865 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 866 | "dev": true 867 | }, 868 | "negotiator": { 869 | "version": "0.6.1", 870 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 871 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", 872 | "dev": true 873 | }, 874 | "oauth-sign": { 875 | "version": "0.9.0", 876 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 877 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", 878 | "dev": true 879 | }, 880 | "object-assign": { 881 | "version": "4.1.1", 882 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 883 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 884 | "dev": true 885 | }, 886 | "on-finished": { 887 | "version": "2.3.0", 888 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 889 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 890 | "dev": true, 891 | "requires": { 892 | "ee-first": "1.1.1" 893 | } 894 | }, 895 | "parseurl": { 896 | "version": "1.3.2", 897 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 898 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", 899 | "dev": true 900 | }, 901 | "path-to-regexp": { 902 | "version": "0.1.7", 903 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 904 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", 905 | "dev": true 906 | }, 907 | "performance-now": { 908 | "version": "2.1.0", 909 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 910 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", 911 | "dev": true 912 | }, 913 | "proxy-addr": { 914 | "version": "2.0.4", 915 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", 916 | "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", 917 | "dev": true, 918 | "requires": { 919 | "forwarded": "~0.1.2", 920 | "ipaddr.js": "1.8.0" 921 | } 922 | }, 923 | "pseudomap": { 924 | "version": "1.0.2", 925 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 926 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 927 | "dev": true 928 | }, 929 | "psl": { 930 | "version": "1.1.29", 931 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", 932 | "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", 933 | "dev": true 934 | }, 935 | "punycode": { 936 | "version": "1.4.1", 937 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 938 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", 939 | "dev": true 940 | }, 941 | "qs": { 942 | "version": "6.5.2", 943 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 944 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", 945 | "dev": true 946 | }, 947 | "range-parser": { 948 | "version": "1.2.0", 949 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 950 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", 951 | "dev": true 952 | }, 953 | "raw-body": { 954 | "version": "2.3.3", 955 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", 956 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", 957 | "dev": true, 958 | "requires": { 959 | "bytes": "3.0.0", 960 | "http-errors": "1.6.3", 961 | "iconv-lite": "0.4.23", 962 | "unpipe": "1.0.0" 963 | } 964 | }, 965 | "request": { 966 | "version": "2.88.0", 967 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 968 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 969 | "dev": true, 970 | "requires": { 971 | "aws-sign2": "~0.7.0", 972 | "aws4": "^1.8.0", 973 | "caseless": "~0.12.0", 974 | "combined-stream": "~1.0.6", 975 | "extend": "~3.0.2", 976 | "forever-agent": "~0.6.1", 977 | "form-data": "~2.3.2", 978 | "har-validator": "~5.1.0", 979 | "http-signature": "~1.2.0", 980 | "is-typedarray": "~1.0.0", 981 | "isstream": "~0.1.2", 982 | "json-stringify-safe": "~5.0.1", 983 | "mime-types": "~2.1.19", 984 | "oauth-sign": "~0.9.0", 985 | "performance-now": "^2.1.0", 986 | "qs": "~6.5.2", 987 | "safe-buffer": "^5.1.2", 988 | "tough-cookie": "~2.4.3", 989 | "tunnel-agent": "^0.6.0", 990 | "uuid": "^3.3.2" 991 | }, 992 | "dependencies": { 993 | "safe-buffer": { 994 | "version": "5.1.2", 995 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 996 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 997 | "dev": true 998 | } 999 | } 1000 | }, 1001 | "safe-buffer": { 1002 | "version": "5.1.1", 1003 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 1004 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", 1005 | "dev": true 1006 | }, 1007 | "safer-buffer": { 1008 | "version": "2.1.2", 1009 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1010 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1011 | "dev": true 1012 | }, 1013 | "send": { 1014 | "version": "0.16.2", 1015 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 1016 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 1017 | "dev": true, 1018 | "requires": { 1019 | "debug": "2.6.9", 1020 | "depd": "~1.1.2", 1021 | "destroy": "~1.0.4", 1022 | "encodeurl": "~1.0.2", 1023 | "escape-html": "~1.0.3", 1024 | "etag": "~1.8.1", 1025 | "fresh": "0.5.2", 1026 | "http-errors": "~1.6.2", 1027 | "mime": "1.4.1", 1028 | "ms": "2.0.0", 1029 | "on-finished": "~2.3.0", 1030 | "range-parser": "~1.2.0", 1031 | "statuses": "~1.4.0" 1032 | }, 1033 | "dependencies": { 1034 | "statuses": { 1035 | "version": "1.4.0", 1036 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 1037 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", 1038 | "dev": true 1039 | } 1040 | } 1041 | }, 1042 | "serve-static": { 1043 | "version": "1.13.2", 1044 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 1045 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 1046 | "dev": true, 1047 | "requires": { 1048 | "encodeurl": "~1.0.2", 1049 | "escape-html": "~1.0.3", 1050 | "parseurl": "~1.3.2", 1051 | "send": "0.16.2" 1052 | } 1053 | }, 1054 | "setprototypeof": { 1055 | "version": "1.1.0", 1056 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 1057 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", 1058 | "dev": true 1059 | }, 1060 | "sshpk": { 1061 | "version": "1.14.2", 1062 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", 1063 | "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", 1064 | "dev": true, 1065 | "requires": { 1066 | "asn1": "~0.2.3", 1067 | "assert-plus": "^1.0.0", 1068 | "bcrypt-pbkdf": "^1.0.0", 1069 | "dashdash": "^1.12.0", 1070 | "ecc-jsbn": "~0.1.1", 1071 | "getpass": "^0.1.1", 1072 | "jsbn": "~0.1.0", 1073 | "safer-buffer": "^2.0.2", 1074 | "tweetnacl": "~0.14.0" 1075 | } 1076 | }, 1077 | "statuses": { 1078 | "version": "1.5.0", 1079 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1080 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 1081 | "dev": true 1082 | }, 1083 | "tough-cookie": { 1084 | "version": "2.4.3", 1085 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 1086 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 1087 | "dev": true, 1088 | "requires": { 1089 | "psl": "^1.1.24", 1090 | "punycode": "^1.4.1" 1091 | } 1092 | }, 1093 | "tunnel-agent": { 1094 | "version": "0.6.0", 1095 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1096 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1097 | "dev": true, 1098 | "requires": { 1099 | "safe-buffer": "^5.0.1" 1100 | } 1101 | }, 1102 | "tweetnacl": { 1103 | "version": "0.14.5", 1104 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1105 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 1106 | "dev": true, 1107 | "optional": true 1108 | }, 1109 | "type-is": { 1110 | "version": "1.6.16", 1111 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 1112 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 1113 | "dev": true, 1114 | "requires": { 1115 | "media-typer": "0.3.0", 1116 | "mime-types": "~2.1.18" 1117 | } 1118 | }, 1119 | "unpipe": { 1120 | "version": "1.0.0", 1121 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1122 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 1123 | "dev": true 1124 | }, 1125 | "utils-merge": { 1126 | "version": "1.0.1", 1127 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1128 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 1129 | "dev": true 1130 | }, 1131 | "uuid": { 1132 | "version": "3.3.2", 1133 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 1134 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", 1135 | "dev": true 1136 | }, 1137 | "vary": { 1138 | "version": "1.1.2", 1139 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1140 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 1141 | "dev": true 1142 | }, 1143 | "verror": { 1144 | "version": "1.10.0", 1145 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 1146 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 1147 | "dev": true, 1148 | "requires": { 1149 | "assert-plus": "^1.0.0", 1150 | "core-util-is": "1.0.2", 1151 | "extsprintf": "^1.2.0" 1152 | } 1153 | }, 1154 | "very-fast-args": { 1155 | "version": "1.1.0", 1156 | "resolved": "https://registry.npmjs.org/very-fast-args/-/very-fast-args-1.1.0.tgz", 1157 | "integrity": "sha1-4W0dH6+KbllqJGQh/ZCneWPQs5Y=", 1158 | "dev": true 1159 | }, 1160 | "yallist": { 1161 | "version": "2.1.2", 1162 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 1163 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 1164 | "dev": true 1165 | } 1166 | } 1167 | } 1168 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodeserver-dragons", 3 | "version": "0.0.1", 4 | "description": "Sample Node server with dragons!", 5 | "repository": "https://github.com/auth0-blog/angular-auth0-aside", 6 | "main": "server.js", 7 | "scripts": { 8 | "start": "node server.js" 9 | }, 10 | "author": "Kim Maida", 11 | "license": "MIT", 12 | "dependencies": {}, 13 | "devDependencies": { 14 | "body-parser": "^1.18.3", 15 | "cors": "^2.8.4", 16 | "express": "^4.16.3", 17 | "express-jwt": "^5.3.1", 18 | "jwks-rsa": "^1.3.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | //-- Require 4 | const express = require('express'); 5 | const app = express(); 6 | const bodyParser = require('body-parser'); 7 | const cors = require('cors'); 8 | const jwt = require('express-jwt'); 9 | const jwks = require('jwks-rsa'); 10 | const dragonsJson = require('./dragons.json'); 11 | const config = require('./config.js'); 12 | 13 | //-- JWT check 14 | 15 | // @TODO: Remove .SAMPLE from /server/config.js.SAMPLE 16 | // and update with your proper Auth0 information 17 | 18 | const jwtCheck = jwt({ 19 | secret: jwks.expressJwtSecret({ 20 | cache: true, 21 | rateLimit: true, 22 | jwksRequestsPerMinute: 5, 23 | jwksUri: `https://${config.CLIENT_DOMAIN}/.well-known/jwks.json` 24 | }), 25 | audience: config.AUTH0_AUDIENCE, 26 | issuer: `https://${config.CLIENT_DOMAIN}/`, 27 | algorithm: 'RS256' 28 | }); 29 | 30 | //--- Set up app 31 | app.use(bodyParser.json()); 32 | app.use(bodyParser.urlencoded({ extended: true })); 33 | app.use(cors()); 34 | 35 | //--- GET protected dragons route 36 | app.get('/api/dragons', jwtCheck, function (req, res) { 37 | res.json(dragonsJson); 38 | }); 39 | 40 | //--- Port 41 | app.listen(3001); 42 | console.log('Listening on localhost:3001'); 43 | -------------------------------------------------------------------------------- /src/app/api.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { throwError, Observable } from 'rxjs'; 3 | import { HttpClient } from '@angular/common/http'; 4 | import { catchError } from 'rxjs/operators'; 5 | import { environment } from './../environments/environment'; 6 | 7 | @Injectable() 8 | export class ApiService { 9 | 10 | constructor(private http: HttpClient) { } 11 | 12 | getDragons$(): Observable { 13 | return this.http 14 | .get(`${environment.auth.AUDIENCE}dragons`) 15 | .pipe( 16 | catchError(err => throwError(err)) 17 | ); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule } from '@angular/router'; 3 | import { AuthGuard } from './auth/auth.guard'; 4 | import { HTTP_INTERCEPTORS } from '@angular/common/http'; 5 | import { InterceptorService } from './auth/secure.interceptor'; 6 | 7 | import { HomeComponent } from './pages/home/home.component'; 8 | import { CallbackComponent } from './pages/callback.component'; 9 | import { ProfileComponent } from './pages/profile/profile.component'; 10 | 11 | @NgModule({ 12 | imports: [ 13 | RouterModule.forRoot([ 14 | { 15 | path: 'callback', 16 | component: CallbackComponent 17 | }, 18 | { 19 | path: 'profile', 20 | component: ProfileComponent, 21 | canActivate: [ 22 | AuthGuard 23 | ] 24 | }, 25 | { 26 | path: '', 27 | component: HomeComponent, 28 | pathMatch: 'full' 29 | } 30 | ]) 31 | ], 32 | providers: [ 33 | AuthGuard, 34 | { 35 | provide: HTTP_INTERCEPTORS, 36 | useClass: InterceptorService, 37 | multi: true 38 | } 39 | ], 40 | exports: [ 41 | RouterModule 42 | ] 43 | }) 44 | export class AppRoutingModule {} 45 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0-blog/angular-auth0-aside/d9901b6bfb866432bf8ea539febeb46e02ab3773/src/app/app.component.css -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { AuthService } from './auth/auth.service'; 3 | 4 | @Component({ 5 | selector: 'app-root', 6 | templateUrl: './app.component.html', 7 | styleUrls: ['./app.component.css'] 8 | }) 9 | export class AppComponent implements OnInit { 10 | constructor(private auth: AuthService) {} 11 | 12 | ngOnInit() { 13 | // If there is an active session on the 14 | // authorization server, get tokens 15 | this.auth.renewAuth(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { HttpClientModule } from '@angular/common/http'; 5 | import { AppRoutingModule } from './app-routing.module'; 6 | import { ApiService } from './api.service'; 7 | import { AuthService } from './auth/auth.service'; 8 | import { AppComponent } from './app.component'; 9 | import { HomeComponent } from './pages/home/home.component'; 10 | import { CallbackComponent } from './pages/callback.component'; 11 | import { ProfileComponent } from './pages/profile/profile.component'; 12 | 13 | @NgModule({ 14 | declarations: [ 15 | AppComponent, 16 | HomeComponent, 17 | CallbackComponent, 18 | ProfileComponent 19 | ], 20 | imports: [ 21 | BrowserModule, 22 | FormsModule, 23 | HttpClientModule, 24 | AppRoutingModule 25 | ], 26 | providers: [ 27 | ApiService, 28 | AuthService 29 | ], 30 | bootstrap: [AppComponent] 31 | }) 32 | export class AppModule { } 33 | -------------------------------------------------------------------------------- /src/app/auth/auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { 3 | Router, 4 | CanActivate, 5 | ActivatedRouteSnapshot, 6 | RouterStateSnapshot 7 | } from '@angular/router'; 8 | import { AuthService } from './auth.service'; 9 | import { Observable } from 'rxjs'; 10 | 11 | @Injectable() 12 | export class AuthGuard implements CanActivate { 13 | 14 | constructor( 15 | private auth: AuthService, 16 | private router: Router 17 | ) { } 18 | 19 | canActivate( 20 | next: ActivatedRouteSnapshot, 21 | state: RouterStateSnapshot 22 | ): Observable | Promise | boolean { 23 | if (this.auth.isAuthenticated) { 24 | return true; 25 | } 26 | this.router.navigate([this.auth.onAuthFailureUrl]); 27 | return false; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/app/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { BehaviorSubject, bindNodeCallback } from 'rxjs'; 3 | import * as auth0 from 'auth0-js'; 4 | import { environment } from './../../environments/environment'; 5 | import { Router } from '@angular/router'; 6 | 7 | @Injectable() 8 | export class AuthService { 9 | // Create Auth0 web auth instance 10 | // @TODO: Update environment variables and remove .example 11 | // extension in src/environments/environment.ts.example 12 | private Auth0 = new auth0.WebAuth({ 13 | clientID: environment.auth.CLIENT_ID, 14 | domain: environment.auth.CLIENT_DOMAIN, 15 | responseType: 'id_token token', 16 | redirectUri: environment.auth.REDIRECT, 17 | audience: environment.auth.AUDIENCE, 18 | scope: 'openid profile email' 19 | }); 20 | // Track whether or not to renew token 21 | private authFlag = 'isLoggedIn'; 22 | // Create stream for token 23 | token$ = new BehaviorSubject(null); 24 | // Create stream for user profile data 25 | userProfile$ = new BehaviorSubject(null); 26 | // Authentication navigation 27 | onAuthSuccessUrl = '/'; 28 | onAuthFailureUrl = '/'; 29 | logoutUrl = environment.auth.LOGOUT_URL; 30 | // Create observable of Auth0 parseHash method to gather auth results 31 | parseHash$ = bindNodeCallback(this.Auth0.parseHash.bind(this.Auth0)); 32 | // Create observable of Auth0 checkSession method to 33 | // verify authorization server session and renew tokens 34 | checkSession$ = bindNodeCallback(this.Auth0.checkSession.bind(this.Auth0)); 35 | 36 | constructor(private router: Router) { } 37 | 38 | login() { 39 | this.Auth0.authorize(); 40 | } 41 | 42 | handleLoginCallback() { 43 | if (window.location.hash && !this.isAuthenticated) { 44 | this.parseHash$().subscribe( 45 | authResult => { 46 | this.localLogin(authResult); 47 | this.router.navigate([this.onAuthSuccessUrl]); 48 | }, 49 | err => this.handleError(err) 50 | ) 51 | } 52 | } 53 | 54 | private localLogin(authResult) { 55 | // Observable of token 56 | this.token$.next(authResult.accessToken); 57 | // Emit value for user data subject 58 | this.userProfile$.next(authResult.idTokenPayload); 59 | // Set flag in local storage stating this app is logged in 60 | localStorage.setItem(this.authFlag, JSON.stringify(true)); 61 | } 62 | 63 | get isAuthenticated(): boolean { 64 | return JSON.parse(localStorage.getItem(this.authFlag)); 65 | } 66 | 67 | renewAuth() { 68 | if (this.isAuthenticated) { 69 | this.checkSession$({}).subscribe( 70 | authResult => this.localLogin(authResult), 71 | err => { 72 | localStorage.removeItem(this.authFlag); 73 | this.router.navigate([this.onAuthFailureUrl]); 74 | } 75 | ); 76 | } 77 | } 78 | 79 | private localLogout() { 80 | localStorage.setItem(this.authFlag, JSON.stringify(false)); 81 | this.token$.next(null); 82 | this.userProfile$.next(null); 83 | } 84 | 85 | logout() { 86 | this.localLogout(); 87 | // This does a refresh and redirects back to homepage 88 | // Make sure you have the logout URL in your Auth0 89 | // Dashboard Application settings in Allowed Logout URLs 90 | this.Auth0.logout({ 91 | returnTo: this.logoutUrl, 92 | clientID: environment.auth.CLIENT_ID 93 | }); 94 | } 95 | 96 | private handleError(err) { 97 | if (err.error_description) { 98 | console.error(`Error: ${err.error_description}`); 99 | } else { 100 | console.error(`Error: ${JSON.stringify(err)}`); 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/app/auth/secure.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; 3 | import { AuthService } from './auth.service'; 4 | import { Observable } from 'rxjs'; 5 | import { filter, mergeMap } from 'rxjs/operators'; 6 | 7 | @Injectable() 8 | export class InterceptorService implements HttpInterceptor { 9 | 10 | constructor(private auth: AuthService) { } 11 | 12 | intercept( 13 | req: HttpRequest, 14 | next: HttpHandler 15 | ): Observable> { 16 | // @NOTE: If you have some endpoints that are public 17 | // and do not need Authorization header, implement logic 18 | // here to accommodate that and conditionally let public 19 | // requests pass through based on your requirements 20 | return this.auth.token$ 21 | .pipe( 22 | filter(token => typeof token === 'string'), 23 | mergeMap(token => { 24 | const tokenReq = req.clone({ 25 | setHeaders: { Authorization: `Bearer ${token}` } 26 | }); 27 | return next.handle(tokenReq); 28 | }) 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/pages/callback.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { AuthService } from '../auth/auth.service'; 3 | 4 | @Component({ 5 | selector: 'app-callback', 6 | template: `
Loading...
`, 7 | styles: [] 8 | }) 9 | export class CallbackComponent implements OnInit { 10 | 11 | constructor(private auth: AuthService) { } 12 | 13 | ngOnInit() { 14 | this.auth.handleLoginCallback(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/app/pages/home/home.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0-blog/angular-auth0-aside/d9901b6bfb866432bf8ea539febeb46e02ab3773/src/app/pages/home/home.component.css -------------------------------------------------------------------------------- /src/app/pages/home/home.component.html: -------------------------------------------------------------------------------- 1 |

Angular with Auth0

2 | 3 |
4 | 5 |
6 | 7 |
8 |

Hello, {{ user.name }}!

9 | 10 | 11 |
12 |

Here Be Dragons

13 |
    14 |
  • 15 | {{ dragon.name }} - {{ dragon.source }} 16 |
  • 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /src/app/pages/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { throwError } from 'rxjs'; 3 | import { catchError } from 'rxjs/operators'; 4 | import { ApiService } from './../../api.service'; 5 | import { AuthService } from './../../auth/auth.service'; 6 | 7 | @Component({ 8 | selector: 'app-home', 9 | templateUrl: './home.component.html', 10 | styleUrls: ['./home.component.css'] 11 | }) 12 | export class HomeComponent implements OnInit { 13 | dragons$ = this.api.getDragons$(); 14 | user$ = this.auth.userProfile$.pipe(catchError(err => throwError(err))); 15 | 16 | constructor( 17 | private api: ApiService, 18 | public auth: AuthService 19 | ) { } 20 | 21 | ngOnInit() { 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/app/pages/profile/profile.component.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0-blog/angular-auth0-aside/d9901b6bfb866432bf8ea539febeb46e02ab3773/src/app/pages/profile/profile.component.css -------------------------------------------------------------------------------- /src/app/pages/profile/profile.component.html: -------------------------------------------------------------------------------- 1 |
2 |

{{ user.name }}

3 |
    4 |
  • 5 | {{ profileProp }} 6 |
  • 7 |
8 |

9 | Back to Home 10 |

11 |
12 | -------------------------------------------------------------------------------- /src/app/pages/profile/profile.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { AuthService } from './../../auth/auth.service'; 3 | 4 | @Component({ 5 | selector: 'app-profile', 6 | templateUrl: './profile.component.html', 7 | styleUrls: ['./profile.component.css'] 8 | }) 9 | export class ProfileComponent implements OnInit { 10 | 11 | constructor(public auth: AuthService) { } 12 | 13 | ngOnInit() { 14 | } 15 | 16 | makeProfileArray(obj): string[] { 17 | const keyPropArray = []; 18 | for (const key in obj) { 19 | if (obj.hasOwnProperty(key)) { 20 | keyPropArray.push(key + ': ' + JSON.stringify(obj[key])); 21 | } 22 | } 23 | return keyPropArray; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0-blog/angular-auth0-aside/d9901b6bfb866432bf8ea539febeb46e02ab3773/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/environments/environment.ts.example: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false, 8 | auth: { 9 | CLIENT_ID: '[YOUR_CLIENT_ID]', 10 | CLIENT_DOMAIN: '[YOUR_AUTH0_DOMAIN]', // e.g., 'you.auth0.com' 11 | AUDIENCE: 'http://localhost:3001/api/', 12 | REDIRECT: 'http://localhost:4200/callback', 13 | LOGOUT_URL: 'http://localhost:4200' 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/auth0-blog/angular-auth0-aside/d9901b6bfb866432bf8ea539febeb46e02ab3773/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularAuth0Aside 6 | 7 | 8 | 9 | 10 | 11 | 12 | Loading... 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule); 12 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/set'; 35 | 36 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 37 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 38 | 39 | /** IE10 and IE11 requires the following to support `@angular/animation`. */ 40 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 41 | 42 | 43 | /** Evergreen browsers require these. **/ 44 | import 'core-js/es6/reflect'; 45 | 46 | 47 | /** ALL Firefox browsers require the following to support `@angular/animation`. **/ 48 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 49 | 50 | 51 | 52 | /*************************************************************************************************** 53 | * Zone JS is required by Angular itself. 54 | */ 55 | import 'zone.js/dist/zone'; // Included with Angular CLI. 56 | 57 | 58 | 59 | /*************************************************************************************************** 60 | * APPLICATION IMPORTS 61 | */ 62 | 63 | /** 64 | * Date, currency, decimal and percent pipes. 65 | * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10 66 | */ 67 | // import 'intl'; // Run `npm install --save intl`. 68 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | import { getTestBed } from '@angular/core/testing'; 10 | import { 11 | BrowserDynamicTestingModule, 12 | platformBrowserDynamicTesting 13 | } from '@angular/platform-browser-dynamic/testing'; 14 | 15 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 16 | declare var __karma__: any; 17 | declare var require: any; 18 | 19 | // Prevent Karma from running prematurely. 20 | __karma__.loaded = function () {}; 21 | 22 | // First, initialize the Angular testing environment. 23 | getTestBed().initTestEnvironment( 24 | BrowserDynamicTestingModule, 25 | platformBrowserDynamicTesting() 26 | ); 27 | // Then we find all the tests. 28 | const context = require.context('./', true, /\.spec\.ts$/); 29 | // And load the modules. 30 | context.keys().map(context); 31 | // Finally, start Karma to run the tests. 32 | __karma__.start(); 33 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "", 6 | "types": [] 7 | }, 8 | "exclude": [ 9 | "test.ts", 10 | "**/*.spec.ts" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "", 6 | "types": [ 7 | "jasmine", 8 | "node" 9 | ] 10 | }, 11 | "files": [ 12 | "test.ts", 13 | "polyfills.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "importHelpers": true, 5 | "module": "esnext", 6 | "outDir": "./dist/out-tsc", 7 | "baseUrl": "src", 8 | "sourceMap": true, 9 | "declaration": false, 10 | "moduleResolution": "node", 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2016", 19 | "dom" 20 | ] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "callable-types": true, 7 | "class-name": true, 8 | "comment-format": [ 9 | true, 10 | "check-space" 11 | ], 12 | "curly": true, 13 | "eofline": true, 14 | "forin": true, 15 | "import-blacklist": [true], 16 | "import-spacing": true, 17 | "indent": [ 18 | true, 19 | "spaces" 20 | ], 21 | "interface-over-type-literal": true, 22 | "label-position": true, 23 | "max-line-length": [ 24 | true, 25 | 140 26 | ], 27 | "member-access": false, 28 | "member-ordering": [ 29 | true, 30 | "static-before-instance", 31 | "variables-before-functions" 32 | ], 33 | "no-arg": true, 34 | "no-bitwise": true, 35 | "no-console": [ 36 | true, 37 | "debug", 38 | "info", 39 | "time", 40 | "timeEnd", 41 | "trace" 42 | ], 43 | "no-construct": true, 44 | "no-debugger": true, 45 | "no-duplicate-variable": true, 46 | "no-empty": false, 47 | "no-empty-interface": true, 48 | "no-eval": true, 49 | "no-inferrable-types": [true, "ignore-params"], 50 | "no-shadowed-variable": true, 51 | "no-string-literal": false, 52 | "no-string-throw": true, 53 | "no-switch-case-fall-through": true, 54 | "no-trailing-whitespace": true, 55 | "no-unused-expression": true, 56 | "no-use-before-declare": true, 57 | "no-var-keyword": true, 58 | "object-literal-sort-keys": false, 59 | "one-line": [ 60 | true, 61 | "check-open-brace", 62 | "check-catch", 63 | "check-else", 64 | "check-whitespace" 65 | ], 66 | "prefer-const": true, 67 | "quotemark": [ 68 | true, 69 | "single" 70 | ], 71 | "radix": true, 72 | "semicolon": [ 73 | "always" 74 | ], 75 | "triple-equals": [ 76 | true, 77 | "allow-null-check" 78 | ], 79 | "typedef-whitespace": [ 80 | true, 81 | { 82 | "call-signature": "nospace", 83 | "index-signature": "nospace", 84 | "parameter": "nospace", 85 | "property-declaration": "nospace", 86 | "variable-declaration": "nospace" 87 | } 88 | ], 89 | "typeof-compare": true, 90 | "unified-signatures": true, 91 | "variable-name": false, 92 | "whitespace": [ 93 | true, 94 | "check-branch", 95 | "check-decl", 96 | "check-operator", 97 | "check-separator", 98 | "check-type" 99 | ], 100 | 101 | "directive-selector": [true, "attribute", "app", "camelCase"], 102 | "component-selector": [true, "element", "app", "kebab-case"], 103 | "no-inputs-metadata-property": true, 104 | "no-outputs-metadata-property": true, 105 | "no-host-metadata-property": true, 106 | "no-input-rename": true, 107 | "no-output-rename": true, 108 | "use-lifecycle-interface": true, 109 | "use-pipe-transform-interface": true, 110 | "component-class-suffix": true, 111 | "directive-class-suffix": true, 112 | "no-access-missing-member": true, 113 | "templates-use-public": true, 114 | "invoke-injectable": true 115 | } 116 | } 117 | --------------------------------------------------------------------------------