mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
removing socket.io creating first middlewares
This commit is contained in:
parent
87fb346c48
commit
2cc8070065
16
backend/middlewares/BaseMWs.ts
Normal file
16
backend/middlewares/BaseMWs.ts
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {Message} from "../../common/entities/Message";
|
||||
import {Error} from "../../common/entities/Error";
|
||||
|
||||
export class BaseMWs {
|
||||
|
||||
protected static renderMessage<T>(res:Response, content:T){
|
||||
let message = new Message<T> ([],content);
|
||||
res.json(message);
|
||||
}
|
||||
protected static renderError(res:Response, error:Error){
|
||||
let message = new Message<any> ([],null);
|
||||
res.json(message);
|
||||
}
|
||||
}
|
@ -1,20 +1,22 @@
|
||||
|
||||
import {UserManager} from "../model/UserManager";
|
||||
import {NextFunction, Request, Response} from "express";
|
||||
import {BaseMWs} from "./BaseMWs";
|
||||
import {Error, ErrorCodes} from "../../common/entities/Error";
|
||||
|
||||
export class UserMWs {
|
||||
export class UserMWs extends BaseMWs{
|
||||
|
||||
|
||||
public static authenticate(req:Request, res:Response, next:NextFunction){
|
||||
if (typeof req.session.user === 'undefined') {
|
||||
return res.redirect('/');
|
||||
return super.renderError(res,new Error(ErrorCodes.NOT_AUTHENTICATED));
|
||||
}
|
||||
return next();
|
||||
}
|
||||
|
||||
public static inverseAuthenticate(req:Request, res:Response, next:NextFunction){
|
||||
if (typeof req.session.user !== 'undefined') {
|
||||
return res.redirect('/');
|
||||
return super.renderError(res,new Error(ErrorCodes.ALREADY_AUTHENTICATED));
|
||||
}
|
||||
return next();
|
||||
}
|
||||
@ -54,7 +56,7 @@ export class UserMWs {
|
||||
|
||||
|
||||
public static renderUser(req:Request, res:Response, next:NextFunction){
|
||||
res.json(req.session.user);
|
||||
super.renderMessage(res,req.session.user);
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,7 +9,7 @@ export class UserRouter{
|
||||
}
|
||||
|
||||
private initLogin() {
|
||||
this.app.get("/api/login",
|
||||
this.app.post("/api/login",
|
||||
UserMWs.inverseAuthenticate,
|
||||
UserMWs.login,
|
||||
UserMWs.renderUser
|
||||
|
@ -4,6 +4,7 @@ import * as _express from 'express';
|
||||
import * as _session from 'express-session';
|
||||
import * as _debug from 'debug';
|
||||
import * as _http from 'http';
|
||||
import * as _path from 'path';
|
||||
import {PublicRouter} from "./routes/PublicRouter";
|
||||
import {UserRouter} from "./routes/UserRouter";
|
||||
|
||||
@ -42,6 +43,10 @@ export class Server {
|
||||
new PublicRouter(this.app);
|
||||
new UserRouter(this.app);
|
||||
|
||||
var renderIndex = (req: _express.Request, res: _express.Response) => {
|
||||
res.sendFile(_path.resolve(__dirname, './../frontend/index.html'));
|
||||
};
|
||||
this.app.get(['/login',"/gallery"], renderIndex);
|
||||
|
||||
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
export class Error{
|
||||
|
||||
export enum ErrorCodes{
|
||||
NOT_AUTHENTICATED,
|
||||
ALREADY_AUTHENTICATED
|
||||
}
|
||||
|
||||
export class Error{
|
||||
constructor(public code:ErrorCodes, public message?:String) {}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import {Error} from "./Error";
|
||||
|
||||
export class Message<T>{
|
||||
constructor(public error:Error,public result:T){}
|
||||
constructor(public errors:Array<Error>,public result:T){}
|
||||
}
|
@ -3,13 +3,13 @@
|
||||
import { Component } from 'angular2/core';
|
||||
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
|
||||
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";
|
||||
import {Router, Location} from "angular2/router";
|
||||
import {HTTP_PROVIDERS} from "angular2/http";
|
||||
import {UserService} from "./model/user.service";
|
||||
|
||||
|
||||
|
||||
@ -19,10 +19,10 @@ import {Router} from "angular2/router";
|
||||
template: `<router-outlet></router-outlet>`,
|
||||
directives: [ROUTER_DIRECTIVES],
|
||||
providers: [
|
||||
HTTP_PROVIDERS,
|
||||
ROUTER_PROVIDERS,
|
||||
NetworkService,
|
||||
AuthenticationService,
|
||||
LoginService
|
||||
UserService,
|
||||
AuthenticationService
|
||||
]
|
||||
})
|
||||
@RouteConfig([
|
||||
@ -40,13 +40,15 @@ import {Router} from "angular2/router";
|
||||
])
|
||||
export class AppComponent implements OnInit{
|
||||
|
||||
constructor(private _router: Router ,private _authenticationService: AuthenticationService){
|
||||
constructor(private _router: Router, private _location:Location, private _authenticationService: AuthenticationService){
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this._authenticationService.OnAuthenticated.on((user:User) =>
|
||||
{
|
||||
this._location.replaceState('/'); // clears browser history so they can't navigate with back button
|
||||
this._router.navigate(["Gallery"]);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
@ -1,11 +1,25 @@
|
||||
///<reference path="../../browser.d.ts"/>
|
||||
|
||||
import { Component } from 'angular2/core';
|
||||
import {Component, OnInit} from 'angular2/core';
|
||||
import {AuthenticationService} from "../model/authentication.service";
|
||||
import {Router,Location} from "angular2/router";
|
||||
|
||||
@Component({
|
||||
selector: 'gallery',
|
||||
templateUrl: 'app/gallery/gallery.component.html'
|
||||
})
|
||||
export class GalleryComponent{
|
||||
export class GalleryComponent implements OnInit{
|
||||
|
||||
constructor(private _authService: AuthenticationService, private _router: Router, private _location:Location) {
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(){
|
||||
if (!this._authService.isAuthenticated()) {
|
||||
this._location.replaceState('/'); // clears browser history so they can't navigate with back button
|
||||
this._router.navigate(['Login']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
<form>
|
||||
<form name="LoginForm">
|
||||
<div class="group">
|
||||
<input type="text" [(ngModel)]="user.username" required><span class="highlight"></span><span class="bar"></span>
|
||||
<label *ngIf="!user.username">Username (or e-mail)</label>
|
||||
<input type="text" [(ngModel)]="loginCredential.username" required><span class="highlight"></span><span class="bar"></span>
|
||||
<label *ngIf="!loginCredential.username">Username (or e-mail)</label>
|
||||
</div>
|
||||
<div class="group">
|
||||
<input type="password" [(ngModel)]="user.password" required><span class="highlight"></span><span class="bar"></span>
|
||||
<label *ngIf="!user.password">Password</label>
|
||||
<input type="password" [(ngModel)]="loginCredential.password" required><span class="highlight"></span><span class="bar"></span>
|
||||
<label *ngIf="!loginCredential.password">Password</label>
|
||||
</div>
|
||||
<button type="button" class="button buttonBlue" (click)="onLogin()">Login
|
||||
<button type="button" class="button buttonBlue" (disabled)="LoginForm.$invalid" (click)="onLogin()">Login
|
||||
<div class="ripples buttonRipples"><span class="ripplesCircle"></span></div>
|
||||
</button>
|
||||
</form>
|
@ -2,21 +2,29 @@
|
||||
|
||||
import {Component, OnInit} from 'angular2/core';
|
||||
import {LoginCredential} from '../../../common/entities/LoginCredential';
|
||||
import {LoginService} from "./login.service";
|
||||
import {AuthenticationService} from "../model/authentication.service";
|
||||
import {Router, Location} from "angular2/router";
|
||||
|
||||
@Component({
|
||||
selector: 'login',
|
||||
templateUrl: 'app/login/login.component.html',
|
||||
styleUrls: ['app/login/login.component.css']
|
||||
})
|
||||
export class LoginComponent{
|
||||
user: LoginCredential;
|
||||
constructor(private _loginService: LoginService) {
|
||||
this.user = new LoginCredential();
|
||||
export class LoginComponent implements OnInit{
|
||||
loginCredential: LoginCredential;
|
||||
constructor(private _authService: AuthenticationService, private _router: Router, private _location:Location) {
|
||||
this.loginCredential = new LoginCredential();
|
||||
}
|
||||
|
||||
ngOnInit(){
|
||||
if (this._authService.isAuthenticated()) {
|
||||
this._location.replaceState('/'); // clears browser history so they can't navigate with back button
|
||||
this._router.navigate(['Gallery']);
|
||||
}
|
||||
}
|
||||
|
||||
onLogin(){
|
||||
this._loginService.login(this.user);
|
||||
this._authService.login(this.loginCredential);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,42 +0,0 @@
|
||||
///<reference path="../../browser.d.ts"/>
|
||||
|
||||
import {
|
||||
it,
|
||||
inject,
|
||||
injectAsync,
|
||||
beforeEachProviders,
|
||||
TestComponentBuilder
|
||||
} from 'angular2/testing';
|
||||
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {BaseRequestOptions, Http} from 'angular2/http';
|
||||
import {MockBackend} from 'angular2/http/testing';
|
||||
import {LoginService} from "./login.service";
|
||||
import {NetworkService} from "../model/network.service";
|
||||
|
||||
|
||||
|
||||
describe('LoginService', () => {
|
||||
beforeEachProviders(() => [
|
||||
provide(NetworkService, {
|
||||
useFactory: function() {
|
||||
return {login() {}};
|
||||
}
|
||||
}),
|
||||
|
||||
LoginService
|
||||
]);
|
||||
|
||||
|
||||
it('should call Network service login', inject([ LoginService,NetworkService ], (loginService, networkService) => {
|
||||
spyOn(networkService,"login");
|
||||
expect(networkService.login).not.toHaveBeenCalled();
|
||||
loginService.login();
|
||||
expect(networkService.login).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
it('should be true', () => {
|
||||
expect(true).toEqual(true)
|
||||
});
|
||||
|
||||
});
|
@ -1,22 +0,0 @@
|
||||
///<reference path="../../browser.d.ts"/>
|
||||
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {NetworkService} from "../model/network.service";
|
||||
import {OnInit} from "angular2/core";
|
||||
import {LoginCredential} from "../../../common/entities/LoginCredential";
|
||||
import {User} from "../../../common/entities/User";
|
||||
import {Message} from "../../../common/entities/Message";
|
||||
|
||||
@Injectable()
|
||||
export class LoginService {
|
||||
|
||||
constructor(private _networkService: NetworkService){
|
||||
}
|
||||
|
||||
public login(credential:LoginCredential) {
|
||||
this._networkService.login(credential);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
37
frontend/app/model/autehentication.service.spec.ts
Normal file
37
frontend/app/model/autehentication.service.spec.ts
Normal file
@ -0,0 +1,37 @@
|
||||
///<reference path="../../browser.d.ts"/>
|
||||
|
||||
import {
|
||||
it,
|
||||
inject,
|
||||
injectAsync,
|
||||
beforeEachProviders,
|
||||
TestComponentBuilder
|
||||
} from 'angular2/testing';
|
||||
|
||||
import {Component, provide} from 'angular2/core';
|
||||
import {AuthenticationService} from "../../../frontend/app/model/authentication.service";
|
||||
import {UserService} from "./user.service";
|
||||
|
||||
|
||||
|
||||
describe('LoginService', () => {
|
||||
beforeEachProviders(() => [
|
||||
provide(UserService, {
|
||||
useFactory: function() {
|
||||
return {login() {}};
|
||||
}
|
||||
}),
|
||||
|
||||
AuthenticationService
|
||||
]);
|
||||
|
||||
|
||||
it('should call User service login', inject([ AuthenticationService,UserService ], (authService, userService) => {
|
||||
spyOn(userService,"login");
|
||||
expect(userService.login).not.toHaveBeenCalled();
|
||||
authService.login();
|
||||
expect(userService.login).toHaveBeenCalled();
|
||||
}));
|
||||
|
||||
|
||||
});
|
@ -1,28 +1,38 @@
|
||||
///<reference path="../../browser.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";
|
||||
import {UserService} from "./user.service";
|
||||
import {LoginCredential} from "../../../common/entities/LoginCredential";
|
||||
import {Message} from "../../../common/entities/Message";
|
||||
|
||||
@Injectable()
|
||||
export class AuthenticationService{
|
||||
|
||||
private _user:User;
|
||||
private _user:User = null;
|
||||
public OnAuthenticated:Event<User>;
|
||||
|
||||
constructor(private _networkService: NetworkService){
|
||||
constructor(private _userService: UserService){
|
||||
this.OnAuthenticated = new Event();
|
||||
this._networkService.OnAuthenticated.on(this.onAuthenticated);
|
||||
}
|
||||
|
||||
|
||||
private onAuthenticated = (user:User) => {
|
||||
this._user=user;
|
||||
public login(credential:LoginCredential){
|
||||
this._userService.login(credential).then( (message:Message<User>) =>{
|
||||
console.log(message);
|
||||
if(message.errors && message.errors.length > 0){
|
||||
console.log(message.errors);
|
||||
}else{
|
||||
this._user = message.result;
|
||||
this.OnAuthenticated.trigger(this._user);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public isAuthenticated():boolean{
|
||||
return this._user && this._user != null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,39 +1,33 @@
|
||||
///<reference path="../../browser.d.ts"/>
|
||||
|
||||
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 {Http, Headers, RequestOptions, Response} from "angular2/http";
|
||||
import {Message} from "../../../common/entities/Message";
|
||||
import "rxjs/Rx";
|
||||
|
||||
@Injectable()
|
||||
export class NetworkService{
|
||||
|
||||
private _socketIO: SocketIOClient.Socket;
|
||||
_baseUrl = "/api";
|
||||
|
||||
public OnAuthenticated:Event<User>;
|
||||
|
||||
constructor(){
|
||||
this._socketIO = io();
|
||||
this.OnAuthenticated = new Event();
|
||||
this._subscribeMessages();
|
||||
constructor(protected _http:Http){
|
||||
}
|
||||
|
||||
|
||||
public login(credential:LoginCredential){
|
||||
this._socketIO.emit(MessageTypes.Client.Login.Authenticate,credential);
|
||||
|
||||
protected postJson(url:string, data:any = {}){
|
||||
let body = JSON.stringify({ data });
|
||||
let headers = new Headers({ 'Content-Type': 'application/json' });
|
||||
let options = new RequestOptions({ headers: headers });
|
||||
console.log(this._http.post(this._baseUrl+url, body, options));
|
||||
return this._http.post(this._baseUrl+url, body, options)
|
||||
.toPromise()
|
||||
.then(res => <Message<any>> res.json())
|
||||
.catch(NetworkService.handleError);
|
||||
}
|
||||
|
||||
private _subscribeMessages(){
|
||||
this._socketIO.on(MessageTypes.Server.Login.Authenticated, (message:Message<User>) =>{
|
||||
if(message.error){
|
||||
//TODO: Handle error
|
||||
}else{
|
||||
this.OnAuthenticated.trigger(message.result);
|
||||
}
|
||||
});
|
||||
private static handleError (error: any) {
|
||||
// in a real world app, we may send the error to some remote logging infrastructure
|
||||
// instead of just logging it to the console
|
||||
console.error(error);
|
||||
return Promise.reject(error.message || error.json().error || 'Server error');
|
||||
}
|
||||
}
|
||||
|
23
frontend/app/model/user.service.ts
Normal file
23
frontend/app/model/user.service.ts
Normal file
@ -0,0 +1,23 @@
|
||||
///<reference path="../../browser.d.ts"/>
|
||||
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {LoginCredential} from "../../../common/entities/LoginCredential";
|
||||
import {Http} from "angular2/http";
|
||||
import {NetworkService} from "./network.service";
|
||||
|
||||
@Injectable()
|
||||
export class UserService extends NetworkService{
|
||||
|
||||
|
||||
|
||||
constructor(_http:Http){
|
||||
super(_http);
|
||||
}
|
||||
|
||||
|
||||
public login(credential:LoginCredential){
|
||||
return this.postJson("/login",credential);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -33,8 +33,6 @@
|
||||
"protractor": "^3.2.0",
|
||||
"reflect-metadata": "0.1.2",
|
||||
"rxjs": "^5.0.0-beta.2",
|
||||
"socket.io": "^1.4.5",
|
||||
"socket.io-client": "^1.4.5",
|
||||
"ts-loader": "^0.8.1",
|
||||
"ts-node": "^0.6.2",
|
||||
"typescript": "^1.8.9",
|
||||
|
@ -8,8 +8,6 @@
|
||||
"jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#d22516f9f089de107d7e7d5938566377370631f6",
|
||||
"mime": "github:DefinitelyTyped/DefinitelyTyped/mime/mime.d.ts#0d622d857f97d44ea7dcad2b3edec1f23c48fe9e",
|
||||
"node": "github:DefinitelyTyped/DefinitelyTyped/node/node.d.ts#0d622d857f97d44ea7dcad2b3edec1f23c48fe9e",
|
||||
"serve-static": "github:DefinitelyTyped/DefinitelyTyped/serve-static/serve-static.d.ts#0d622d857f97d44ea7dcad2b3edec1f23c48fe9e",
|
||||
"socket.io": "github:DefinitelyTyped/DefinitelyTyped/socket.io/socket.io.d.ts#d22516f9f089de107d7e7d5938566377370631f6",
|
||||
"socket.io-client": "github:DefinitelyTyped/DefinitelyTyped/socket.io-client/socket.io-client.d.ts#d22516f9f089de107d7e7d5938566377370631f6"
|
||||
"serve-static": "github:DefinitelyTyped/DefinitelyTyped/serve-static/serve-static.d.ts#0d622d857f97d44ea7dcad2b3edec1f23c48fe9e"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user