mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-25 02:04:15 +02:00
implementing client side login
This commit is contained in:
parent
df717f55e1
commit
60df6caf4a
27
backend/NetworkManager.ts
Normal file
27
backend/NetworkManager.ts
Normal file
@ -0,0 +1,27 @@
|
||||
///<reference path="../typings/tsd.d.ts"/>
|
||||
|
||||
|
||||
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"));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
10
common/common-classes.d.ts
vendored
Normal file
10
common/common-classes.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
///<reference path="event/Event.ts"/>
|
||||
///<reference path="event/Event2Args.ts"/>
|
||||
///<reference path="event/EventLimit.ts"/>
|
||||
|
||||
///<reference path="MessageTypes.ts"/>
|
||||
|
||||
///<reference path="entities/Error.ts"/>
|
||||
///<reference path="entities/LoginCredential.ts"/>
|
||||
///<reference path="entities/User.ts"/>
|
||||
///<reference path="entities/Message.ts"/>
|
32
common/event/Event.ts
Normal file
32
common/event/Event.ts
Normal file
@ -0,0 +1,32 @@
|
||||
///<reference path="../../typings/tsd.d.ts"/>
|
||||
|
||||
function isFunction(functionToCheck) {
|
||||
var getType = {};
|
||||
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
|
||||
}
|
||||
|
||||
export class Event<T> {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
23
common/event/Event2Args.ts
Normal file
23
common/event/Event2Args.ts
Normal file
@ -0,0 +1,23 @@
|
||||
///<reference path="../../typings/tsd.d.ts"/>
|
||||
|
||||
export class Event2Args<T,M> {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
72
common/event/EventLimit.ts
Normal file
72
common/event/EventLimit.ts
Normal file
@ -0,0 +1,72 @@
|
||||
///<reference path="../../typings/tsd.d.ts"/>
|
||||
|
||||
export class EventLimit<T> {
|
||||
|
||||
private lastTriggerValue:T = null;
|
||||
|
||||
private handlers:Array<EventLimitHandler<T>> = [];
|
||||
|
||||
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<T> {
|
||||
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<T> extends EventLimitHandler<T>{
|
||||
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;
|
||||
}
|
||||
}
|
@ -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"]);
|
||||
});
|
||||
}
|
||||
}
|
1
frontend/app/gallery/gallery.component.html
Normal file
1
frontend/app/gallery/gallery.component.html
Normal file
@ -0,0 +1 @@
|
||||
<h1>Gallery</h1>
|
11
frontend/app/gallery/gallery.component.ts
Normal file
11
frontend/app/gallery/gallery.component.ts
Normal file
@ -0,0 +1,11 @@
|
||||
///<reference path="../../../typings/tsd.d.ts"/>
|
||||
|
||||
import { Component } from 'angular2/core';
|
||||
|
||||
@Component({
|
||||
selector: 'gallery',
|
||||
templateUrl: 'app/gallery/gallery.component.html'
|
||||
})
|
||||
export class GalleryComponent{
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form>
|
||||
<div class="group">
|
||||
<input type="text" [(ngModel)]="user.username"><span class="highlight"></span><span class="bar"></span>
|
||||
<input type="text" [(ngModel)]="user.username" required><span class="highlight"></span><span class="bar"></span>
|
||||
<label *ngIf="!user.username">Username (or e-mail)</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<input type="password" [(ngModel)]="user.password"><span class="highlight"></span><span class="bar"></span>
|
||||
<input type="password" [(ngModel)]="user.password" required><span class="highlight"></span><span class="bar"></span>
|
||||
<label *ngIf="!user.password">Password</label>
|
||||
</div>
|
||||
<button type="button" class="button buttonBlue">Login
|
||||
<button type="button" class="button buttonBlue" (click)="onLogin()">Login
|
||||
<div class="ripples buttonRipples"><span class="ripplesCircle"></span></div>
|
||||
</button>
|
||||
</form>
|
@ -14,5 +14,9 @@ export class LoginComponent{
|
||||
constructor(private _loginService: LoginService) {
|
||||
this.user = new LoginCredential();
|
||||
}
|
||||
|
||||
onLogin(){
|
||||
this._loginService.login(this.user);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<User>) => {
|
||||
if(message.result.name == this._authenticating.username || message.result.email == this._authenticating.username){
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public login(user:LoginCredential):Promise<User> {
|
||||
this._networkService.socketIO.emit(MessageTypes.Client.Login.Authenticate, user);
|
||||
this._authenticating = Utils.clone(user);
|
||||
public login(credential:LoginCredential) {
|
||||
this._networkService.login(credential);
|
||||
}
|
||||
|
||||
|
||||
|
28
frontend/app/model/authentication.service.ts
Normal file
28
frontend/app/model/authentication.service.ts
Normal file
@ -0,0 +1,28 @@
|
||||
///<reference path="../../../typings/tsd.d.ts"/>
|
||||
|
||||
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<User>;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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<User>;
|
||||
|
||||
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<User>) =>{
|
||||
if(message.error){
|
||||
//TODO: Handle error
|
||||
}else{
|
||||
this.OnAuthenticated.trigger(message.result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user