├── .gitignore
├── LICENSE
├── README.md
├── ng2auth
├── .editorconfig
├── .gitignore
├── README.md
├── angular.json
├── e2e
│ ├── app.e2e-spec.ts
│ ├── app.po.ts
│ └── tsconfig.e2e.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── protractor.conf.js
├── src
│ ├── app
│ │ ├── app-routing.module.ts
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── auth
│ │ │ ├── auth.guard.ts
│ │ │ └── auth.service.ts
│ │ ├── callback.component.ts
│ │ ├── deal.service.ts
│ │ ├── deal.ts
│ │ ├── private-deals
│ │ │ ├── private-deals.component.css
│ │ │ ├── private-deals.component.html
│ │ │ └── private-deals.component.ts
│ │ └── public-deals
│ │ │ ├── public-deals.component.css
│ │ │ ├── public-deals.component.html
│ │ │ └── public-deals.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
└── server
├── .gitignore
├── LICENSE
├── README.md
├── heroes.js
├── package-lock.json
├── package.json
└── server.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 |
33 | # Optional npm cache directory
34 | .npm
35 |
36 | # Optional REPL history
37 | .node_repl_history
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Auth0 Blog Samples
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 | # Daily Deals
2 |
3 | Daily Deals is an application built with Angular that shows how you can add token based authentication to your Angular applications. You can read the full tutorial for this project here: [Angular Authentication Tutorial](https://auth0.com/blog/angular-2-authentication/).
4 |
5 | # Running the App
6 |
7 | You will need to run both the Node.js server located in the `server` directory and Angular front-end located in the `ng2auth` directory. See each of the project directories for detailed instructions on how to run the projects. You will need an Auth0 account, so if you don't already have one, [sign up](https://auth0.com/signup) for a free account today.
8 |
9 | ## What is Auth0?
10 |
11 | Auth0 helps you to:
12 |
13 | * 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**.
14 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**.
15 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user.
16 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely.
17 | * Analytics of how, when and where users are logging in.
18 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules).
19 |
20 | ## Create a free Auth0 account
21 |
22 | 1. Go to [Auth0](https://auth0.com/signup) and click Sign Up.
23 | 2. Use Google, GitHub or Microsoft Account to log in.
24 |
25 | ## Issue Reporting
26 |
27 | 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.
28 |
29 | ## Author
30 |
31 | [Auth0](auth0.com)
32 |
33 | ## License
34 |
35 | This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
--------------------------------------------------------------------------------
/ng2auth/.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 |
--------------------------------------------------------------------------------
/ng2auth/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | environment.ts
4 |
5 | # compiled output
6 | /dist
7 | /tmp
8 | /out-tsc
9 |
10 | # dependencies
11 | /node_modules
12 |
13 | # IDEs and editors
14 | /.idea
15 | .project
16 | .classpath
17 | .c9/
18 | *.launch
19 | .settings/
20 | *.sublime-workspace
21 |
22 | # IDE - VSCode
23 | .vscode/*
24 | !.vscode/settings.json
25 | !.vscode/tasks.json
26 | !.vscode/launch.json
27 | !.vscode/extensions.json
28 |
29 | # misc
30 | /.sass-cache
31 | /connect.lock
32 | /coverage
33 | /libpeerconnection.log
34 | npm-debug.log
35 | testem.log
36 | /typings
37 |
38 | # e2e
39 | /e2e/*.js
40 | /e2e/*.map
41 |
42 | # System Files
43 | .DS_Store
44 | Thumbs.db
45 |
--------------------------------------------------------------------------------
/ng2auth/README.md:
--------------------------------------------------------------------------------
1 | # Ng2auth
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.5.5.
4 |
5 | ## Development server
6 |
7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 |
25 | ## Further help
26 |
27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
28 |
--------------------------------------------------------------------------------
/ng2auth/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "ng2auth": {
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": "ng2auth:build"
52 | },
53 | "configurations": {
54 | "production": {
55 | "browserTarget": "ng2auth:build:production"
56 | }
57 | }
58 | },
59 | "extract-i18n": {
60 | "builder": "@angular-devkit/build-angular:extract-i18n",
61 | "options": {
62 | "browserTarget": "ng2auth: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 | "**/node_modules/**"
91 | ]
92 | }
93 | }
94 | }
95 | },
96 | "ng2auth-e2e": {
97 | "root": "",
98 | "sourceRoot": "",
99 | "projectType": "application",
100 | "architect": {
101 | "e2e": {
102 | "builder": "@angular-devkit/build-angular:protractor",
103 | "options": {
104 | "protractorConfig": "./protractor.conf.js",
105 | "devServerTarget": "ng2auth:serve"
106 | }
107 | },
108 | "lint": {
109 | "builder": "@angular-devkit/build-angular:tslint",
110 | "options": {
111 | "tsConfig": [
112 | "e2e/tsconfig.e2e.json"
113 | ],
114 | "exclude": [
115 | "**/node_modules/**"
116 | ]
117 | }
118 | }
119 | }
120 | }
121 | },
122 | "defaultProject": "ng2auth",
123 | "schematics": {
124 | "@schematics/angular:class": {
125 | "spec": false
126 | },
127 | "@schematics/angular:component": {
128 | "spec": false,
129 | "prefix": "app",
130 | "styleext": "css"
131 | },
132 | "@schematics/angular:directive": {
133 | "spec": false,
134 | "prefix": "app"
135 | },
136 | "@schematics/angular:guard": {
137 | "spec": false
138 | },
139 | "@schematics/angular:module": {
140 | "spec": false
141 | },
142 | "@schematics/angular:pipe": {
143 | "spec": false
144 | },
145 | "@schematics/angular:service": {
146 | "spec": false
147 | }
148 | }
149 | }
--------------------------------------------------------------------------------
/ng2auth/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 |
3 | describe('ng2auth App', () => {
4 | let page: AppPage;
5 |
6 | beforeEach(() => {
7 | page = new AppPage();
8 | });
9 |
10 | it('should display welcome message', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('Welcome to app!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/ng2auth/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/ng2auth/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/e2e",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": [
9 | "jasmine",
10 | "jasminewd2",
11 | "node"
12 | ]
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/ng2auth/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/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 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
20 | fixWebpackSourcePaths: true
21 | },
22 | angularCli: {
23 | environment: 'dev'
24 | },
25 | reporters: ['progress', 'kjhtml'],
26 | port: 9876,
27 | colors: true,
28 | logLevel: config.LOG_INFO,
29 | autoWatch: true,
30 | browsers: ['Chrome'],
31 | singleRun: false
32 | });
33 | };
34 |
--------------------------------------------------------------------------------
/ng2auth/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng2auth",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "ng serve",
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": "6.0.0",
16 | "@angular/common": "6.0.0",
17 | "@angular/compiler": "6.0.0",
18 | "@angular/core": "6.0.0",
19 | "@angular/forms": "6.0.0",
20 | "@angular/http": "6.0.0",
21 | "@angular/platform-browser": "6.0.0",
22 | "@angular/platform-browser-dynamic": "6.0.0",
23 | "@angular/router": "6.0.0",
24 | "auth0-js": "^9.5.1",
25 | "core-js": "^2.4.1",
26 | "rxjs": "^6.1.0",
27 | "zone.js": "^0.8.26"
28 | },
29 | "devDependencies": {
30 | "@angular-devkit/core": "0.6.0",
31 | "@angular-devkit/schematics": "0.6.0",
32 | "@angular/cli": "6.0.0",
33 | "@angular/compiler-cli": "6.0.0",
34 | "@angular/language-service": "6.0.0",
35 | "@types/jasmine": "~2.5.53",
36 | "@types/jasminewd2": "~2.0.2",
37 | "@types/node": "~6.0.60",
38 | "ajv": "^6.1.1",
39 | "codelyzer": "4.3.0",
40 | "jasmine-core": "~2.6.2",
41 | "jasmine-spec-reporter": "~4.1.0",
42 | "karma": "~1.7.0",
43 | "karma-chrome-launcher": "~2.1.1",
44 | "karma-cli": "~1.0.1",
45 | "karma-coverage-istanbul-reporter": "^1.2.1",
46 | "karma-jasmine": "~1.1.0",
47 | "karma-jasmine-html-reporter": "^0.2.2",
48 | "protractor": "~5.1.2",
49 | "ts-node": "~3.2.0",
50 | "tslint": "5.10.0",
51 | "typescript": "2.7.2",
52 | "@angular-devkit/build-angular": "~0.6.0"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/ng2auth/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 | onPrepare() {
23 | require('ts-node').register({
24 | project: 'e2e/tsconfig.e2e.json'
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/ng2auth/src/app/app-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { Routes, RouterModule } from '@angular/router';
3 | import { CallbackComponent } from './callback.component';
4 | import { PublicDealsComponent } from './public-deals/public-deals.component';
5 | import { PrivateDealsComponent } from './private-deals/private-deals.component';
6 | import { AuthGuard } from './auth/auth.guard';
7 |
8 | const routes: Routes = [
9 | {
10 | path: '',
11 | redirectTo: 'deals',
12 | pathMatch: 'full'
13 | },
14 | {
15 | path: 'deals',
16 | component: PublicDealsComponent
17 | },
18 | {
19 | path: 'special',
20 | component: PrivateDealsComponent,
21 | canActivate: [
22 | AuthGuard
23 | ]
24 | },
25 | {
26 | path: 'callback',
27 | component: CallbackComponent
28 | }
29 | ];
30 |
31 | @NgModule({
32 | imports: [RouterModule.forRoot(routes)],
33 | providers: [AuthGuard],
34 | exports: [RouterModule]
35 | })
36 | export class AppRoutingModule { }
37 |
--------------------------------------------------------------------------------
/ng2auth/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { AuthService } from './auth/auth.service';
3 |
4 | @Component({
5 | selector: 'app-root',
6 | template: `
7 |
8 |
29 |
30 |
31 |
32 |
33 | `,
34 | styles: [
35 | `.navbar-right { margin-right: 0px !important}`
36 | ]
37 | })
38 | export class AppComponent {
39 | title = 'Daily Deals';
40 |
41 | constructor(public authService: AuthService) {}
42 | }
43 |
--------------------------------------------------------------------------------
/ng2auth/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 |
4 | import { AppRoutingModule } from './app-routing.module';
5 |
6 | import { AppComponent } from './app.component';
7 | import { PublicDealsComponent } from './public-deals/public-deals.component';
8 | import { PrivateDealsComponent } from './private-deals/private-deals.component';
9 | import { CallbackComponent } from './callback.component';
10 | import { AuthService } from './auth/auth.service';
11 | import { DealService } from './deal.service';
12 | import { HttpClientModule } from '@angular/common/http';
13 |
14 |
15 | @NgModule({
16 | declarations: [
17 | AppComponent,
18 | PublicDealsComponent,
19 | PrivateDealsComponent,
20 | CallbackComponent
21 | ],
22 | imports: [
23 | BrowserModule,
24 | AppRoutingModule,
25 | HttpClientModule
26 | ],
27 | providers: [
28 | AuthService,
29 | DealService
30 | ],
31 | bootstrap: [AppComponent]
32 | })
33 | export class AppModule { }
34 |
--------------------------------------------------------------------------------
/ng2auth/src/app/auth/auth.guard.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
3 | import { Observable } from 'rxjs';
4 | import { AuthService } from './auth.service';
5 | import { Router } from '@angular/router';
6 |
7 | @Injectable()
8 | export class AuthGuard implements CanActivate {
9 |
10 | constructor(
11 | private authService: AuthService,
12 | private router: Router
13 | ) {}
14 |
15 | canActivate(
16 | next: ActivatedRouteSnapshot,
17 | state: RouterStateSnapshot): Observable | Promise | boolean {
18 | if (!this.authService.isLoggedIn) {
19 | this.router.navigate(['/']);
20 | return false;
21 | }
22 | return true;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/ng2auth/src/app/auth/auth.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import * as auth0 from 'auth0-js';
3 | import { environment } from './../../environments/environment';
4 | import { Router } from '@angular/router';
5 |
6 | (window as any).global = window;
7 |
8 | @Injectable()
9 | export class AuthService {
10 | // Create Auth0 web auth instance
11 | auth0 = new auth0.WebAuth({
12 | clientID: environment.auth.clientID,
13 | domain: environment.auth.domain,
14 | responseType: 'token',
15 | redirectUri: environment.auth.redirect,
16 | audience: environment.auth.audience,
17 | scope: environment.auth.scope
18 | });
19 | // Store authentication data
20 | expiresAt: number;
21 | userProfile: any;
22 | accessToken: string;
23 | authenticated: boolean;
24 |
25 | constructor(private router: Router) {
26 | this.getAccessToken();
27 | }
28 |
29 | login() {
30 | // Auth0 authorize request
31 | this.auth0.authorize();
32 | }
33 |
34 | handleLoginCallback() {
35 | // When Auth0 hash parsed, get profile
36 | this.auth0.parseHash((err, authResult) => {
37 | if (authResult && authResult.accessToken) {
38 | window.location.hash = '';
39 | this.getUserInfo(authResult);
40 | } else if (err) {
41 | console.error(`Error: ${err.error}`);
42 | }
43 | this.router.navigate(['/']);
44 | });
45 | }
46 |
47 | getAccessToken() {
48 | this.auth0.checkSession({}, (err, authResult) => {
49 | if (authResult && authResult.accessToken) {
50 | this.getUserInfo(authResult);
51 | }
52 | });
53 | }
54 |
55 | getUserInfo(authResult) {
56 | // Use access token to retrieve user's profile and set session
57 | this.auth0.client.userInfo(authResult.accessToken, (err, profile) => {
58 | if (profile) {
59 | this._setSession(authResult, profile);
60 | }
61 | });
62 | }
63 |
64 | private _setSession(authResult, profile) {
65 | // Save authentication data and update login status subject
66 | this.expiresAt = authResult.expiresIn * 1000 + Date.now();
67 | this.accessToken = authResult.accessToken;
68 | this.userProfile = profile;
69 | this.authenticated = true;
70 | }
71 |
72 | logout() {
73 | // Log out of Auth0 session
74 | // Ensure that returnTo URL is specified in Auth0
75 | // Application settings for Allowed Logout URLs
76 | this.auth0.logout({
77 | returnTo: 'http://localhost:4200',
78 | clientID: environment.auth.clientID
79 | });
80 | }
81 |
82 | get isLoggedIn(): boolean {
83 | // Check if current date is before token
84 | // expiration and user is signed in locally
85 | return (Date.now() < this.expiresAt) && this.authenticated;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/ng2auth/src/app/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: `
7 |
8 | Loading...
9 |
10 | `,
11 | styles: []
12 | })
13 | export class CallbackComponent implements OnInit {
14 |
15 | constructor(private auth: AuthService) { }
16 |
17 | ngOnInit() {
18 | this.auth.handleLoginCallback();
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/ng2auth/src/app/deal.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
3 | import { throwError, Observable } from 'rxjs';
4 | import { catchError } from 'rxjs/operators';
5 | import { AuthService } from './auth/auth.service';
6 | import { Deal } from './deal';
7 |
8 | @Injectable()
9 | export class DealService {
10 | // Define the routes we are going to interact with
11 | private publicDealsUrl = 'http://localhost:3001/api/deals/public';
12 | private privateDealsUrl = 'http://localhost:3001/api/deals/private';
13 |
14 | constructor(
15 | private http: HttpClient,
16 | private authService: AuthService
17 | ) { }
18 |
19 | // Implement a method to get the public deals
20 | getPublicDeals() {
21 | return this.http
22 | .get(this.publicDealsUrl)
23 | .pipe(
24 | catchError(this.handleError)
25 | );
26 | }
27 |
28 | // Implement a method to get the private deals
29 | getPrivateDeals() {
30 | return this.http
31 | .get(this.privateDealsUrl, {
32 | headers: new HttpHeaders().set('Authorization', `Bearer ${this.authService.accessToken}`)
33 | })
34 | .pipe(
35 | catchError(this.handleError)
36 | );
37 | }
38 |
39 | // Implement a method to handle errors if any
40 | private handleError(err: HttpErrorResponse | any) {
41 | console.error('An error occurred', err);
42 | return throwError(err.message || err);
43 | }
44 |
45 | purchase(item) {
46 | alert(`You bought the: ${item.name}`);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ng2auth/src/app/deal.ts:
--------------------------------------------------------------------------------
1 | export class Deal {
2 | id: number;
3 | name: string;
4 | description: string;
5 | originalPrice: number;
6 | salePrice: number;
7 | }
8 |
--------------------------------------------------------------------------------
/ng2auth/src/app/private-deals/private-deals.component.css:
--------------------------------------------------------------------------------
1 | .panel-body {
2 | min-height: 100px;
3 | }
4 |
--------------------------------------------------------------------------------
/ng2auth/src/app/private-deals/private-deals.component.html:
--------------------------------------------------------------------------------
1 |
2 | Special (Private) Deals
3 |
4 |
5 |
6 |
7 |
{{ deal.name }}
8 |
9 |
10 | {{ deal.description }}
11 |
12 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
34 | Oops! An error occurred fetching data. Please try again.
35 |
36 |
--------------------------------------------------------------------------------
/ng2auth/src/app/private-deals/private-deals.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, OnDestroy } from '@angular/core';
2 | import { DealService } from '../deal.service';
3 | import { AuthService } from '../auth/auth.service';
4 | import { Subscription } from 'rxjs';
5 | import { Deal } from '../deal';
6 |
7 | @Component({
8 | selector: 'app-private-deals',
9 | templateUrl: './private-deals.component.html',
10 | styleUrls: ['./private-deals.component.css']
11 | })
12 | export class PrivateDealsComponent implements OnInit, OnDestroy {
13 | dealsSub: Subscription;
14 | privateDeals: Deal[];
15 | error: any;
16 |
17 | constructor(
18 | public dealService: DealService,
19 | public authService: AuthService
20 | ) { }
21 |
22 | ngOnInit() {
23 | this.dealsSub = this.dealService
24 | .getPrivateDeals()
25 | .subscribe(
26 | deals => this.privateDeals = deals,
27 | err => error => this.error = err
28 | );
29 | }
30 |
31 | ngOnDestroy() {
32 | this.dealsSub.unsubscribe();
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/ng2auth/src/app/public-deals/public-deals.component.css:
--------------------------------------------------------------------------------
1 | .panel-body {
2 | min-height: 100px;
3 | }
4 |
--------------------------------------------------------------------------------
/ng2auth/src/app/public-deals/public-deals.component.html:
--------------------------------------------------------------------------------
1 | Daily Deals
2 |
3 |
4 |
5 |
6 |
{{ deal.name }}
7 |
8 |
9 | {{ deal.description }}
10 |
11 |
21 |
22 |
23 |
24 |
25 |
26 |
Get More Deals By Logging In
27 |
28 |
29 |
30 |
36 |
37 |
38 | Oops! An error occurred fetching data. Please try again.
39 |
40 |
--------------------------------------------------------------------------------
/ng2auth/src/app/public-deals/public-deals.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, OnDestroy } from '@angular/core';
2 | import { DealService } from '../deal.service';
3 | import { AuthService } from '../auth/auth.service';
4 | import { Subscription } from 'rxjs';
5 | import { Deal } from '../deal';
6 |
7 | @Component({
8 | selector: 'app-public-deals',
9 | templateUrl: './public-deals.component.html',
10 | styleUrls: ['./public-deals.component.css']
11 | })
12 | export class PublicDealsComponent implements OnInit, OnDestroy {
13 | dealsSub: Subscription;
14 | publicDeals: Deal[];
15 | error: any;
16 |
17 | constructor(
18 | public dealService: DealService,
19 | public authService: AuthService) { }
20 |
21 | ngOnInit() {
22 | this.dealsSub = this.dealService
23 | .getPublicDeals()
24 | .subscribe(
25 | deals => this.publicDeals = deals,
26 | err => this.error = err
27 | );
28 | }
29 |
30 | ngOnDestroy() {
31 | this.dealsSub.unsubscribe();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/ng2auth/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/auth0-blog/angular-2-authentication-tutorial/ce4fe9b396080481146b226db01cc2d7925186a5/ng2auth/src/assets/.gitkeep
--------------------------------------------------------------------------------
/ng2auth/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/ng2auth/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 | clientID: 'YOUR-AUTH0-CLIENT-ID',
10 | domain: 'YOUR-AUTH0-DOMAIN', // e.g., you.auth0.com
11 | audience: 'YOUR-AUTH0-API-IDENTIFIER', // e.g., http://localhost:3001
12 | redirect: 'http://localhost:4200/callback',
13 | scope: 'openid profile email'
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/ng2auth/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/auth0-blog/angular-2-authentication-tutorial/ce4fe9b396080481146b226db01cc2d7925186a5/ng2auth/src/favicon.ico
--------------------------------------------------------------------------------
/ng2auth/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ng2auth
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ng2auth/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 | .catch(err => console.log(err));
13 |
--------------------------------------------------------------------------------
/ng2auth/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/weak-map';
35 | // import 'core-js/es6/set';
36 |
37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
38 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
39 |
40 | /** IE10 and IE11 requires the following for the Reflect API. */
41 | // import 'core-js/es6/reflect';
42 |
43 |
44 | /** Evergreen browsers require these. **/
45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
46 | import 'core-js/es7/reflect';
47 |
48 |
49 | /**
50 | * Required to support Web Animations `@angular/platform-browser/animations`.
51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
52 | **/
53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
54 |
55 |
56 |
57 | /***************************************************************************************************
58 | * Zone JS is required by default for Angular itself.
59 | */
60 | import 'zone.js/dist/zone'; // Included with Angular CLI.
61 |
62 |
63 |
64 | /***************************************************************************************************
65 | * APPLICATION IMPORTS
66 | */
67 |
--------------------------------------------------------------------------------
/ng2auth/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/ng2auth/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 const __karma__: any;
17 | declare const 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 |
--------------------------------------------------------------------------------
/ng2auth/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "baseUrl": "./",
6 | "module": "es2015",
7 | "types": []
8 | },
9 | "exclude": [
10 | "test.ts",
11 | "**/*.spec.ts"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/ng2auth/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": [
9 | "jasmine",
10 | "node"
11 | ]
12 | },
13 | "files": [
14 | "test.ts",
15 | "polyfills.ts"
16 | ],
17 | "include": [
18 | "**/*.spec.ts",
19 | "**/*.d.ts"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/ng2auth/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/ng2auth/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "outDir": "./dist/out-tsc",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "target": "es5",
11 | "typeRoots": [
12 | "node_modules/@types"
13 | ],
14 | "lib": [
15 | "es2017",
16 | "dom"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ng2auth/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "deprecation": {
15 | "severity": "warn"
16 | },
17 | "eofline": true,
18 | "forin": true,
19 | "import-blacklist": [
20 | true
21 | ],
22 | "import-spacing": true,
23 | "indent": [
24 | true,
25 | "spaces"
26 | ],
27 | "interface-over-type-literal": true,
28 | "label-position": true,
29 | "max-line-length": [
30 | true,
31 | 140
32 | ],
33 | "member-access": false,
34 | "member-ordering": [
35 | true,
36 | {
37 | "order": [
38 | "static-field",
39 | "instance-field",
40 | "static-method",
41 | "instance-method"
42 | ]
43 | }
44 | ],
45 | "no-arg": true,
46 | "no-bitwise": true,
47 | "no-console": [
48 | true,
49 | "debug",
50 | "info",
51 | "time",
52 | "timeEnd",
53 | "trace"
54 | ],
55 | "no-construct": true,
56 | "no-debugger": true,
57 | "no-duplicate-super": true,
58 | "no-empty": false,
59 | "no-empty-interface": true,
60 | "no-eval": true,
61 | "no-inferrable-types": [
62 | true,
63 | "ignore-params"
64 | ],
65 | "no-misused-new": true,
66 | "no-non-null-assertion": true,
67 | "no-shadowed-variable": true,
68 | "no-string-literal": false,
69 | "no-string-throw": true,
70 | "no-switch-case-fall-through": true,
71 | "no-trailing-whitespace": true,
72 | "no-unnecessary-initializer": true,
73 | "no-unused-expression": true,
74 | "no-use-before-declare": true,
75 | "no-var-keyword": true,
76 | "object-literal-sort-keys": false,
77 | "one-line": [
78 | true,
79 | "check-open-brace",
80 | "check-catch",
81 | "check-else",
82 | "check-whitespace"
83 | ],
84 | "prefer-const": true,
85 | "quotemark": [
86 | true,
87 | "single"
88 | ],
89 | "radix": true,
90 | "semicolon": [
91 | true,
92 | "always"
93 | ],
94 | "triple-equals": [
95 | true,
96 | "allow-null-check"
97 | ],
98 | "typedef-whitespace": [
99 | true,
100 | {
101 | "call-signature": "nospace",
102 | "index-signature": "nospace",
103 | "parameter": "nospace",
104 | "property-declaration": "nospace",
105 | "variable-declaration": "nospace"
106 | }
107 | ],
108 | "typeof-compare": true,
109 | "unified-signatures": true,
110 | "variable-name": false,
111 | "whitespace": [
112 | true,
113 | "check-branch",
114 | "check-decl",
115 | "check-operator",
116 | "check-separator",
117 | "check-type"
118 | ],
119 | "directive-selector": [
120 | true,
121 | "attribute",
122 | "app",
123 | "camelCase"
124 | ],
125 | "component-selector": [
126 | true,
127 | "element",
128 | "app",
129 | "kebab-case"
130 | ],
131 | "angular-whitespace": [true, "check-interpolation"],
132 | "no-output-on-prefix": true,
133 | "use-input-property-decorator": true,
134 | "use-output-property-decorator": true,
135 | "use-host-property-decorator": true,
136 | "no-input-rename": true,
137 | "no-output-rename": true,
138 | "use-life-cycle-interface": true,
139 | "use-pipe-transform-interface": true,
140 | "component-class-suffix": true,
141 | "directive-class-suffix": true
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/server/.gitignore:
--------------------------------------------------------------------------------
1 | env.json
2 | .idea/
3 | /node_modules
4 | /bower_components
5 | /build
6 | /report
7 | /typings
8 | /src/tmp
9 | .DS_Store
10 | /src/assets/styles/*.css
11 | npm-debug.log
--------------------------------------------------------------------------------
/server/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Auth0, Inc. (http://auth0.com)
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.
--------------------------------------------------------------------------------
/server/README.md:
--------------------------------------------------------------------------------
1 | # Daily Deals
2 |
3 | Daily Deals is an application built with Angular 2 that shows how you can add token based authentication to your Angular 2 applications.
4 |
5 | ## Running the App
6 |
7 | Install the dependencies by running `npm install`. Then run `node server` to serve your application.
8 |
9 | You will need to remove the placeholder `AUTH0-CLIENT-SECRET`, `AUTH0-CLIENT-ID` strings in `server.js` and put in your [Auth0](https://manage.auth0.com) credentials. If you don't already have an Auth0 account, [sign up](https://auth0.com/signup) for a free one today.
10 |
11 | ## What is Auth0?
12 |
13 | Auth0 helps you to:
14 |
15 | * 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**.
16 | * Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**.
17 | * Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user.
18 | * Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely.
19 | * Analytics of how, when and where users are logging in.
20 | * Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules).
21 |
22 | ## Create a free Auth0 account
23 |
24 | 1. Go to [Auth0](https://auth0.com/signup) and click Sign Up.
25 | 2. Use Google, GitHub or Microsoft Account to login.
26 |
27 | ## Issue Reporting
28 |
29 | 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.
30 |
31 | ## Author
32 |
33 | [Auth0](auth0.com)
34 |
35 | ## License
36 |
37 | This project is licensed under the MIT license. See the [LICENSE](LICENSE) file for more info.
--------------------------------------------------------------------------------
/server/heroes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const publicHeroes = [
4 | { 'id': 11, 'name': 'Mr. Nice' },
5 | { 'id': 12, 'name': 'Narco' },
6 | { 'id': 13, 'name': 'Bombasto' },
7 | { 'id': 14, 'name': 'Celeritas' },
8 | { 'id': 15, 'name': 'Magneta' },
9 | { 'id': 16, 'name': 'RubberMan' },
10 | { 'id': 17, 'name': 'Dynama' },
11 | { 'id': 18, 'name': 'Dr IQ' },
12 | { 'id': 19, 'name': 'Magma' },
13 | { 'id': 20, 'name': 'Tornado' }
14 | ];
15 |
16 | const secretHeroes = [
17 | { 'id': 21, 'name': 'Wonder Woman' },
18 | { 'id': 22, 'name': 'The Incredible Hulk' },
19 | { 'id': 23, 'name': 'Superman' },
20 | { 'id': 24, 'name': 'Thor' },
21 | { 'id': 25, 'name': 'Batman' },
22 | { 'id': 26, 'name': 'Spiderman' },
23 | { 'id': 27, 'name': 'Captain America' },
24 | { 'id': 28, 'name': 'Silver Surfer' },
25 | { 'id': 29, 'name': 'The Flash' },
26 | { 'id': 30, 'name': 'Iron Man' }
27 | ];
28 |
29 | module.exports = {
30 | publicHeroes,
31 | secretHeroes
32 | }
--------------------------------------------------------------------------------
/server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-authentication-tutorial",
3 | "version": "0.0.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@types/body-parser": {
8 | "version": "1.16.8",
9 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.8.tgz",
10 | "integrity": "sha512-BdN2PXxOFnTXFcyONPW6t0fHjz2fvRZHVMFpaS0wYr+Y8fWEaNOs4V8LEu/fpzQlMx+ahdndgTaGTwPC+J/EeA==",
11 | "requires": {
12 | "@types/express": "4.0.39",
13 | "@types/node": "8.0.53"
14 | }
15 | },
16 | "@types/express": {
17 | "version": "4.0.39",
18 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.39.tgz",
19 | "integrity": "sha512-dBUam7jEjyuEofigUXCtublUHknRZvcRgITlGsTbFgPvnTwtQUt2NgLakbsf+PsGo/Nupqr3IXCYsOpBpofyrA==",
20 | "requires": {
21 | "@types/body-parser": "1.16.8",
22 | "@types/express-serve-static-core": "4.0.57",
23 | "@types/serve-static": "1.13.1"
24 | }
25 | },
26 | "@types/express-jwt": {
27 | "version": "0.0.34",
28 | "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.34.tgz",
29 | "integrity": "sha1-/b7kxq9cCiRu8qkz9VGZc8dxfwI=",
30 | "requires": {
31 | "@types/express": "4.0.39",
32 | "@types/express-unless": "0.0.32"
33 | }
34 | },
35 | "@types/express-serve-static-core": {
36 | "version": "4.0.57",
37 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.0.57.tgz",
38 | "integrity": "sha512-QLAHjdLwEICm3thVbXSKRoisjfgMVI4xJH/HU8F385BR2HI7PmM6ax4ELXf8Du6sLmSpySXMYaI+xc//oQ/IFw==",
39 | "requires": {
40 | "@types/node": "8.0.53"
41 | }
42 | },
43 | "@types/express-unless": {
44 | "version": "0.0.32",
45 | "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.0.32.tgz",
46 | "integrity": "sha512-6YpJyFNlDDnPnRjMOvJCoDYlSDDmG/OEEUsPk7yhNkL4G9hUYtgab6vi1CcWsGSSSM0CsvNlWTG+ywAGnvF03g==",
47 | "requires": {
48 | "@types/express": "4.0.39"
49 | }
50 | },
51 | "@types/mime": {
52 | "version": "2.0.0",
53 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz",
54 | "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA=="
55 | },
56 | "@types/node": {
57 | "version": "8.0.53",
58 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz",
59 | "integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ=="
60 | },
61 | "@types/serve-static": {
62 | "version": "1.13.1",
63 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz",
64 | "integrity": "sha512-jDMH+3BQPtvqZVIcsH700Dfi8Q3MIcEx16g/VdxjoqiGR/NntekB10xdBpirMKnPe9z2C5cBmL0vte0YttOr3Q==",
65 | "requires": {
66 | "@types/express-serve-static-core": "4.0.57",
67 | "@types/mime": "2.0.0"
68 | }
69 | },
70 | "accepts": {
71 | "version": "1.3.4",
72 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
73 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
74 | "requires": {
75 | "mime-types": "2.1.17",
76 | "negotiator": "0.6.1"
77 | }
78 | },
79 | "ajv": {
80 | "version": "5.5.0",
81 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz",
82 | "integrity": "sha1-6yhAdG6dxIvV4GOjbj/UAMXqtak=",
83 | "requires": {
84 | "co": "4.6.0",
85 | "fast-deep-equal": "1.0.0",
86 | "fast-json-stable-stringify": "2.0.0",
87 | "json-schema-traverse": "0.3.1"
88 | }
89 | },
90 | "array-flatten": {
91 | "version": "1.1.1",
92 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
93 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
94 | },
95 | "asn1": {
96 | "version": "0.2.3",
97 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
98 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
99 | },
100 | "assert-plus": {
101 | "version": "1.0.0",
102 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
103 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
104 | },
105 | "async": {
106 | "version": "1.5.2",
107 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
108 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
109 | },
110 | "asynckit": {
111 | "version": "0.4.0",
112 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
113 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
114 | },
115 | "aws-sign2": {
116 | "version": "0.7.0",
117 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
118 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
119 | },
120 | "aws4": {
121 | "version": "1.6.0",
122 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
123 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
124 | },
125 | "base64url": {
126 | "version": "2.0.0",
127 | "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz",
128 | "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs="
129 | },
130 | "bcrypt-pbkdf": {
131 | "version": "1.0.1",
132 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
133 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
134 | "optional": true,
135 | "requires": {
136 | "tweetnacl": "0.14.5"
137 | }
138 | },
139 | "body-parser": {
140 | "version": "1.18.2",
141 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
142 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
143 | "requires": {
144 | "bytes": "3.0.0",
145 | "content-type": "1.0.4",
146 | "debug": "2.6.9",
147 | "depd": "1.1.1",
148 | "http-errors": "1.6.2",
149 | "iconv-lite": "0.4.19",
150 | "on-finished": "2.3.0",
151 | "qs": "6.5.1",
152 | "raw-body": "2.3.2",
153 | "type-is": "1.6.15"
154 | }
155 | },
156 | "boom": {
157 | "version": "4.3.1",
158 | "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
159 | "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
160 | "requires": {
161 | "hoek": "4.2.0"
162 | },
163 | "dependencies": {
164 | "hoek": {
165 | "version": "4.2.0",
166 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
167 | "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
168 | }
169 | }
170 | },
171 | "buffer-equal-constant-time": {
172 | "version": "1.0.1",
173 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
174 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
175 | },
176 | "bytes": {
177 | "version": "3.0.0",
178 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
179 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
180 | },
181 | "caseless": {
182 | "version": "0.12.0",
183 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
184 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
185 | },
186 | "co": {
187 | "version": "4.6.0",
188 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
189 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
190 | },
191 | "combined-stream": {
192 | "version": "1.0.5",
193 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
194 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
195 | "requires": {
196 | "delayed-stream": "1.0.0"
197 | }
198 | },
199 | "content-disposition": {
200 | "version": "0.5.2",
201 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
202 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
203 | },
204 | "content-type": {
205 | "version": "1.0.4",
206 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
207 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
208 | },
209 | "cookie": {
210 | "version": "0.3.1",
211 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
212 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
213 | },
214 | "cookie-signature": {
215 | "version": "1.0.6",
216 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
217 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
218 | },
219 | "core-util-is": {
220 | "version": "1.0.2",
221 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
222 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
223 | },
224 | "cors": {
225 | "version": "2.8.4",
226 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz",
227 | "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=",
228 | "requires": {
229 | "object-assign": "4.1.1",
230 | "vary": "1.1.2"
231 | }
232 | },
233 | "cryptiles": {
234 | "version": "3.1.2",
235 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
236 | "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
237 | "requires": {
238 | "boom": "5.2.0"
239 | },
240 | "dependencies": {
241 | "boom": {
242 | "version": "5.2.0",
243 | "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
244 | "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
245 | "requires": {
246 | "hoek": "4.2.0"
247 | }
248 | },
249 | "hoek": {
250 | "version": "4.2.0",
251 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
252 | "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
253 | }
254 | }
255 | },
256 | "dashdash": {
257 | "version": "1.14.1",
258 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
259 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
260 | "requires": {
261 | "assert-plus": "1.0.0"
262 | }
263 | },
264 | "debug": {
265 | "version": "2.6.9",
266 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
267 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
268 | "requires": {
269 | "ms": "2.0.0"
270 | }
271 | },
272 | "delayed-stream": {
273 | "version": "1.0.0",
274 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
275 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
276 | },
277 | "depd": {
278 | "version": "1.1.1",
279 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
280 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
281 | },
282 | "destroy": {
283 | "version": "1.0.4",
284 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
285 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
286 | },
287 | "ecc-jsbn": {
288 | "version": "0.1.1",
289 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
290 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
291 | "optional": true,
292 | "requires": {
293 | "jsbn": "0.1.1"
294 | }
295 | },
296 | "ecdsa-sig-formatter": {
297 | "version": "1.0.9",
298 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz",
299 | "integrity": "sha1-S8kmJ07Dtau1AW5+HWCSGsJisqE=",
300 | "requires": {
301 | "base64url": "2.0.0",
302 | "safe-buffer": "5.1.1"
303 | }
304 | },
305 | "ee-first": {
306 | "version": "1.1.1",
307 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
308 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
309 | },
310 | "encodeurl": {
311 | "version": "1.0.1",
312 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
313 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
314 | },
315 | "escape-html": {
316 | "version": "1.0.3",
317 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
318 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
319 | },
320 | "etag": {
321 | "version": "1.8.1",
322 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
323 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
324 | },
325 | "express": {
326 | "version": "4.16.2",
327 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
328 | "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
329 | "requires": {
330 | "accepts": "1.3.4",
331 | "array-flatten": "1.1.1",
332 | "body-parser": "1.18.2",
333 | "content-disposition": "0.5.2",
334 | "content-type": "1.0.4",
335 | "cookie": "0.3.1",
336 | "cookie-signature": "1.0.6",
337 | "debug": "2.6.9",
338 | "depd": "1.1.1",
339 | "encodeurl": "1.0.1",
340 | "escape-html": "1.0.3",
341 | "etag": "1.8.1",
342 | "finalhandler": "1.1.0",
343 | "fresh": "0.5.2",
344 | "merge-descriptors": "1.0.1",
345 | "methods": "1.1.2",
346 | "on-finished": "2.3.0",
347 | "parseurl": "1.3.2",
348 | "path-to-regexp": "0.1.7",
349 | "proxy-addr": "2.0.2",
350 | "qs": "6.5.1",
351 | "range-parser": "1.2.0",
352 | "safe-buffer": "5.1.1",
353 | "send": "0.16.1",
354 | "serve-static": "1.13.1",
355 | "setprototypeof": "1.1.0",
356 | "statuses": "1.3.1",
357 | "type-is": "1.6.15",
358 | "utils-merge": "1.0.1",
359 | "vary": "1.1.2"
360 | },
361 | "dependencies": {
362 | "setprototypeof": {
363 | "version": "1.1.0",
364 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
365 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
366 | },
367 | "statuses": {
368 | "version": "1.3.1",
369 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
370 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
371 | }
372 | }
373 | },
374 | "express-jwt": {
375 | "version": "5.3.0",
376 | "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.0.tgz",
377 | "integrity": "sha1-PZDNZYAuYzYlLxnmo98+FJ4MXqA=",
378 | "requires": {
379 | "async": "1.5.2",
380 | "express-unless": "0.3.1",
381 | "jsonwebtoken": "7.4.3",
382 | "lodash.set": "4.3.2"
383 | }
384 | },
385 | "express-unless": {
386 | "version": "0.3.1",
387 | "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz",
388 | "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA="
389 | },
390 | "extend": {
391 | "version": "3.0.1",
392 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
393 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
394 | },
395 | "extsprintf": {
396 | "version": "1.3.0",
397 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
398 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
399 | },
400 | "fast-deep-equal": {
401 | "version": "1.0.0",
402 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
403 | "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
404 | },
405 | "fast-json-stable-stringify": {
406 | "version": "2.0.0",
407 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
408 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
409 | },
410 | "finalhandler": {
411 | "version": "1.1.0",
412 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
413 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
414 | "requires": {
415 | "debug": "2.6.9",
416 | "encodeurl": "1.0.1",
417 | "escape-html": "1.0.3",
418 | "on-finished": "2.3.0",
419 | "parseurl": "1.3.2",
420 | "statuses": "1.3.1",
421 | "unpipe": "1.0.0"
422 | },
423 | "dependencies": {
424 | "statuses": {
425 | "version": "1.3.1",
426 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
427 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
428 | }
429 | }
430 | },
431 | "forever-agent": {
432 | "version": "0.6.1",
433 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
434 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
435 | },
436 | "form-data": {
437 | "version": "2.3.1",
438 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
439 | "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
440 | "requires": {
441 | "asynckit": "0.4.0",
442 | "combined-stream": "1.0.5",
443 | "mime-types": "2.1.17"
444 | }
445 | },
446 | "forwarded": {
447 | "version": "0.1.2",
448 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
449 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
450 | },
451 | "fresh": {
452 | "version": "0.5.2",
453 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
454 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
455 | },
456 | "getpass": {
457 | "version": "0.1.7",
458 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
459 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
460 | "requires": {
461 | "assert-plus": "1.0.0"
462 | }
463 | },
464 | "har-schema": {
465 | "version": "2.0.0",
466 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
467 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
468 | },
469 | "har-validator": {
470 | "version": "5.0.3",
471 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
472 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
473 | "requires": {
474 | "ajv": "5.5.0",
475 | "har-schema": "2.0.0"
476 | }
477 | },
478 | "hawk": {
479 | "version": "6.0.2",
480 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
481 | "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
482 | "requires": {
483 | "boom": "4.3.1",
484 | "cryptiles": "3.1.2",
485 | "hoek": "4.2.0",
486 | "sntp": "2.1.0"
487 | },
488 | "dependencies": {
489 | "hoek": {
490 | "version": "4.2.0",
491 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
492 | "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
493 | }
494 | }
495 | },
496 | "hoek": {
497 | "version": "2.16.3",
498 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
499 | "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
500 | },
501 | "http-errors": {
502 | "version": "1.6.2",
503 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
504 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
505 | "requires": {
506 | "depd": "1.1.1",
507 | "inherits": "2.0.3",
508 | "setprototypeof": "1.0.3",
509 | "statuses": "1.4.0"
510 | }
511 | },
512 | "http-signature": {
513 | "version": "1.2.0",
514 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
515 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
516 | "requires": {
517 | "assert-plus": "1.0.0",
518 | "jsprim": "1.4.1",
519 | "sshpk": "1.13.1"
520 | }
521 | },
522 | "iconv-lite": {
523 | "version": "0.4.19",
524 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
525 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
526 | },
527 | "inherits": {
528 | "version": "2.0.3",
529 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
530 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
531 | },
532 | "ipaddr.js": {
533 | "version": "1.5.2",
534 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
535 | "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
536 | },
537 | "is-typedarray": {
538 | "version": "1.0.0",
539 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
540 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
541 | },
542 | "isemail": {
543 | "version": "1.2.0",
544 | "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz",
545 | "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo="
546 | },
547 | "isstream": {
548 | "version": "0.1.2",
549 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
550 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
551 | },
552 | "joi": {
553 | "version": "6.10.1",
554 | "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz",
555 | "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=",
556 | "requires": {
557 | "hoek": "2.16.3",
558 | "isemail": "1.2.0",
559 | "moment": "2.19.3",
560 | "topo": "1.1.0"
561 | }
562 | },
563 | "jsbn": {
564 | "version": "0.1.1",
565 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
566 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
567 | "optional": true
568 | },
569 | "json-schema": {
570 | "version": "0.2.3",
571 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
572 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
573 | },
574 | "json-schema-traverse": {
575 | "version": "0.3.1",
576 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
577 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
578 | },
579 | "json-stringify-safe": {
580 | "version": "5.0.1",
581 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
582 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
583 | },
584 | "jsonwebtoken": {
585 | "version": "7.4.3",
586 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz",
587 | "integrity": "sha1-d/UCHeBYtgWheD+hKD6ZgS5kVjg=",
588 | "requires": {
589 | "joi": "6.10.1",
590 | "jws": "3.1.4",
591 | "lodash.once": "4.1.1",
592 | "ms": "2.0.0",
593 | "xtend": "4.0.1"
594 | }
595 | },
596 | "jsprim": {
597 | "version": "1.4.1",
598 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
599 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
600 | "requires": {
601 | "assert-plus": "1.0.0",
602 | "extsprintf": "1.3.0",
603 | "json-schema": "0.2.3",
604 | "verror": "1.10.0"
605 | }
606 | },
607 | "jwa": {
608 | "version": "1.1.5",
609 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz",
610 | "integrity": "sha1-oFUs4CIHQs1S4VN3SjKQXDDnVuU=",
611 | "requires": {
612 | "base64url": "2.0.0",
613 | "buffer-equal-constant-time": "1.0.1",
614 | "ecdsa-sig-formatter": "1.0.9",
615 | "safe-buffer": "5.1.1"
616 | }
617 | },
618 | "jwks-rsa": {
619 | "version": "1.2.1",
620 | "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.2.1.tgz",
621 | "integrity": "sha512-xg+fw7FOV4eGdDIEMqQJvPLmFv85h4uN+j/GKwJZAxlCrDQpM8ov1F709xKGEp/dG3l4TUxoSOeN6YK7+KpinQ==",
622 | "requires": {
623 | "@types/express-jwt": "0.0.34",
624 | "debug": "2.6.9",
625 | "limiter": "1.1.2",
626 | "lru-memoizer": "1.11.1",
627 | "ms": "2.0.0",
628 | "request": "2.83.0"
629 | }
630 | },
631 | "jws": {
632 | "version": "3.1.4",
633 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz",
634 | "integrity": "sha1-+ei5M46KhHJ31kRLFGT2GIDgUKI=",
635 | "requires": {
636 | "base64url": "2.0.0",
637 | "jwa": "1.1.5",
638 | "safe-buffer": "5.1.1"
639 | }
640 | },
641 | "limiter": {
642 | "version": "1.1.2",
643 | "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.2.tgz",
644 | "integrity": "sha512-JIKZ0xb6fZZYa3deZ0BgXCgX6HgV8Nx3mFGeFHmFWW8Fb2c08e0CyE+G3nalpD0xGvGssjGb1UdFr+PprxZEbw=="
645 | },
646 | "lock": {
647 | "version": "0.1.4",
648 | "resolved": "https://registry.npmjs.org/lock/-/lock-0.1.4.tgz",
649 | "integrity": "sha1-/sfervF+fDoKVeHaBCgD4l2RdF0="
650 | },
651 | "lodash": {
652 | "version": "4.5.1",
653 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.5.1.tgz",
654 | "integrity": "sha1-gOigdMpfOJOmscELKmNkktcQwxY="
655 | },
656 | "lodash.once": {
657 | "version": "4.1.1",
658 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
659 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
660 | },
661 | "lodash.set": {
662 | "version": "4.3.2",
663 | "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz",
664 | "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM="
665 | },
666 | "lru-cache": {
667 | "version": "4.0.2",
668 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz",
669 | "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=",
670 | "requires": {
671 | "pseudomap": "1.0.2",
672 | "yallist": "2.1.2"
673 | }
674 | },
675 | "lru-memoizer": {
676 | "version": "1.11.1",
677 | "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-1.11.1.tgz",
678 | "integrity": "sha1-BpP2EAWTkUwC4ZK/m42TiEy/UNM=",
679 | "requires": {
680 | "lock": "0.1.4",
681 | "lodash": "4.5.1",
682 | "lru-cache": "4.0.2",
683 | "very-fast-args": "1.1.0"
684 | }
685 | },
686 | "media-typer": {
687 | "version": "0.3.0",
688 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
689 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
690 | },
691 | "merge-descriptors": {
692 | "version": "1.0.1",
693 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
694 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
695 | },
696 | "methods": {
697 | "version": "1.1.2",
698 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
699 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
700 | },
701 | "mime": {
702 | "version": "1.4.1",
703 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
704 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
705 | },
706 | "mime-db": {
707 | "version": "1.30.0",
708 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
709 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
710 | },
711 | "mime-types": {
712 | "version": "2.1.17",
713 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
714 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
715 | "requires": {
716 | "mime-db": "1.30.0"
717 | }
718 | },
719 | "moment": {
720 | "version": "2.19.3",
721 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.3.tgz",
722 | "integrity": "sha1-vbmdJw1tf9p4zA+6zoVeJ/59pp8="
723 | },
724 | "ms": {
725 | "version": "2.0.0",
726 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
727 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
728 | },
729 | "negotiator": {
730 | "version": "0.6.1",
731 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
732 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
733 | },
734 | "oauth-sign": {
735 | "version": "0.8.2",
736 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
737 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
738 | },
739 | "object-assign": {
740 | "version": "4.1.1",
741 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
742 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
743 | },
744 | "on-finished": {
745 | "version": "2.3.0",
746 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
747 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
748 | "requires": {
749 | "ee-first": "1.1.1"
750 | }
751 | },
752 | "parseurl": {
753 | "version": "1.3.2",
754 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
755 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
756 | },
757 | "path-to-regexp": {
758 | "version": "0.1.7",
759 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
760 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
761 | },
762 | "performance-now": {
763 | "version": "2.1.0",
764 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
765 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
766 | },
767 | "proxy-addr": {
768 | "version": "2.0.2",
769 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
770 | "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
771 | "requires": {
772 | "forwarded": "0.1.2",
773 | "ipaddr.js": "1.5.2"
774 | }
775 | },
776 | "pseudomap": {
777 | "version": "1.0.2",
778 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
779 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
780 | },
781 | "punycode": {
782 | "version": "1.4.1",
783 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
784 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
785 | },
786 | "qs": {
787 | "version": "6.5.1",
788 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
789 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
790 | },
791 | "range-parser": {
792 | "version": "1.2.0",
793 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
794 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
795 | },
796 | "raw-body": {
797 | "version": "2.3.2",
798 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
799 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
800 | "requires": {
801 | "bytes": "3.0.0",
802 | "http-errors": "1.6.2",
803 | "iconv-lite": "0.4.19",
804 | "unpipe": "1.0.0"
805 | }
806 | },
807 | "request": {
808 | "version": "2.83.0",
809 | "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
810 | "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
811 | "requires": {
812 | "aws-sign2": "0.7.0",
813 | "aws4": "1.6.0",
814 | "caseless": "0.12.0",
815 | "combined-stream": "1.0.5",
816 | "extend": "3.0.1",
817 | "forever-agent": "0.6.1",
818 | "form-data": "2.3.1",
819 | "har-validator": "5.0.3",
820 | "hawk": "6.0.2",
821 | "http-signature": "1.2.0",
822 | "is-typedarray": "1.0.0",
823 | "isstream": "0.1.2",
824 | "json-stringify-safe": "5.0.1",
825 | "mime-types": "2.1.17",
826 | "oauth-sign": "0.8.2",
827 | "performance-now": "2.1.0",
828 | "qs": "6.5.1",
829 | "safe-buffer": "5.1.1",
830 | "stringstream": "0.0.5",
831 | "tough-cookie": "2.3.3",
832 | "tunnel-agent": "0.6.0",
833 | "uuid": "3.1.0"
834 | }
835 | },
836 | "safe-buffer": {
837 | "version": "5.1.1",
838 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
839 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
840 | },
841 | "send": {
842 | "version": "0.16.1",
843 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
844 | "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
845 | "requires": {
846 | "debug": "2.6.9",
847 | "depd": "1.1.1",
848 | "destroy": "1.0.4",
849 | "encodeurl": "1.0.1",
850 | "escape-html": "1.0.3",
851 | "etag": "1.8.1",
852 | "fresh": "0.5.2",
853 | "http-errors": "1.6.2",
854 | "mime": "1.4.1",
855 | "ms": "2.0.0",
856 | "on-finished": "2.3.0",
857 | "range-parser": "1.2.0",
858 | "statuses": "1.3.1"
859 | },
860 | "dependencies": {
861 | "statuses": {
862 | "version": "1.3.1",
863 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
864 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
865 | }
866 | }
867 | },
868 | "serve-static": {
869 | "version": "1.13.1",
870 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
871 | "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
872 | "requires": {
873 | "encodeurl": "1.0.1",
874 | "escape-html": "1.0.3",
875 | "parseurl": "1.3.2",
876 | "send": "0.16.1"
877 | }
878 | },
879 | "setprototypeof": {
880 | "version": "1.0.3",
881 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
882 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
883 | },
884 | "sntp": {
885 | "version": "2.1.0",
886 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
887 | "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
888 | "requires": {
889 | "hoek": "4.2.0"
890 | },
891 | "dependencies": {
892 | "hoek": {
893 | "version": "4.2.0",
894 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
895 | "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
896 | }
897 | }
898 | },
899 | "sshpk": {
900 | "version": "1.13.1",
901 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
902 | "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
903 | "requires": {
904 | "asn1": "0.2.3",
905 | "assert-plus": "1.0.0",
906 | "bcrypt-pbkdf": "1.0.1",
907 | "dashdash": "1.14.1",
908 | "ecc-jsbn": "0.1.1",
909 | "getpass": "0.1.7",
910 | "jsbn": "0.1.1",
911 | "tweetnacl": "0.14.5"
912 | }
913 | },
914 | "statuses": {
915 | "version": "1.4.0",
916 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
917 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
918 | },
919 | "stringstream": {
920 | "version": "0.0.5",
921 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
922 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
923 | },
924 | "topo": {
925 | "version": "1.1.0",
926 | "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz",
927 | "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=",
928 | "requires": {
929 | "hoek": "2.16.3"
930 | }
931 | },
932 | "tough-cookie": {
933 | "version": "2.3.3",
934 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
935 | "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
936 | "requires": {
937 | "punycode": "1.4.1"
938 | }
939 | },
940 | "tunnel-agent": {
941 | "version": "0.6.0",
942 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
943 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
944 | "requires": {
945 | "safe-buffer": "5.1.1"
946 | }
947 | },
948 | "tweetnacl": {
949 | "version": "0.14.5",
950 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
951 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
952 | "optional": true
953 | },
954 | "type-is": {
955 | "version": "1.6.15",
956 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
957 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
958 | "requires": {
959 | "media-typer": "0.3.0",
960 | "mime-types": "2.1.17"
961 | }
962 | },
963 | "unpipe": {
964 | "version": "1.0.0",
965 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
966 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
967 | },
968 | "utils-merge": {
969 | "version": "1.0.1",
970 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
971 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
972 | },
973 | "uuid": {
974 | "version": "3.1.0",
975 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
976 | "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
977 | },
978 | "vary": {
979 | "version": "1.1.2",
980 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
981 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
982 | },
983 | "verror": {
984 | "version": "1.10.0",
985 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
986 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
987 | "requires": {
988 | "assert-plus": "1.0.0",
989 | "core-util-is": "1.0.2",
990 | "extsprintf": "1.3.0"
991 | }
992 | },
993 | "very-fast-args": {
994 | "version": "1.1.0",
995 | "resolved": "https://registry.npmjs.org/very-fast-args/-/very-fast-args-1.1.0.tgz",
996 | "integrity": "sha1-4W0dH6+KbllqJGQh/ZCneWPQs5Y="
997 | },
998 | "xtend": {
999 | "version": "4.0.1",
1000 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
1001 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
1002 | },
1003 | "yallist": {
1004 | "version": "2.1.2",
1005 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
1006 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
1007 | }
1008 | }
1009 | }
1010 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-authentication-tutorial",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "node server.js",
9 | "dev": "nodemon server.js"
10 | },
11 | "author": "Auth0",
12 | "license": "MIT",
13 | "dependencies": {
14 | "body-parser": "^1.18.2",
15 | "cors": "^2.8.4",
16 | "express": "^4.16.2",
17 | "express-jwt": "^5.3.0",
18 | "jwks-rsa": "^1.2.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const express = require('express');
4 | const app = express();
5 | const jwt = require('express-jwt');
6 | const jwks = require('jwks-rsa');
7 | const cors = require('cors');
8 | const bodyParser = require('body-parser');
9 |
10 | app.use(bodyParser.json());
11 | app.use(bodyParser.urlencoded({ extended: true }));
12 | app.use(cors());
13 |
14 | const authCheck = jwt({
15 | secret: jwks.expressJwtSecret({
16 | cache: true,
17 | rateLimit: true,
18 | jwksRequestsPerMinute: 5,
19 | jwksUri: "https://kmaida.auth0.com/.well-known/jwks.json" // @TODO: remove domain name
20 | }),
21 | audience: 'http://localhost:3001',
22 | issuer: "https://kmaida.auth0.com/", // @TODO: remove domain name
23 | algorithms: ['RS256']
24 | });
25 |
26 | app.get('/api/deals/public', (req, res)=>{
27 | let deals = [
28 | {
29 | id: 12231,
30 | name: 'Playstation 4 500GB Console',
31 | description: 'The Playstation 4 is the next gen console to own. With the best games and online experience.',
32 | originalPrice: 399.99,
33 | salePrice: 299.99
34 | },
35 | {
36 | id: 12234,
37 | name: 'Galaxy Note 7',
38 | description: 'The Note 7 has been fixed and will no longer explode. Get it an amazing price!',
39 | originalPrice: 899.99,
40 | salePrice: 499.99
41 | },
42 | {
43 | id: 12245,
44 | name: 'Macbook Pro 2016',
45 | description: 'The Macbook Pro is the de-facto standard for best in breed mobile computing.',
46 | originalPrice: 2199.99,
47 | salePrice: 1999.99
48 | },
49 | {
50 | id: 12267,
51 | name: 'Amazon Echo',
52 | description: 'Turn your home into a smart home with Amazon Echo. Just say the word and Echo will do it.',
53 | originalPrice: 179.99,
54 | salePrice: 129.99
55 | },
56 | {
57 | id: 12288,
58 | name: 'Nest Outdoor Camera',
59 | description: 'The Nest Outdoor camera records and keeps track of events outside your home 24/7.',
60 | originalPrice: 199.99,
61 | salePrice: 149.99
62 | },
63 | {
64 | id: 12290,
65 | name: 'GoPro 4',
66 | description: 'Record yourself in first person 24/7 with the GoPro 4. Show everyone how exciting your life is.',
67 | originalPrice: 299.99,
68 | salePrice: 199.99
69 | },
70 | ];
71 | res.json(deals);
72 | })
73 |
74 | app.get('/api/deals/private', authCheck, (req,res)=>{
75 | let deals = [
76 | {
77 | id: 14423,
78 | name: 'Tesla S',
79 | description: 'Ride in style and say goodbye to paying for gas. The Tesla S is the car of the future.',
80 | originalPrice: 90000.00,
81 | salePrice: 75000.00
82 | },
83 | {
84 | id: 14553,
85 | name: 'DJI Phantom 4',
86 | description: 'The Drone revolution is here. Take to the skies with the DJI Phantom 4.',
87 | originalPrice: 1299.99,
88 | salePrice: 749.99
89 | },
90 | {
91 | id: 15900,
92 | name: 'iPhone 7 - Jet Black',
93 | description: 'Get the latest and greatest iPhone in the limited edition jet black.',
94 | originalPrice: 899.99,
95 | salePrice: 799.99
96 | },
97 | {
98 | id: 16000,
99 | name: '70" Samsung 4K HDR TV',
100 | description: 'Watch as if you were there with the latest innovations including 4K and HDR.',
101 | originalPrice: 2999.99,
102 | salePrice: 2499.99
103 | },
104 | {
105 | id: 17423,
106 | name: 'Canon t8i DSLR',
107 | description: 'Capture life\'s moments with the amazing Canon t8i DSLR',
108 | originalPrice: 999.99,
109 | salePrice: 549.99
110 | },
111 | {
112 | id: 17423,
113 | name: 'Xbox One S',
114 | description: 'Get the latest Xbox and play the best first party games including Gears of War and Forza.',
115 | originalPrice: 299.99,
116 | salePrice: 279.99
117 | },
118 | ];
119 | res.json(deals);
120 | })
121 |
122 | app.listen(3001);
123 | console.log('Listening on localhost:3001');
--------------------------------------------------------------------------------