From 60df6caf4a9c9eedc895c66a8b8b2ab6806bd397 Mon Sep 17 00:00:00 2001 From: Braun Patrik Date: Sun, 13 Mar 2016 11:28:29 +0100 Subject: [PATCH] implementing client side login --- backend/NetworkManager.ts | 27 ++++++++ backend/server.ts | 2 + common/common-classes.d.ts | 10 +++ common/event/Event.ts | 32 +++++++++ common/event/Event2Args.ts | 23 +++++++ common/event/EventLimit.ts | 72 ++++++++++++++++++++ common/{tsconfig.json => tsconfig.json.back} | 0 frontend/app/app.component.ts | 22 +++++- frontend/app/gallery/gallery.component.html | 1 + frontend/app/gallery/gallery.component.ts | 11 +++ frontend/app/login/login.component.html | 6 +- frontend/app/login/login.component.ts | 4 ++ frontend/app/login/login.service.ts | 18 +---- frontend/app/model/authentication.service.ts | 28 ++++++++ frontend/app/model/network.service.ts | 27 ++++++-- 15 files changed, 259 insertions(+), 24 deletions(-) create mode 100644 backend/NetworkManager.ts create mode 100644 common/common-classes.d.ts create mode 100644 common/event/Event.ts create mode 100644 common/event/Event2Args.ts create mode 100644 common/event/EventLimit.ts rename common/{tsconfig.json => tsconfig.json.back} (100%) create mode 100644 frontend/app/gallery/gallery.component.html create mode 100644 frontend/app/gallery/gallery.component.ts create mode 100644 frontend/app/model/authentication.service.ts diff --git a/backend/NetworkManager.ts b/backend/NetworkManager.ts new file mode 100644 index 00000000..b335328f --- /dev/null +++ b/backend/NetworkManager.ts @@ -0,0 +1,27 @@ +/// + + +import * as _socketIo from 'socket.io'; +import {MessageTypes} from "../common/MessageTypes"; +import {User} from "../common/entities/User"; +import {LoginCredential} from "../common/entities/LoginCredential"; + +import * as _debug from 'debug'; +var debug = _debug("PiGallery2:NetworkManager"); + +export class NetworkManager{ + private socketIo:SocketIO.Server; + + constructor(http){ + + this.socketIo = _socketIo(http); + + this.socketIo.on('connection', function(socket:SocketIO.Server){ + debug("Client Connected"); + socket.on(MessageTypes.Client.Login.Authenticate,(credential:LoginCredential) =>{ + debug("Message: " + MessageTypes.Client.Login.Authenticate); + socket.emit(MessageTypes.Server.Login.Authenticated,new User("Dummy user","dummy@mail.com","password")); + }); + }); + } +} \ No newline at end of file diff --git a/backend/server.ts b/backend/server.ts index cde74f13..a0a239ee 100644 --- a/backend/server.ts +++ b/backend/server.ts @@ -4,6 +4,7 @@ import * as _express from 'express'; import * as _debug from 'debug'; import * as _http from 'http'; import * as path from 'path'; +import {NetworkManager} from "./NetworkManager"; export class Server { @@ -46,6 +47,7 @@ export class Server { this.server.on('error', this.onError); this.server.on('listening', this.onListening); + new NetworkManager(this.server); } diff --git a/common/common-classes.d.ts b/common/common-classes.d.ts new file mode 100644 index 00000000..d05bde7e --- /dev/null +++ b/common/common-classes.d.ts @@ -0,0 +1,10 @@ +/// +/// +/// + +/// + +/// +/// +/// +/// diff --git a/common/event/Event.ts b/common/event/Event.ts new file mode 100644 index 00000000..566fb298 --- /dev/null +++ b/common/event/Event.ts @@ -0,0 +1,32 @@ +/// + +function isFunction(functionToCheck) { + var getType = {}; + return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; +} + +export class Event { + private handlers: { (data?: T): void; }[] = []; + + public on(handler: { (data?: T): void }) { + if(!isFunction(handler)){ + throw new Error("Handler is not a function"); + } + this.handlers.push(handler); + } + + public off(handler: { (data?: T): void }) { + this.handlers = this.handlers.filter(h => h !== handler); + } + + public allOff() { + this.handlers = []; + } + + public trigger(data?: T) { + if (this.handlers) { + this.handlers.slice(0).forEach(h => h(data)); + } + } +} + diff --git a/common/event/Event2Args.ts b/common/event/Event2Args.ts new file mode 100644 index 00000000..609c07d4 --- /dev/null +++ b/common/event/Event2Args.ts @@ -0,0 +1,23 @@ +/// + +export class Event2Args { + private handlers: { (data?: T,data2?: M): void; }[] = []; + + public on(handler: { (data?: T,data2?: M): void }) { + this.handlers.push(handler); + } + + public off(handler: { (data?: T,data2?: M): void }) { + this.handlers = this.handlers.filter(h => h !== handler); + } + + public allOff() { + this.handlers = []; + } + + public trigger(data?: T,data2?: M) { + if (this.handlers) { + this.handlers.slice(0).forEach(h => h(data,data2)); + } + } +} diff --git a/common/event/EventLimit.ts b/common/event/EventLimit.ts new file mode 100644 index 00000000..460ee10c --- /dev/null +++ b/common/event/EventLimit.ts @@ -0,0 +1,72 @@ +/// + +export class EventLimit { + + private lastTriggerValue:T = null; + + private handlers:Array> = []; + + public on(limit:T, handler:{ (data?:T): void }) { + this.handlers.push(new EventLimitHandler(limit, handler)); + if (this.lastTriggerValue != null) { + this.trigger(this.lastTriggerValue); + } + } + + public onSingle(limit:T, handler:{ (data?:T): void }) { + this.handlers.push(new SingleFireEventLimitHandler(limit, handler)); + if (this.lastTriggerValue != null) { + this.trigger(this.lastTriggerValue); + } + } + + public off(limit:T, handler:{ (data?:T): void }) { + this.handlers = this.handlers.filter(h => h.handler !== handler && h.limit !== limit); + } + + public allOff() { + this.handlers = []; + } + + public trigger = (data?:T) => { + if (this.handlers) { + this.handlers.slice(0).forEach(h => { + if (h.limit <= data && (h.lastTriggerValue < h.limit || h.lastTriggerValue == null)) { + h.fire(data); + } + h.lastTriggerValue = data; + }); + this.handlers = this.handlers.filter(h => h.isValid()); + } + this.lastTriggerValue = data; + }; +} + +class EventLimitHandler { + public lastTriggerValue:T = null; + constructor(public limit:T, public handler:{ (data?:T): void }) { + } + public fire(data?: T){ + this.handler(data); + } + public isValid():boolean{ + return true; + } +} +class SingleFireEventLimitHandler extends EventLimitHandler{ + public fired = false; + constructor(public limit:T, public handler:{ (data?:T): void }) { + super(limit,handler); + } + + public fire(data?: T){ + if(this.fired == false) { + this.handler(data); + } + this.fired = true + } + + public isValid():boolean{ + return this.fired === false; + } +} diff --git a/common/tsconfig.json b/common/tsconfig.json.back similarity index 100% rename from common/tsconfig.json rename to common/tsconfig.json.back diff --git a/frontend/app/app.component.ts b/frontend/app/app.component.ts index e8d12f61..345d7a2e 100644 --- a/frontend/app/app.component.ts +++ b/frontend/app/app.component.ts @@ -5,6 +5,11 @@ import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/route import {LoginComponent} from "./login/login.component"; import {NetworkService} from "./model/network.service"; import {LoginService} from "./login/login.service"; +import {AuthenticationService} from "./model/authentication.service"; +import {GalleryComponent} from "./gallery/gallery.component"; +import {OnInit} from "angular2/core"; +import {User} from "../../common/entities/User"; +import {Router} from "angular2/router"; @@ -16,6 +21,7 @@ import {LoginService} from "./login/login.service"; providers: [ ROUTER_PROVIDERS, NetworkService, + AuthenticationService, LoginService ] }) @@ -25,10 +31,22 @@ import {LoginService} from "./login/login.service"; name: 'Login', component: LoginComponent, useAsDefault: true + }, + { + path: '/gallery', + name: 'Gallery', + component: GalleryComponent } ]) -export class AppComponent { - constructor(){ +export class AppComponent implements OnInit{ + constructor(private _router: Router ,private _authenticationService: AuthenticationService){ + } + + ngOnInit() { + this._authenticationService.OnAuthenticated.on((user:User) => + { + this._router.navigate(["Gallery"]); + }); } } \ No newline at end of file diff --git a/frontend/app/gallery/gallery.component.html b/frontend/app/gallery/gallery.component.html new file mode 100644 index 00000000..dc2cd0a3 --- /dev/null +++ b/frontend/app/gallery/gallery.component.html @@ -0,0 +1 @@ +

Gallery

\ No newline at end of file diff --git a/frontend/app/gallery/gallery.component.ts b/frontend/app/gallery/gallery.component.ts new file mode 100644 index 00000000..f14597ba --- /dev/null +++ b/frontend/app/gallery/gallery.component.ts @@ -0,0 +1,11 @@ +/// + +import { Component } from 'angular2/core'; + +@Component({ + selector: 'gallery', + templateUrl: 'app/gallery/gallery.component.html' +}) +export class GalleryComponent{ +} + diff --git a/frontend/app/login/login.component.html b/frontend/app/login/login.component.html index 1a31f1d9..71bf3ea7 100644 --- a/frontend/app/login/login.component.html +++ b/frontend/app/login/login.component.html @@ -1,13 +1,13 @@
- +
- +
-
\ No newline at end of file diff --git a/frontend/app/login/login.component.ts b/frontend/app/login/login.component.ts index 312cd6e8..b61ecc90 100644 --- a/frontend/app/login/login.component.ts +++ b/frontend/app/login/login.component.ts @@ -14,5 +14,9 @@ export class LoginComponent{ constructor(private _loginService: LoginService) { this.user = new LoginCredential(); } + + onLogin(){ + this._loginService.login(this.user); + } } diff --git a/frontend/app/login/login.service.ts b/frontend/app/login/login.service.ts index 176ab78e..25d571ef 100644 --- a/frontend/app/login/login.service.ts +++ b/frontend/app/login/login.service.ts @@ -4,30 +4,18 @@ import {Injectable} from 'angular2/core'; import {NetworkService} from "../model/network.service"; import {OnInit} from "angular2/core"; import {MessageTypes} from "../../../common/MessageTypes"; -import {Utils} from "../../../common/Utils"; import {LoginCredential} from "../../../common/entities/LoginCredential"; import {User} from "../../../common/entities/User"; import {Message} from "../../../common/entities/Message"; @Injectable() -export class LoginService implements OnInit{ +export class LoginService { - private _authenticating:LoginCredential; constructor(private _networkService: NetworkService){ - } - ngOnInit() { - this._networkService.socketIO.on(MessageTypes.Server.Login.Authenticated, (message:Message) => { - if(message.result.name == this._authenticating.username || message.result.email == this._authenticating.username){ - - } - }); - } - - public login(user:LoginCredential):Promise { - this._networkService.socketIO.emit(MessageTypes.Client.Login.Authenticate, user); - this._authenticating = Utils.clone(user); + public login(credential:LoginCredential) { + this._networkService.login(credential); } diff --git a/frontend/app/model/authentication.service.ts b/frontend/app/model/authentication.service.ts new file mode 100644 index 00000000..342dee0d --- /dev/null +++ b/frontend/app/model/authentication.service.ts @@ -0,0 +1,28 @@ +/// + +import * as io from 'socket.io-client'; +import {Injectable} from 'angular2/core'; +import {OnInit} from "angular2/core"; +import {NetworkService} from "./network.service"; +import {User} from "../../../common/entities/User"; +import {Event} from "../../../common/event/Event"; + +@Injectable() +export class AuthenticationService{ + + private _user:User; + public OnAuthenticated:Event; + + constructor(private _networkService: NetworkService){ + this.OnAuthenticated = new Event(); + this._networkService.OnAuthenticated.on(this.onAuthenticated); + } + + + private onAuthenticated = (user:User) => { + this._user=user; + this.OnAuthenticated.trigger(this._user); + } + + +} diff --git a/frontend/app/model/network.service.ts b/frontend/app/model/network.service.ts index e78e907c..a2e7a417 100644 --- a/frontend/app/model/network.service.ts +++ b/frontend/app/model/network.service.ts @@ -3,18 +3,37 @@ import * as io from 'socket.io-client'; import {Injectable} from 'angular2/core'; import {OnInit} from "angular2/core"; +import {LoginCredential} from "../../../common/entities/LoginCredential"; +import {MessageTypes} from "../../../common/MessageTypes"; +import {Event} from "../../../common/event/Event"; +import {User} from "../../../common/entities/User"; +import {Message} from "../../../common/entities/Message"; @Injectable() -export class NetworkService implements OnInit{ +export class NetworkService{ private _socketIO: SocketIOClient.Socket; - ngOnInit() { + public OnAuthenticated:Event; + + constructor(){ this._socketIO = io(); + this.OnAuthenticated = new Event(); + this._subscribeMessages(); } - get socketIO():SocketIOClient.Socket { - return this._socketIO; + public login(credential:LoginCredential){ + this._socketIO.emit(MessageTypes.Client.Login.Authenticate,credential); + } + + private _subscribeMessages(){ + this._socketIO.on(MessageTypes.Server.Login.Authenticated, (message:Message) =>{ + if(message.error){ + //TODO: Handle error + }else{ + this.OnAuthenticated.trigger(message.result); + } + }); } }