<!DOCTYPE html>
<html>
<head>
<title>App</title>
<base href=".">
<script src="https://code.angularjs.org/tools/traceur-runtime.js"></script>
<script src="https://code.angularjs.org/tools/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="config.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.53/angular2.js"></script>
<script src="https://code.angularjs.org/2.0.0-alpha.53/router.dev.js"></script>
<script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-alpha.14/dist/global/Rx.js"></script>
<script>
System.import('./bootstrap.ts').then(null, console.error.bind(console));
</script>
</head>
<body>
<app></app>
</body>
</html>
// app.ts
import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES, Router} from 'angular2/router';
import {Home} from './home.ts';
import {Login} from './login.ts';
@Component({
selector: 'app',
directives: [ROUTER_DIRECTIVES]
template: `
<h1>Hello world</h1>
<router-outlet></router-outlet>
`
})
@RouteConfig([
{ path: '/', redirectTo: ['Login'] },
{ path: '/home', as: 'Home', component: Home },
{ path: '/login', as: 'Login', component: Login }
])
export class App {
constructor() {}
}
System.config({
//use typescript for compilation
transpiler: 'typescript',
//typescript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
}
});
//main entry point
import {bootstrap} from 'angular2/platform/browser';
import {provide} from 'angular2/core';
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {App} from './app.ts';
import {Authentication} from './authentication.ts';
bootstrap(App, [
ROUTER_PROVIDERS,
provide(LocationStrategy, {useClass: HashLocationStrategy}),
Authentication
]);
// login.ts
import {Component} from 'angular2/core';
import {FORM_DIRECTIVES, FormBuilder, Validators, ControlGroup, NgIf} from 'angular2/common';
import {Router} from 'angular2/router';
import {Authentication} from './authentication.ts';
@Component({
selector: 'login',
directives: [ FORM_DIRECTIVES, NgIf ],
template: `
<form [ngFormModel]="form" (submit)="$event.preventDefault(); onSubmit(form.value)">
<div *ngIf="error">Check your password</div>
<div>
<label for="username">Username</label>
<input type="text" ngControl="username">
</div>
<div>
<label for="password">Password</label>
<input type="password" ngControl="password">
</div>
<div class="form-group">
<button type="submit" [disabled]="!form.valid">Login</button>
</div>
</form>
`
})
export class Login {
form: ControlGroup;
error: boolean = false;
constructor(fb: FormBuilder, public auth: Authentication, public router: Router) {
this.form = fb.group({
username: ['', Validators.required],
password: ['', Validators.required]
});
}
onSubmit(value: any) {
this.auth.login(value.username, value.password)
.subscribe(
(token: any) => { this.router.navigate(['../Home']); },
() => { this.error = true; }
);
}
}
// home.ts
import {Component} from 'angular2/core';
import {Router, CanActivate} from 'angular2/router';
import {Authentication} from './authentication.ts';
import {isLoggedin} from './is-loggedin.ts';
@Component({
selector: 'home',
directives: [],
template: `
<h2>I am logged in</h2>
<a href="#" (click)="onLogout()">Logout</a>
`
})
@CanActivate(() => isLoggedin())
export class Home {
constructor(public auth: Authentication, public router: Router) {}
onLogout() {
this.auth.logout()
.subscribe(
() => this.router.navigate(['../Login']),
);
}
}
// authentication.ts
import {Injectable} from 'angular2/core';
@Injectable()
export class Authentication {
token: string;
constructor() {
this.token = localStorage.getItem('token');
}
login(username: String, password: String) {
/*
* If we had a login api, we would have done something like this
return this.http.post('/auth/login', JSON.stringify({
username: username,
password: password
}), {
headers: new Headers({
'Content-Type': 'application/json'
})
})
.map((res : any) => {
let data = res.json();
this.token = data.token;
localStorage.setItem('token', this.token);
});
for the purpose of this cookbook, we will juste simulate that
*/
if (username === 'test' && password === 'test') {
this.token = 'token';
localStorage.setItem('token', this.token);
return Rx.Observable.of('token');
}
return Rx.Observable.throw('authentication failure');
}
logout() {
/*
* If we had a login api, we would have done something like this
return this.http.get(this.config.serverUrl + '/auth/logout', {
headers: new Headers({
'x-security-token': this.token
})
})
.map((res : any) => {
this.token = undefined;
localStorage.removeItem('token');
});
*/
this.token = undefined;
localStorage.removeItem('token');
return Rx.Observable.of(true);
}
}
export function isLoggedin() {
return !!localStorage.getItem('token');
}