diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..496ee2ca --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store \ No newline at end of file diff --git a/02-Custom-Login/.editorconfig b/02-Custom-Login/.editorconfig new file mode 100644 index 00000000..6e87a003 --- /dev/null +++ b/02-Custom-Login/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/02-Custom-Login/.gitignore b/02-Custom-Login/.gitignore new file mode 100644 index 00000000..8328204b --- /dev/null +++ b/02-Custom-Login/.gitignore @@ -0,0 +1,42 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. + +# compiled output +/dist +/tmp + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log +/typings + +# e2e +/e2e/*.js +/e2e/*.map + +#System Files +.DS_Store +Thumbs.db + +auth0-variables.ts diff --git a/02-Custom-Login/README.md b/02-Custom-Login/README.md new file mode 100644 index 00000000..e61a3b13 --- /dev/null +++ b/02-Custom-Login/README.md @@ -0,0 +1,59 @@ +# Auth0 Angular Custom Login + +This sample demonstrates how to add authentication with a custom login form to an Angular application using Auth0. The sample uses the Angular CLI. + +## Getting Started + +If you haven't already done so, [sign up](https://auth0.com) for your free Auth0 account and create a new client in the [dashboard](https://manage.auth0.com). Find the **domain** and **client ID** from the settings area and add the URL for your application to the **Allowed Callback URLs** box. + +Clone the repo or download it from the Angular quickstart page in Auth0's documentation. Install the Angular CLI and the dependencies for the app. + +```bash +npm install -g angular-cli +cd 02-Custom-Login +npm install +``` + +## Set the Client ID and Domain + +If you download the sample from the quickstart page, it will come pre-populated with the **client ID** and **domain** for your application. If you clone the repo directly from Github, rename the `auth0-variables.ts.example` file to `auth0-variables.ts` and provide the **client ID** and **domain** there. This file is located in `src/app/auth/`. + +## Run the Application + +The development server that comes with the Angular CLI can be used to serve the application. + +```bash +ng serve +``` + +The application will be served at `http://localhost:4200`. + +## What is Auth0? + +Auth0 helps you to: + +* 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**. +* Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. +* Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. +* Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. +* Analytics of how, when and where users are logging in. +* Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). + +## Create a free Auth0 account + +1. Go to [Auth0](https://auth0.com/signup) and click Sign Up. +2. Use Google, GitHub or Microsoft Account to login. + +## Issue Reporting + +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. + +## Author + +[Auth0](auth0.com) + +## License + +This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. + + diff --git a/02-Custom-Login/angular-cli.json b/02-Custom-Login/angular-cli.json new file mode 100644 index 00000000..39ebbb1f --- /dev/null +++ b/02-Custom-Login/angular-cli.json @@ -0,0 +1,62 @@ +{ + "project": { + "version": "1.0.0-beta.24", + "name": "custom-login" + }, + "apps": [ + { + "root": "src", + "outDir": "dist", + "assets": [ + "assets", + "favicon.ico" + ], + "index": "index.html", + "main": "main.ts", + "test": "test.ts", + "tsconfig": "tsconfig.json", + "prefix": "app", + "mobile": false, + "styles": [ + "styles.css", + "../node_modules/bootstrap/dist/css/bootstrap.min.css" + ], + "scripts": [ + "../node_modules/auth0-js/build/auth0.js" + ], + "environments": { + "source": "environments/environment.ts", + "dev": "environments/environment.ts", + "prod": "environments/environment.prod.ts" + } + } + ], + "addons": [], + "packages": [], + "e2e": { + "protractor": { + "config": "./protractor.conf.js" + } + }, + "test": { + "karma": { + "config": "./karma.conf.js" + } + }, + "defaults": { + "styleExt": "css", + "prefixInterfaces": false, + "inline": { + "style": false, + "template": false + }, + "spec": { + "class": false, + "component": true, + "directive": true, + "module": false, + "pipe": true, + "service": true + } + } +} diff --git a/02-Custom-Login/e2e/app.e2e-spec.ts b/02-Custom-Login/e2e/app.e2e-spec.ts new file mode 100644 index 00000000..06f43423 --- /dev/null +++ b/02-Custom-Login/e2e/app.e2e-spec.ts @@ -0,0 +1,14 @@ +import { CustomLoginPage } from './app.po'; + +describe('custom-login App', function() { + let page: CustomLoginPage; + + beforeEach(() => { + page = new CustomLoginPage(); + }); + + it('should display message saying app works', () => { + page.navigateTo(); + expect(page.getParagraphText()).toEqual('app works!'); + }); +}); diff --git a/02-Custom-Login/e2e/app.po.ts b/02-Custom-Login/e2e/app.po.ts new file mode 100644 index 00000000..983dde87 --- /dev/null +++ b/02-Custom-Login/e2e/app.po.ts @@ -0,0 +1,11 @@ +import { browser, element, by } from 'protractor'; + +export class CustomLoginPage { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('app-root h1')).getText(); + } +} diff --git a/02-Custom-Login/e2e/tsconfig.json b/02-Custom-Login/e2e/tsconfig.json new file mode 100644 index 00000000..656bdb14 --- /dev/null +++ b/02-Custom-Login/e2e/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "declaration": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "module": "commonjs", + "moduleResolution": "node", + "outDir": "../dist/out-tsc-e2e", + "sourceMap": true, + "target": "es5", + "typeRoots": [ + "../node_modules/@types" + ] + } +} diff --git a/02-Custom-Login/karma.conf.js b/02-Custom-Login/karma.conf.js new file mode 100644 index 00000000..1f2613a3 --- /dev/null +++ b/02-Custom-Login/karma.conf.js @@ -0,0 +1,43 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/0.13/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', 'angular-cli'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-remap-istanbul'), + require('angular-cli/plugins/karma') + ], + files: [ + { pattern: './src/test.ts', watched: false } + ], + preprocessors: { + './src/test.ts': ['angular-cli'] + }, + mime: { + 'text/x-typescript': ['ts','tsx'] + }, + remapIstanbulReporter: { + reports: { + html: 'coverage', + lcovonly: './coverage/coverage.lcov' + } + }, + angularCli: { + config: './angular-cli.json', + environment: 'dev' + }, + reporters: config.angularCli && config.angularCli.codeCoverage + ? ['progress', 'karma-remap-istanbul'] + : ['progress'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; diff --git a/02-Custom-Login/package.json b/02-Custom-Login/package.json new file mode 100644 index 00000000..c34f1fde --- /dev/null +++ b/02-Custom-Login/package.json @@ -0,0 +1,50 @@ +{ + "name": "custom-login", + "version": "0.0.0", + "license": "MIT", + "angular-cli": {}, + "scripts": { + "ng": "ng", + "start": "ng serve", + "lint": "tslint \"src/**/*.ts\"", + "test": "ng test", + "pree2e": "webdriver-manager update --standalone false --gecko false", + "e2e": "protractor" + }, + "private": true, + "dependencies": { + "@angular/common": "^2.3.1", + "@angular/compiler": "^2.3.1", + "@angular/core": "^2.3.1", + "@angular/forms": "^2.3.1", + "@angular/http": "^2.3.1", + "@angular/platform-browser": "^2.3.1", + "@angular/platform-browser-dynamic": "^2.3.1", + "@angular/router": "^3.3.1", + "angular2-jwt": "^0.1.27", + "auth0-js": "^8.0.0-beta.3", + "bootstrap": "^3.3.7", + "core-js": "^2.4.1", + "rxjs": "^5.0.1", + "ts-helpers": "^1.1.1", + "zone.js": "^0.7.2" + }, + "devDependencies": { + "@angular/compiler-cli": "^2.3.1", + "@types/jasmine": "2.5.38", + "@types/node": "^6.0.42", + "angular-cli": "1.0.0-beta.24", + "codelyzer": "~2.0.0-beta.1", + "jasmine-core": "2.5.2", + "jasmine-spec-reporter": "2.5.0", + "karma": "1.2.0", + "karma-chrome-launcher": "^2.0.0", + "karma-cli": "^1.0.1", + "karma-jasmine": "^1.0.2", + "karma-remap-istanbul": "^0.2.1", + "protractor": "~4.0.13", + "ts-node": "1.2.1", + "tslint": "^4.0.2", + "typescript": "~2.0.3" + } +} diff --git a/02-Custom-Login/protractor.conf.js b/02-Custom-Login/protractor.conf.js new file mode 100644 index 00000000..ffded701 --- /dev/null +++ b/02-Custom-Login/protractor.conf.js @@ -0,0 +1,32 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +/*global jasmine */ +var SpecReporter = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './e2e/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + useAllAngular2AppRoots: true, + beforeLaunch: function() { + require('ts-node').register({ + project: 'e2e' + }); + }, + onPrepare: function() { + jasmine.getEnv().addReporter(new SpecReporter()); + } +}; diff --git a/02-Custom-Login/src/app/app.component.css b/02-Custom-Login/src/app/app.component.css new file mode 100644 index 00000000..e69de29b diff --git a/02-Custom-Login/src/app/app.component.html b/02-Custom-Login/src/app/app.component.html new file mode 100644 index 00000000..5ac62a8d --- /dev/null +++ b/02-Custom-Login/src/app/app.component.html @@ -0,0 +1,32 @@ + + +
+ +
diff --git a/02-Custom-Login/src/app/app.component.spec.ts b/02-Custom-Login/src/app/app.component.spec.ts new file mode 100644 index 00000000..3ad633ec --- /dev/null +++ b/02-Custom-Login/src/app/app.component.spec.ts @@ -0,0 +1,34 @@ +/* tslint:disable:no-unused-variable */ + +import { TestBed, async } from '@angular/core/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [ + AppComponent + ], + }); + TestBed.compileComponents(); + }); + + it('should create the app', async(() => { + let fixture = TestBed.createComponent(AppComponent); + let app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + })); + + it(`should have as title 'app works!'`, async(() => { + let fixture = TestBed.createComponent(AppComponent); + let app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('app works!'); + })); + + it('should render title in a h1 tag', async(() => { + let fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + let compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('app works!'); + })); +}); diff --git a/02-Custom-Login/src/app/app.component.ts b/02-Custom-Login/src/app/app.component.ts new file mode 100644 index 00000000..9c6c633d --- /dev/null +++ b/02-Custom-Login/src/app/app.component.ts @@ -0,0 +1,13 @@ +import { Component } from '@angular/core'; +import { AuthService } from './auth/auth.service'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'] +}) +export class AppComponent { + + constructor(private auth: AuthService) {} + +} diff --git a/02-Custom-Login/src/app/app.module.ts b/02-Custom-Login/src/app/app.module.ts new file mode 100644 index 00000000..c83a0891 --- /dev/null +++ b/02-Custom-Login/src/app/app.module.ts @@ -0,0 +1,30 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; +import { RouterModule } from '@angular/router'; + +import { AppComponent } from './app.component'; +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +import { ROUTES } from './app.routes'; + +import { AuthService } from './auth/auth.service'; + +@NgModule({ + declarations: [ + AppComponent, + HomeComponent, + LoginComponent + ], + imports: [ + BrowserModule, + FormsModule, + HttpModule, + RouterModule.forRoot(ROUTES) + ], + providers: [AuthService], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/02-Custom-Login/src/app/app.routes.ts b/02-Custom-Login/src/app/app.routes.ts new file mode 100644 index 00000000..d51b74de --- /dev/null +++ b/02-Custom-Login/src/app/app.routes.ts @@ -0,0 +1,9 @@ +import { Routes } from '@angular/router'; +import { HomeComponent } from './home/home.component'; +import { LoginComponent } from './login/login.component'; + +export const ROUTES: Routes = [ + { path: '', component: HomeComponent }, + { path: 'login', component: LoginComponent }, + { path: '**', redirectTo: '' } +]; \ No newline at end of file diff --git a/02-Custom-Login/src/app/auth/auth.service.spec.ts b/02-Custom-Login/src/app/auth/auth.service.spec.ts new file mode 100644 index 00000000..9cf16b3b --- /dev/null +++ b/02-Custom-Login/src/app/auth/auth.service.spec.ts @@ -0,0 +1,16 @@ +/* tslint:disable:no-unused-variable */ + +import { TestBed, async, inject } from '@angular/core/testing'; +import { AuthService } from './auth.service'; + +describe('AuthService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [AuthService] + }); + }); + + it('should ...', inject([AuthService], (service: AuthService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/02-Custom-Login/src/app/auth/auth.service.ts b/02-Custom-Login/src/app/auth/auth.service.ts new file mode 100644 index 00000000..78a60caa --- /dev/null +++ b/02-Custom-Login/src/app/auth/auth.service.ts @@ -0,0 +1,75 @@ +import { Injectable } from '@angular/core'; +import { tokenNotExpired } from 'angular2-jwt'; +import { Router } from '@angular/router'; +import { AUTH_CONFIG } from './auth0-variables'; + +// Avoid name not found warnings +declare var auth0: any; + +@Injectable() +export class AuthService { + + // Configure Auth0 + auth0 = new auth0.WebAuth({ + domain: AUTH_CONFIG.domain, + clientID: AUTH_CONFIG.clientID, + redirectUri: AUTH_CONFIG.callbackURL, + responseType: 'token id_token' + }); + + constructor(private router: Router) { + + let authResult = this.auth0.parseHash(window.location.hash); + + if (authResult && authResult.accessToken && authResult.idToken) { + window.location.hash = ''; + localStorage.setItem('access_token', authResult.accessToken); + localStorage.setItem('id_token', authResult.idToken); + this.router.navigate(['/home']); + } else if (authResult && authResult.error) { + alert(`Error: ${authResult.error}`); + } + } + + public login(email, password): void { + this.auth0.redirect.login({ + connection: 'Username-Password-Authentication', + audience: `https://${AUTH_CONFIG.domain}/userinfo`, + email, + password + }, function(err) { + if (err) alert(`Error: ${err.description}`); + }); + } + + public signup(email, password): void { + this.auth0.signup({ + connection: 'Username-Password-Authentication', + email, + password, + }, function(err) { + if (err) alert(`Error: ${err.description}`); + }); + }; + + + public loginWithGoogle(): void { + this.auth0.login({ + connection: 'google-oauth2', + }, function(err) { + if (err) alert(`Error: ${err.description}`); + }); + }; + + public isAuthenticated(): boolean { + // Check if there's an unexpired JWT + // It searches for an item in localStorage with key == 'id_token' + return tokenNotExpired(); + }; + + public logout(): void { + // Remove token from localStorage + localStorage.removeItem('access_token'); + localStorage.removeItem('id_token'); + }; +} diff --git a/02-Custom-Login/src/app/auth/auth0-variables.ts.example b/02-Custom-Login/src/app/auth/auth0-variables.ts.example new file mode 100644 index 00000000..accdb267 --- /dev/null +++ b/02-Custom-Login/src/app/auth/auth0-variables.ts.example @@ -0,0 +1,11 @@ +interface AuthConfig { + clientID: string, + domain: string, + callbackURL: string +} + +export const AUTH_CONFIG: AuthConfig = { + clientID: '{CLIENT_ID}', + domain: '{DOMAIN}', + callbackURL: 'http://localhost:4200/' +} \ No newline at end of file diff --git a/02-Custom-Login/src/app/home/home.component.css b/02-Custom-Login/src/app/home/home.component.css new file mode 100644 index 00000000..e69de29b diff --git a/02-Custom-Login/src/app/home/home.component.html b/02-Custom-Login/src/app/home/home.component.html new file mode 100644 index 00000000..513149b4 --- /dev/null +++ b/02-Custom-Login/src/app/home/home.component.html @@ -0,0 +1,6 @@ +

+ You are logged in! +

+

+ You are not logged in! Please Log In to continue. +

diff --git a/02-Custom-Login/src/app/home/home.component.spec.ts b/02-Custom-Login/src/app/home/home.component.spec.ts new file mode 100644 index 00000000..f77d7390 --- /dev/null +++ b/02-Custom-Login/src/app/home/home.component.spec.ts @@ -0,0 +1,28 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { HomeComponent } from './home.component'; + +describe('HomeComponent', () => { + let component: HomeComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ HomeComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/02-Custom-Login/src/app/home/home.component.ts b/02-Custom-Login/src/app/home/home.component.ts new file mode 100644 index 00000000..97bf3edb --- /dev/null +++ b/02-Custom-Login/src/app/home/home.component.ts @@ -0,0 +1,16 @@ +import { Component, OnInit } from '@angular/core'; +import { AuthService } from './../auth/auth.service'; + +@Component({ + selector: 'app-home', + templateUrl: './home.component.html', + styleUrls: ['./home.component.css'] +}) +export class HomeComponent implements OnInit { + + constructor(private auth: AuthService) { } + + ngOnInit() { + } + +} diff --git a/02-Custom-Login/src/app/login/login.component.css b/02-Custom-Login/src/app/login/login.component.css new file mode 100644 index 00000000..e69de29b diff --git a/02-Custom-Login/src/app/login/login.component.html b/02-Custom-Login/src/app/login/login.component.html new file mode 100644 index 00000000..e95fda13 --- /dev/null +++ b/02-Custom-Login/src/app/login/login.component.html @@ -0,0 +1,56 @@ +
+
+
+

Username/Password Authentication

+ +
+ +
+ + +
+ +
+ + +
+ + + + + +
+ +
+ +
+

Social Authentication

+ + + +
+
+
diff --git a/02-Custom-Login/src/app/login/login.component.spec.ts b/02-Custom-Login/src/app/login/login.component.spec.ts new file mode 100644 index 00000000..556444c8 --- /dev/null +++ b/02-Custom-Login/src/app/login/login.component.spec.ts @@ -0,0 +1,28 @@ +/* tslint:disable:no-unused-variable */ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { DebugElement } from '@angular/core'; + +import { LoginComponent } from './login.component'; + +describe('LoginComponent', () => { + let component: LoginComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LoginComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/02-Custom-Login/src/app/login/login.component.ts b/02-Custom-Login/src/app/login/login.component.ts new file mode 100644 index 00000000..46761da4 --- /dev/null +++ b/02-Custom-Login/src/app/login/login.component.ts @@ -0,0 +1,16 @@ +import { Component, OnInit } from '@angular/core'; +import { AuthService } from './../auth/auth.service'; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: ['./login.component.css'] +}) +export class LoginComponent implements OnInit { + + constructor(private auth: AuthService) { } + + ngOnInit() { + } + +} diff --git a/02-Custom-Login/src/assets/.gitkeep b/02-Custom-Login/src/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/02-Custom-Login/src/environments/environment.prod.ts b/02-Custom-Login/src/environments/environment.prod.ts new file mode 100644 index 00000000..3612073b --- /dev/null +++ b/02-Custom-Login/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; diff --git a/02-Custom-Login/src/environments/environment.ts b/02-Custom-Login/src/environments/environment.ts new file mode 100644 index 00000000..00313f16 --- /dev/null +++ b/02-Custom-Login/src/environments/environment.ts @@ -0,0 +1,8 @@ +// The file contents for the current environment will overwrite these during build. +// The build system defaults to the dev environment which uses `environment.ts`, but if you do +// `ng build --env=prod` then `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `angular-cli.json`. + +export const environment = { + production: false +}; diff --git a/02-Custom-Login/src/favicon.ico b/02-Custom-Login/src/favicon.ico new file mode 100644 index 00000000..8081c7ce Binary files /dev/null and b/02-Custom-Login/src/favicon.ico differ diff --git a/02-Custom-Login/src/index.html b/02-Custom-Login/src/index.html new file mode 100644 index 00000000..00338595 --- /dev/null +++ b/02-Custom-Login/src/index.html @@ -0,0 +1,14 @@ + + + + + CustomLogin + + + + + + + Loading... + + diff --git a/02-Custom-Login/src/main.ts b/02-Custom-Login/src/main.ts new file mode 100644 index 00000000..ac78a713 --- /dev/null +++ b/02-Custom-Login/src/main.ts @@ -0,0 +1,12 @@ +import './polyfills.ts'; + +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { enableProdMode } from '@angular/core'; +import { environment } from './environments/environment'; +import { AppModule } from './app/app.module'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/02-Custom-Login/src/polyfills.ts b/02-Custom-Login/src/polyfills.ts new file mode 100644 index 00000000..3b4c55b0 --- /dev/null +++ b/02-Custom-Login/src/polyfills.ts @@ -0,0 +1,19 @@ +// This file includes polyfills needed by Angular 2 and is loaded before +// the app. You can add your own extra polyfills to this file. +import 'core-js/es6/symbol'; +import 'core-js/es6/object'; +import 'core-js/es6/function'; +import 'core-js/es6/parse-int'; +import 'core-js/es6/parse-float'; +import 'core-js/es6/number'; +import 'core-js/es6/math'; +import 'core-js/es6/string'; +import 'core-js/es6/date'; +import 'core-js/es6/array'; +import 'core-js/es6/regexp'; +import 'core-js/es6/map'; +import 'core-js/es6/set'; +import 'core-js/es6/reflect'; + +import 'core-js/es7/reflect'; +import 'zone.js/dist/zone'; diff --git a/02-Custom-Login/src/styles.css b/02-Custom-Login/src/styles.css new file mode 100644 index 00000000..6658885d --- /dev/null +++ b/02-Custom-Login/src/styles.css @@ -0,0 +1,4 @@ +/* You can add global styles to this file, and also import other style files */ +.btn-margin { + margin-top: 7px +} \ No newline at end of file diff --git a/02-Custom-Login/src/test.ts b/02-Custom-Login/src/test.ts new file mode 100644 index 00000000..be44dc58 --- /dev/null +++ b/02-Custom-Login/src/test.ts @@ -0,0 +1,32 @@ +import './polyfills.ts'; + +import 'zone.js/dist/long-stack-trace-zone'; +import 'zone.js/dist/proxy.js'; +import 'zone.js/dist/sync-test'; +import 'zone.js/dist/jasmine-patch'; +import 'zone.js/dist/async-test'; +import 'zone.js/dist/fake-async-test'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +// Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. +declare var __karma__: any; +declare var require: any; + +// Prevent Karma from running prematurely. +__karma__.loaded = function () {}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +let context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); +// Finally, start Karma to run the tests. +__karma__.start(); diff --git a/02-Custom-Login/src/tsconfig.json b/02-Custom-Login/src/tsconfig.json new file mode 100644 index 00000000..1cf713a3 --- /dev/null +++ b/02-Custom-Login/src/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "baseUrl": "", + "declaration": false, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "lib": ["es6", "dom"], + "mapRoot": "./", + "module": "es6", + "moduleResolution": "node", + "outDir": "../dist/out-tsc", + "sourceMap": true, + "target": "es5", + "typeRoots": [ + "../node_modules/@types" + ] + } +} diff --git a/02-Custom-Login/tslint.json b/02-Custom-Login/tslint.json new file mode 100644 index 00000000..640d02c9 --- /dev/null +++ b/02-Custom-Login/tslint.json @@ -0,0 +1,107 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "eofline": true, + "forin": true, + "indent": [ + true, + "spaces" + ], + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + "static-before-instance", + "variables-before-functions" + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-variable": true, + "no-empty": false, + "no-eval": true, + "no-inferrable-types": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + + "directive-selector": [true, "attribute", "app", "camelCase"], + "component-selector": [true, "element", "app", "kebab-case"], + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true, + "no-access-missing-member": true, + "templates-use-public": true, + "invoke-injectable": true + } +} diff --git a/LICENCE b/LICENCE new file mode 100644 index 00000000..8dfefda6 --- /dev/null +++ b/LICENCE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Auth0 Samples + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..813365a7 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Auth0 Angular Samples + +These samples demonstrate how to add authentication to an Angular application with Auth0. Each folder contains a distinct application so that various Auth0 features can be viewed in isolation. + +## What is Auth0? + +Auth0 helps you to: + +* 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**. +* Add authentication through more traditional **[username/password databases](https://docs.auth0.com/mysql-connection-tutorial)**. +* Add support for **[linking different user accounts](https://docs.auth0.com/link-accounts)** with the same user. +* Support for generating signed [Json Web Tokens](https://docs.auth0.com/jwt) to call your APIs and **flow the user identity** securely. +* Analytics of how, when and where users are logging in. +* Pull data from other sources and add it to the user profile, through [JavaScript rules](https://docs.auth0.com/rules). + +## Create a free Auth0 account + +1. Go to [Auth0](https://auth0.com/signup) and click Sign Up. +2. Use Google, GitHub or Microsoft Account to login. + +## Issue Reporting + +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. + +## Author + +[Auth0](auth0.com) + +## License + +This project is licensed under the MIT license. See the [LICENSE](LICENSE.txt) file for more info. \ No newline at end of file