Refactor Login Service

- Change to new @angular/common/http for requests
master
trivernis 5 years ago
parent dcf3808d49
commit 7e12f42ce0

12
package-lock.json generated

@ -194,6 +194,12 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
"dev": true
},
"typescript": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
"integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
"dev": true
}
}
},
@ -12743,9 +12749,9 @@
"dev": true
},
"typescript": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
"integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
"version": "3.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz",
"integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==",
"dev": true
},
"uglify-js": {

@ -59,6 +59,6 @@
"protractor": "^5.4.2",
"ts-node": "~7.0.0",
"tslint": "^5.20.1",
"typescript": "~3.5.0"
"typescript": "^3.7.4"
}
}

@ -4,6 +4,7 @@ import { Login } from 'src/app/models/login';
import { LoginService } from 'src/app/services/login/login.service';
import {Router} from '@angular/router';
import * as sha512 from 'js-sha512';
import {IErrorResponse} from '../../models/interfaces/IErrorResponse';
@Component({
selector: 'app-login',
@ -21,22 +22,37 @@ export class LoginComponent implements OnInit {
errorMessage: string;
email = new FormControl('', [Validators.required, Validators.email]);
public getErrorMessage() {
private getErrorMessage() {
return this.errorMessage;
}
public loginError(error: any) {
private loginError(errorResponse: IErrorResponse) {
const error = errorResponse.error;
this.errorOccurred = true;
this.errorMessage = error.errors[0].message;
}
/**
* Fired when the submit button is pressed.
* A login request is performed and the user is redirected to the home page on success.
* @param pEmail
* @param pPasswordHash
*/
onClickSubmit(pEmail: string, pPasswordHash: string) {
this.errorOccurred = false;
this.errorMessage = ' ';
this.login.email = pEmail.trim().toLowerCase();
this.login.passwordHash = sha512.sha512(pPasswordHash);
this.loginService.login(this.login, error => this.loginError(error.json()));
this.loginService.login(this.login).subscribe( () => {
this.router.navigateByUrl('').catch((error) => {
this.errorMessage = error.message;
this.errorOccurred = true;
});
}, (error: IErrorResponse) => {
if (error.error) {
this.loginError(error);
}
});
}
ngOnInit() {}

@ -5,4 +5,11 @@ export class FriendRequest {
senderUserID: number;
senderHandle: string;
senderUsername: string;
constructor(id?: number, senderUserId?: number, senderHandle?: string, senderName?: string) {
this.id = id;
this.senderUserID = senderUserId;
this.senderHandle = senderHandle;
this.senderUsername = senderName;
}
}

@ -0,0 +1,12 @@
import {IUser} from './IUser';
export interface IChat {
id: number;
namespace: string;
members: IUser[];
messages: any[];
}

@ -0,0 +1,8 @@
import {IGraphqlError} from './IGraphqlError';
export interface IErrorResponse {
error: {
errors: IGraphqlError[];
data: any;
};
}

@ -0,0 +1,8 @@
export interface IGraphqlError {
message: string;
path: string[];
location: {line: number; column: number}[];
}

@ -0,0 +1,18 @@
import {IUser} from './IUser';
export enum RequestType {
FRIENDREQUEST = 'FRIENDREQUEST',
GROUPINVITE = 'GROUPINVITE',
EVENTINVITE = 'EVENTINVITE',
}
export interface IRequest {
id: number;
sender: IUser;
receiver: IUser;
type: RequestType;
}

@ -0,0 +1,3 @@
export interface ISettings {
darkmode?: boolean;
}

@ -1,4 +1,7 @@
import {IGroup} from './IGroup';
import {ISettings} from './ISettings';
import {IChat} from './IChat';
import {IRequest} from './IRequest';
export interface IUser {
@ -8,8 +11,12 @@ export interface IUser {
handle: string;
email?: string;
profilePicture?: string;
settings?: string;
level: number;
points: number;
@ -20,7 +27,13 @@ export interface IUser {
posts: any[];
joinedAt: Date;
chats: IChat[];
receivedRequests: IRequest[];
sentRequests: IRequest[];
joinedAt: string;
friendCount: number;

@ -2,6 +2,7 @@ import { FriendRequest } from 'src/app/models/friendRequest';
import { FriendInfo } from 'src/app/models/friendinfo';
import { GroupInfo } from 'src/app/models/groupinfo';
import { Post } from 'src/app/models/post';
import {IUser} from './interfaces/IUser';
export class User {
loggedIn = false;
@ -18,12 +19,39 @@ export class User {
darkmode = false;
friends: FriendInfo[] = new Array();
groups: GroupInfo[] = new Array();
posts: Post[] = new Array();
friends: FriendInfo[] = [];
groups: GroupInfo[] = [];
posts: Post[] = [];
chatIDs: number[];
receivedRequests: FriendRequest[] = new Array();
sentRequestUserIDs: number[] = new Array(); // IDs of users that already received requests of the logged in user
receivedRequests: FriendRequest[] = [];
sentRequestUserIDs: number[] = []; // IDs of users that already received requests of the logged in user
allowedToSendRequest = true; /* if a user already received a request this should
be false to avoid multiple invitations*/
public assignFromResponse(userDataResponse: IUser) {
this.userID = userDataResponse.id;
this.username = userDataResponse.name;
this.handle = userDataResponse.handle;
this.email = userDataResponse.email;
this.points = userDataResponse.points;
this.level = userDataResponse.level;
this.profilePicture = userDataResponse.profilePicture;
this.joinedAt = userDataResponse.joinedAt;
this.friendCount = userDataResponse.friendCount;
this.groupCount = userDataResponse.groupCount;
try {
this.darkmode = !!JSON.parse(userDataResponse.settings).darkmode;
} catch (err) {
console.error(err);
}
this.friends = userDataResponse.friends
.map(friend => new FriendInfo(friend.id, friend.name, friend.level));
this.groups = userDataResponse.groups
.map(group => new GroupInfo(group.id, group.name));
this.chatIDs = userDataResponse.chats.map(chat => chat.id);
this.sentRequestUserIDs = userDataResponse.sentRequests
.map(request => request.receiver.id);
this.receivedRequests = userDataResponse.receivedRequests
.map(request => new FriendRequest(request.id, request.sender.id, request.sender.handle, request.sender.name));
}
}

@ -1,105 +1,83 @@
import {Injectable} from '@angular/core';
import {Headers, Http, Request} from '@angular/http';
import {HttpClient} from '@angular/common/http';
import {Login} from '../../models/login';
import {User} from 'src/app/models/user';
import {DatasharingService} from '../datasharing.service';
import {Router} from '@angular/router';
import {environment} from 'src/environments/environment';
import { FriendRequest } from 'src/app/models/friendRequest';
import { FriendInfo } from 'src/app/models/friendinfo';
import { GroupInfo } from 'src/app/models/groupinfo';
import {FriendRequest} from 'src/app/models/friendRequest';
import {FriendInfo} from 'src/app/models/friendinfo';
import {GroupInfo} from 'src/app/models/groupinfo';
import {IUser} from '../../models/interfaces/IUser';
import {BaseService} from '../base.service';
import {tap} from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class LoginService {
constructor(private http: Http, private data: DatasharingService, private router: Router) {
}
public login(login: Login, errorCb: any) {
const headers = new Headers();
headers.set('Content-Type', 'application/json');
interface ILoginRequestResult {
data: {
login: IUser;
};
}
return this.http.post(environment.graphQLUrl, this.buildJson(login))
.subscribe(response => {
this.loginSuccess();
this.updateUserInfo(response.json());
}, errorCb
);
const graphqlQuery = `mutation($email: String!, $pwHash: String!) {
login(email: $email, passwordHash: $pwHash) {
id,
name,
email,
handle,
points,
level,
receivedRequests{id, sender{name, handle, id}},
sentRequests{receiver{id}},
friends {
id,
name,
level
},
groups {
id,
name
},
chats{
id
},
settings
}
}`;
public loginSuccess() {
this.router.navigateByUrl('');
}
@Injectable({
providedIn: 'root'
})
export class LoginService extends BaseService {
public updateUserInfo(response: any) {
const user: User = new User();
let friendRequest: FriendRequest = new FriendRequest();
user.loggedIn = true;
user.userID = response.data.login.id;
user.username = response.data.login.name;
user.handle = response.data.login.handle;
user.email = response.data.login.email;
user.points = response.data.login.points;
user.level = response.data.login.level;
for (const friend of response.data.login.friends) {
user.friends.push(new FriendInfo(friend.id, friend.name, friend.level));
}
for (const group of response.data.login.groups) {
user.groups.push(new GroupInfo(group.id, group.name));
}
user.chatIDs = response.data.login.chats;
for (const request of response.data.login.sentRequests) {
user.sentRequestUserIDs.push(request.receiver.id);
}
for (const request of response.data.login.receivedRequests) {
friendRequest = new FriendRequest();
friendRequest.id = request.id;
friendRequest.senderUserID = request.sender.id;
friendRequest.senderUsername = request.sender.name;
friendRequest.senderHandle = request.sender.handle;
user.receivedRequests.push(friendRequest);
}
if (JSON.parse(response.data.login.settings).darkmode === 'true') {
user.darkmode = true;
}
this.data.changeUserInfo(user);
constructor(private http: HttpClient, private datasharingService: DatasharingService, private router: Router) {
super();
}
public buildJson(login: Login): any {
const body = {
query: `mutation($email: String!, $pwHash: String!) {
login(email: $email, passwordHash: $pwHash) {
id,
name,
email,
handle,
points,
level,
receivedRequests{id, sender{name, handle, id}},
sentRequests{receiver{id}},
friends {
id,
name,
level
},
groups {
id,
name
},
chats{
id
},
settings
}
}`
, variables: {
/**
* Builds the body for the login request
* @param login
*/
private static buildRequestBody(login: Login): any {
return {
query: graphqlQuery,
variables: {
email: login.email,
pwHash: login.passwordHash,
}
};
return body;
}
/**
* Performs a login request and returns the data of the logged in user.
* @param login
*/
public login(login: Login) {
const body = LoginService.buildRequestBody(login);
return this.http.post<ILoginRequestResult>(environment.graphQLUrl, body)
.pipe(tap(response => {
const user = new User();
user.assignFromResponse(response.data.login);
this.datasharingService.changeUserInfo(user);
}));
}
}

@ -42,12 +42,29 @@ const graphqlQuery = `query($query: String!, $first: Int, $offset: Int) {
providedIn: 'root'
})
export class SearchService extends BaseService {
users: User[];
constructor(private http: HttpClient, private data: DatasharingService, private router: Router) {
super();
}
users: User[];
/**
* Builds the body for the request
* @param query - the search query
* @param first - the limit of elements to fetch
* @param offset - offset
*/
private static buildRequestBody(query: String, first: number = 20, offset: number = 0): any {
return {
query: graphqlQuery,
variables: {
query,
first,
offset
}
};
}
/**
* Maps the users in the response to the user class
* @param response
@ -86,24 +103,7 @@ export class SearchService extends BaseService {
* @param query
*/
public search(query: string): Observable<ISearchRequestResult> {
const body = this.buildRequestBody(query);
const body = SearchService.buildRequestBody(query);
return this.http.post<ISearchRequestResult>(environment.graphQLUrl, body, {headers: this.headers});
}
/**
* Builds the body for the request
* @param query - the search query
* @param first - the limit of elements to fetch
* @param offset - offset
*/
private buildRequestBody(query: String, first: number = 20, offset: number = 0): any {
return {
query: graphqlQuery,
variables: {
query,
first,
offset
}
};
}
}

Loading…
Cancel
Save