Config and login
Change-Id: I81ffb9b8097620cb7870beaf1b1b315945eebec0
diff --git a/src/app/components/login/login.component.ts b/src/app/components/login/login.component.ts
new file mode 100644
index 0000000..413290c
--- /dev/null
+++ b/src/app/components/login/login.component.ts
@@ -0,0 +1,38 @@
+/// <reference path="../../../../typings/index.d.ts"/>
+import {Component} from '@angular/core';
+import {Router} from '@angular/router';
+import {IAuthRequest, IAuthResponse} from '../../interfaces/auth.interface';
+import {StyleConfig} from '../../config/style.config';
+import {AuthService} from '../../services/rest/auth.service';
+
+export class Auth {
+ constructor(
+ public username,
+ public password
+ ){
+ }
+}
+
+@Component({
+ selector: 'xos-login',
+ template: require('./login.html'),
+ providers: [AuthService],
+})
+export class LoginComponent {
+ public auth:IAuthRequest;
+ public brandName;
+ constructor(private AuthService: AuthService, private router:Router) {
+ this.auth = new Auth('', '');
+ this.brandName = StyleConfig.projectName;
+ }
+
+ onSubmit(auth:IAuthRequest){
+ this.AuthService.login(auth)
+ .subscribe(
+ (user:IAuthResponse) => {
+ this.router.navigate(['/']);
+ }
+ )
+ }
+}
+
diff --git a/src/app/components/login/login.html b/src/app/components/login/login.html
new file mode 100644
index 0000000..0f8362c
--- /dev/null
+++ b/src/app/components/login/login.html
@@ -0,0 +1,10 @@
+<div class="login-container">
+ <div class="login-form">
+ <h2>Login to {{brandName}}</h2>
+ <form (ngSubmit)="onSubmit(loginForm.value)" #loginForm="ngForm">
+ <input type="email" [(ngModel)]="auth.username" name="username" required/>
+ <input type="password" [(ngModel)]="auth.password" name="password" required/>
+ <button type="submit" [disabled]="!loginForm.form.valid">Login</button>
+ </form>
+ </div>
+</div>
diff --git a/src/app/config/.gitignore b/src/app/config/.gitignore
new file mode 100644
index 0000000..c96a04f
--- /dev/null
+++ b/src/app/config/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/src/app/directives/protected.directive.ts b/src/app/directives/protected.directive.ts
new file mode 100644
index 0000000..9ebe89e
--- /dev/null
+++ b/src/app/directives/protected.directive.ts
@@ -0,0 +1,34 @@
+/**
+ * Created by teone on 12/5/16.
+ */
+import {Directive, OnDestroy} from '@angular/core';
+import {AuthService} from '../services/rest/auth.service';
+import {Router} from '@angular/router';
+
+@Directive({
+ selector: '[xos-protected]',
+ providers: [AuthService]
+})
+export class ProtectedDirective implements OnDestroy {
+ private sub:any = null;
+
+ constructor(private authService:AuthService, private router:Router) {
+ console.log('protected directive');
+ if (!authService.isAuthenticated()) {
+ console.log('redirect');
+ this.router.navigate(['/login']);
+ }
+
+ // this.sub = this.authService.subscribe((val) => {
+ // if (!val.authenticated) {
+ // this.router.navigate(['LoggedoutPage']); // tells them they've been logged out (somehow)
+ // }
+ // });
+ }
+
+ ngOnDestroy() {
+ // if (this.sub != null) {
+ // this.sub.unsubscribe();
+ // }
+ }
+}
diff --git a/src/app/hello.html b/src/app/hello.html
index 2ec8382..089199c 100644
--- a/src/app/hello.html
+++ b/src/app/hello.html
@@ -1 +1,5 @@
-<h1>{{ hello }}</h1>
\ No newline at end of file
+<div xos-protected></div>
+
+<h1>{{ hello }}</h1>
+
+<pre>{{ endpoints | json }}</pre>
diff --git a/src/app/hello.spec.ts b/src/app/hello.spec.ts
index 7e3b2cc..91b3f1a 100644
--- a/src/app/hello.spec.ts
+++ b/src/app/hello.spec.ts
@@ -2,12 +2,26 @@
import {HelloComponent} from './hello';
import {TestBed, async} from '@angular/core/testing';
+import {StyleConfig} from './config/style.config';
+import { Http, BaseRequestOptions } from '@angular/http';
+import { MockBackend } from '@angular/http/testing';
describe('hello component', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
HelloComponent
+ ],
+ providers: [
+ {
+ provide: Http,
+ useFactory: (mockBackend, options) => {
+ return new Http(mockBackend, options);
+ },
+ deps: [MockBackend, BaseRequestOptions]
+ },
+ MockBackend,
+ BaseRequestOptions
]
});
TestBed.compileComponents();
@@ -17,6 +31,6 @@
const fixture = TestBed.createComponent(HelloComponent);
fixture.detectChanges();
const hello = fixture.nativeElement;
- expect(hello.querySelector('h1').textContent).toBe('Hello World!');
+ expect(hello.querySelector('h1').textContent).toBe(`Hello ${StyleConfig.projectName}!`);
});
});
diff --git a/src/app/hello.ts b/src/app/hello.ts
index 9f42916..b67e7f6 100644
--- a/src/app/hello.ts
+++ b/src/app/hello.ts
@@ -1,13 +1,33 @@
-import {Component} from '@angular/core';
+/// <reference path="../../typings/index.d.ts"/>
+import {Component, OnInit} from '@angular/core';
+import {NgFor} from '@angular/common';
+import {StyleConfig} from './config/style.config';
+import {CoreService} from './services/rest/core.service';
@Component({
- selector: 'fountain-app',
- template: require('./hello.html')
+ selector: 'xos-app',
+ template: require('./hello.html'),
+ providers: [CoreService],
})
export class HelloComponent {
- public hello: string;
- constructor() {
- this.hello = 'Hello World!';
+ // declare class properties
+ public hello: string;
+ public endpoints: any[];
+
+ constructor(private coreService: CoreService) {
+ this.hello = `Hello ${StyleConfig.projectName}!`;
+ this.endpoints = [];
+ }
+
+ ngOnInit() {
+ console.log('on init');
+ this.coreService.getCoreEndpoints()
+ .subscribe(
+ endpoints => {
+ this.endpoints = endpoints
+ },
+ err => console.log
+ )
}
}
diff --git a/src/app/index.ts b/src/app/index.ts
index 5f02fe6..4e93275 100644
--- a/src/app/index.ts
+++ b/src/app/index.ts
@@ -1,18 +1,29 @@
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
+import {HttpModule} from '@angular/http';
+import {FormsModule} from '@angular/forms';
+import {CookieService} from 'angular2-cookie/services/cookies.service';
+
import {routing, RootComponent} from './routes';
import {HelloComponent} from './hello';
+import {LoginComponent} from './components/login/login.component';
+import {ProtectedDirective} from './directives/protected.directive';
@NgModule({
imports: [
BrowserModule,
- routing
+ FormsModule,
+ routing,
+ HttpModule
],
declarations: [
RootComponent,
- HelloComponent
+ HelloComponent,
+ LoginComponent,
+ ProtectedDirective
],
+ providers: [CookieService],
bootstrap: [RootComponent]
})
export class AppModule {}
diff --git a/src/app/interfaces/auth.interface.ts b/src/app/interfaces/auth.interface.ts
new file mode 100644
index 0000000..1742fb7
--- /dev/null
+++ b/src/app/interfaces/auth.interface.ts
@@ -0,0 +1,10 @@
+export interface IAuthRequest {
+ username: string;
+ password: string;
+}
+
+export interface IAuthResponse {
+ xossessionid: string;
+ xoscsrftoken: string;
+ user: string;
+}
diff --git a/src/app/routes.ts b/src/app/routes.ts
index 9a197e7..4c27ed1 100644
--- a/src/app/routes.ts
+++ b/src/app/routes.ts
@@ -3,10 +3,13 @@
import {Component} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {HelloComponent} from './hello';
+import {LoginComponent} from "./components/login/login.component";
@Component({
- selector: 'fountain-root',
- template: '<router-outlet></router-outlet>'
+ selector: 'xos-root',
+ template: `
+ <router-outlet></router-outlet>
+ `
})
export class RootComponent {}
@@ -14,6 +17,10 @@
{
path: '',
component: HelloComponent
+ },
+ {
+ path: 'login',
+ component: LoginComponent
}
];
diff --git a/src/app/services/rest/auth.service.ts b/src/app/services/rest/auth.service.ts
new file mode 100644
index 0000000..7c73c28
--- /dev/null
+++ b/src/app/services/rest/auth.service.ts
@@ -0,0 +1,48 @@
+/// <reference path="../../../../typings/index.d.ts"/>
+
+// Imports
+import {AppConfig} from '../../config/app.config';
+import {Injectable} from '@angular/core';
+import {Http, Response} from '@angular/http';
+import {Observable} from 'rxjs/Rx';
+import {IAuthRequest, IAuthResponse} from '../../interfaces/auth.interface';
+import {CookieService} from 'angular2-cookie/core';
+
+// Import RxJs required methods
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/catch';
+
+@Injectable()
+export class AuthService {
+ private xosToken:string;
+ private xosSessionId:string;
+ // Resolve HTTP using the constructor
+ constructor (private http: Http, private cookieService:CookieService) {
+ }
+
+ // check if the user is authenticated
+ isAuthenticated(){
+ this.xosToken = this.cookieService.get('xoscsrftoken');
+ this.xosSessionId = this.cookieService.get('xossessionid');
+ return this.xosToken;
+ }
+
+ // save cookies
+ storeAuth(auth:IAuthResponse){
+ this.cookieService.put('xoscsrftoken', auth.xoscsrftoken);
+ this.cookieService.put('xossessionid', auth.xossessionid);
+ }
+
+ // Log the user in
+ login(auth: IAuthRequest) : Observable<IAuthResponse> {
+ return this.http.post(`${AppConfig.apiEndpoint}/utility/login/`, auth)
+ .map((res:Response) => res.json())
+ .map((auth:IAuthResponse) => {
+ this.storeAuth(auth);
+ auth.user = JSON.parse(auth.user);
+ return auth;
+ })
+ .catch((error:any) => Observable.throw(error.json().error || 'Server error'));
+ }
+}
+
diff --git a/src/app/services/rest/core.service.ts b/src/app/services/rest/core.service.ts
new file mode 100644
index 0000000..04097a6
--- /dev/null
+++ b/src/app/services/rest/core.service.ts
@@ -0,0 +1,31 @@
+/// <reference path="../../../../typings/index.d.ts"/>
+
+// Imports
+import {AppConfig} from '../../config/app.config';
+import { Injectable } from '@angular/core';
+import { Http, Response, Headers, RequestOptions } from '@angular/http';
+import {Observable} from 'rxjs/Rx';
+
+// Import RxJs required methods
+import 'rxjs/add/operator/map';
+import 'rxjs/add/operator/catch';
+
+@Injectable()
+export class CoreService {
+ // Resolve HTTP using the constructor
+ constructor (private http: Http) {}
+ // private instance variable to hold base url
+ private baseUrl = AppConfig.apiEndpoint;
+
+ // Fetch all existing comments
+ getCoreEndpoints() : Observable<any[]> {
+
+ // ...using get request
+ return this.http.get(`${this.baseUrl}/core/`)
+ // ...and calling .json() on the response to return data
+ .map((res:Response) => res.json())
+ //...errors if any
+ .catch((error:any) => Observable.throw(error.json().error || 'Server error'));
+
+ }
+}
diff --git a/src/images/cord-favicon.png b/src/images/cord-favicon.png
new file mode 100644
index 0000000..758902e
--- /dev/null
+++ b/src/images/cord-favicon.png
Binary files differ
diff --git a/src/images/opencloud-favicon.png b/src/images/opencloud-favicon.png
new file mode 100644
index 0000000..d49afe0
--- /dev/null
+++ b/src/images/opencloud-favicon.png
Binary files differ
diff --git a/src/index.html b/src/index.html
index 2d0e805..6d6e8c1 100644
--- a/src/index.html
+++ b/src/index.html
@@ -3,13 +3,13 @@
<head>
<base href="/">
<meta charset="utf-8">
- <title>FountainJS</title>
+ <title>XOS</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
- <link rel="icon" type="image/png" href="http://fountainjs.io/assets/imgs/fountain.png" />
+ <link rel="icon" type="image/png" href="images/cord-favicon.png" />
</head>
<body>
- <fountain-root>Loading...</fountain-root>
+ <xos-root>Loading XOS...</xos-root>
</body>
</html>
diff --git a/src/index.ts b/src/index.ts
index f7b360a..4cf1437 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -13,6 +13,7 @@
import {AppModule} from './app';
declare var process: any;
+console.log(process.env.NODE_ENV);
if (process.env.NODE_ENV === 'production') {
enableProdMode();
} else {