Skip to content

Commit

Permalink
Merge pull request #41 from devdanielsun/developer
Browse files Browse the repository at this point in the history
Developer
  • Loading branch information
devdanielsun authored Feb 3, 2024
2 parents 4e2ed7f + 6a6b851 commit c6748dd
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 92 deletions.
2 changes: 1 addition & 1 deletion database/migration.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ CREATE TABLE [dbo].[users](
[password] [nvarchar](128) NOT NULL,
[first_name] [nvarchar](64) NULL,
[last_name] [nvarchar](64) NULL,
[role] [nvarchar](32) NULL DEFAULT 'user',
[role] [nvarchar](32) NULL DEFAULT 'Basic',
[created_at] [datetime] NOT NULL,
CONSTRAINT PK_users PRIMARY KEY NONCLUSTERED (id),
CONSTRAINT UC_Users UNIQUE (id,emailaddress,username)
Expand Down
2 changes: 1 addition & 1 deletion pollor.Server/Controllers/AuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public IActionResult Login([FromBody] LoginModel loginUser)
_logger.LogError("Rehash password and save to DB");
}

int tokenLongerValid = (bool)loginUser.tokenLongerValid ? 31 : 1;// true = 31, false = 1
int tokenLongerValid = (bool)loginUser.tokenLongerValid ? 14 : 1;// true = 14, false = 1
var currentUser = new PollorDbContext().Users.Where(u => u.username!.ToLower().Equals(authUser.username!.ToLower())).FirstOrDefault();
var tokenOptions = GetJwtTokenOptions(tokenLongerValid, currentUser!);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
Expand Down
71 changes: 37 additions & 34 deletions pollor.client/src/app/alert-message/alert-message.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component } from '@angular/core';
import { Component, Injectable } from '@angular/core';
import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';

interface Alert {
Expand All @@ -16,52 +16,55 @@ const ALERTS: Alert[] = [
];

@Component({
selector: 'ngbd-alert-message',
standalone: true,
imports: [NgbAlertModule],
templateUrl: './alert-message.html',
styleUrl: './alert-message.css'
selector: 'ngbd-alert-message',
standalone: true,
imports: [NgbAlertModule],
templateUrl: './alert-message.html',
styleUrl: './alert-message.css'

})
@Injectable({
providedIn: 'root'
})
export class AlertMessage {
static alerts: Alert[] = ALERTS;
alerts: Alert[] = ALERTS;

constructor() {
this.reset();
}
constructor() {
//this.reset();
}

close(alert: Alert) {
AlertMessage.alerts.splice(AlertMessage.alerts.indexOf(alert), 1);
}
close(alert: Alert) {
this.alerts.splice(this.alerts.indexOf(alert), 1);
}

reset() {
AlertMessage.alerts = [];
}
reset() {
this.alerts = [];
}

static addAlert(alertType: string, alertTitle: string, alertMessage: string, timeout: number = 10000) {
const newAlert : Alert = {
type: alertType,
title: alertTitle,
message: alertMessage
};
addAlert(alertType: string, alertTitle: string, alertMessage: string, timeout: number = 10000) {
const newAlert: Alert = {
type: alertType,
title: alertTitle,
message: alertMessage
};

AlertMessage.alerts.unshift(newAlert);
this.alerts.unshift(newAlert);

setTimeout(() => {
AlertMessage.alerts.splice(AlertMessage.alerts.indexOf(newAlert), 1);
}, timeout); // automatic close the alert after x miliseconds based
setTimeout(() => {
this.alerts.splice(this.alerts.indexOf(newAlert), 1);
}, timeout); // automatic close the alert after x miliseconds based
}


static addSuccessAlert(alertMessage: string) {
AlertMessage.addAlert("success", "Success!", alertMessage);
addSuccessAlert(alertMessage: string) {
this.addAlert("success", "Success!", alertMessage);
}

static addErrorAlert(alertMessage: string) {
AlertMessage.addAlert("danger", "An error occured", alertMessage);
}
addErrorAlert(alertMessage: string) {
this.addAlert("danger", "An error occured", alertMessage);
}

getAlertMessages() {
return AlertMessage.alerts;
}
getAlertMessages() {
return this.alerts;
}
}
2 changes: 2 additions & 0 deletions pollor.client/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { UserLoginComponent } from './user-login/user-login.component';
import { UserRegisterComponent } from './user-register/user-register.component';
import { UserProfileComponent } from './user-profile/user-profile.component';
import { UserAdminProfileComponent } from './user-admin-profile/user-admin-profile.component';
import { UserLogoutComponent } from './user-logout/user-logout.component';

const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'account/login', component: UserLoginComponent },
{ path: 'account/register', component: UserRegisterComponent },
{ path: 'account/logout', component: UserLogoutComponent },
{ path: 'account/profile', component: UserProfileComponent },
{ path: 'account/admin-profile', component: UserAdminProfileComponent },
{ path: 'polls', component: PollsComponent },
Expand Down
4 changes: 3 additions & 1 deletion pollor.client/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { UserLoginComponent } from './user-login/user-login.component';
import { UserRegisterComponent } from './user-register/user-register.component';
import { AlertMessage } from './alert-message/alert-message';
import { UserAdminProfileComponent } from './user-admin-profile/user-admin-profile.component';
import { UserLogoutComponent } from './user-logout/user-logout.component';

@NgModule({
declarations: [
Expand All @@ -31,7 +32,8 @@ import { UserAdminProfileComponent } from './user-admin-profile/user-admin-profi
UserProfileComponent,
UserLoginComponent,
UserRegisterComponent,
UserAdminProfileComponent
UserAdminProfileComponent,
UserLogoutComponent
],
imports: [
BrowserModule,
Expand Down
6 changes: 4 additions & 2 deletions pollor.client/src/app/header/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import { AuthService } from '../../services/auth.service';
})
export class HeaderComponent {

constructor(private authService: AuthService) { }

isAdmin(): boolean {
return AuthService.getRole().toLowerCase() == "admin";
return this.authService.getRole().toLowerCase() == "admin";
}

isLoggedIn(): boolean {
return AuthService.isLoggedIn();
return this.authService.isLoggedIn();
}
}
7 changes: 5 additions & 2 deletions pollor.client/src/app/polls/polls.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ export class PollsComponent {
public pollLoadingMsg: string = "Loading polls...";
public pollLoadingColor: string = "";

constructor(private apiService: ApiService) { }
constructor(
private apiService: ApiService,
private alertMessage: AlertMessage
) { }

ngOnInit() {
this.getPolls();
Expand All @@ -34,7 +37,7 @@ export class PollsComponent {
this.pollLoadingMsg = err.status + ' - ' + msg;
this.pollLoadingColor = "red";
console.error(err);
AlertMessage.addErrorAlert(msg);
this.alertMessage.addErrorAlert(msg);
},
//complete: () => { }
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Component } from '@angular/core';
import { AuthService } from '../../services/auth.service';

@Component({
selector: 'app-user-admin-profile',
Expand All @@ -7,4 +8,8 @@ import { Component } from '@angular/core';
})
export class UserAdminProfileComponent {

constructor(private authService: AuthService) {
this.authService.logoutIfUserDoesNotValidate(); // redirect to logout if user or token is not ok
this.authService.redirectIfUserIsNotAdmin(); // redirect to 404 not found page if user is not admin
}
}
29 changes: 9 additions & 20 deletions pollor.client/src/app/user-login/user-login.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Component } from '@angular/core';
import { AuthService } from '../../services/auth.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { finalize } from 'rxjs/operators';
import { AlertMessage } from '../alert-message/alert-message';

Expand All @@ -18,20 +17,17 @@ export class UserLoginComponent {
constructor(
private formBuilder: FormBuilder,
private authService: AuthService,
private router: Router
private alertMessage: AlertMessage
) {
this.loginForm = formBuilder.group({
username: ["", Validators.required],
password: ["", Validators.required],
tokenLongerValid: [false, Validators.required]
});

const token = localStorage.getItem('token');
const role = localStorage.getItem('role');

if (token && role) {
if (this.authService.isLoggedIn()) {
console.log("validate user");
this.validateUser(); // validate and navigate to role profile page
this.validateUserAndRedirectToProfile(); // validate and navigate to role profile page
}
}

Expand All @@ -52,20 +48,20 @@ export class UserLoginComponent {
localStorage.setItem('role', res.user.role);
this.loginError = '';
this.loginForm.reset();
this.navigateDashboard(res.user.role);
AlertMessage.addSuccessAlert("Login is successfull !");
this.authService.navigateDashboard(res.user.role);
this.alertMessage.addSuccessAlert("Login is successfull !");
},
error: (err: any) => {
const msg = ((err.error && err.error.message) ? err.error.message : err.message);
this.loginError = err.status + ' - ' + msg;
console.error('Login Error:', err);
AlertMessage.addErrorAlert(msg);
this.alertMessage.addErrorAlert(msg);
},
});
}
}

validateUser(): any {
validateUserAndRedirectToProfile(): any {
this.loading = true; // Start the loading spinner
this.authService
.validateToken()
Expand All @@ -77,21 +73,14 @@ export class UserLoginComponent {
.subscribe({
next: (res: any) => {
console.log('Response:', res);
this.navigateDashboard(res.user.role);
this.authService.navigateDashboard(res.user.role);
},
error: (err: any) => {
const msg = ((err.error && err.error.message) ? err.error.message : err.message);
this.loginError = err.status + ' - ' + msg;
console.error('Token validation Error:', err);
AlertMessage.addErrorAlert(msg);
this.alertMessage.addErrorAlert(msg);
},
});
}

navigateDashboard(role: string): void {
const dashboardRoute =
role === 'admin' ? '/account/admin-profile' : '/account/profile';
this.router.navigate([dashboardRoute]);
console.log(`${role} dashboard route`);
}
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>user-logoutt works!</p>
13 changes: 13 additions & 0 deletions pollor.client/src/app/user-logout/user-logout.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import { AuthService } from '../../services/auth.service';

@Component({
selector: 'app-user-logout',
templateUrl: './user-logout.component.html',
styleUrl: './user-logout.component.css'
})
export class UserLogoutComponent {
constructor(private authService: AuthService) {
this.authService.logout("please log me out");
}
}
7 changes: 5 additions & 2 deletions pollor.client/src/app/user-profile/user-profile.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ export class UserProfileComponent {
private formBuilder: FormBuilder,
private authService: AuthService,
private router: Router,
private apiService: ApiService
private apiService: ApiService,
private alertMessage: AlertMessage
) {
this.editUserForm = formBuilder.group({
username: ["", Validators.required],
emailaddress: ["", Validators.required],
first_name: ["", Validators.required],
last_name: ["", Validators.required]
});

this.authService.logoutIfUserDoesNotValidate(); // redirect if not loggedin or token is not ok
}

ngOnInit() {
Expand All @@ -59,7 +62,7 @@ export class UserProfileComponent {
const msg = ((err.error && err.error.message) ? err.error.message : err.message);
this.userLoadingMsg = err.status + ' - ' + msg;
console.error(err);
AlertMessage.addErrorAlert(msg);
this.alertMessage.addErrorAlert(msg);
},
//complete: () => { }
});
Expand Down
30 changes: 10 additions & 20 deletions pollor.client/src/app/user-register/user-register.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export class UserRegisterComponent {
constructor(
private fb: FormBuilder,
private authService: AuthService,
private router: Router) {
private alertMessage: AlertMessage
) {
this.registerForm = this.fb.group({
emailaddress: new FormControl(null, [Validators.required, Validators.pattern(this.regexEmail)]),
username: new FormControl(null, [Validators.required, Validators.minLength(4)]),
Expand All @@ -30,12 +31,8 @@ export class UserRegisterComponent {
validator: this.ConfirmedValidator('password', 'confirmPassword'),
});

const token = localStorage.getItem('token');
const role = localStorage.getItem('role');

if (token && role) {
console.log("validate user");
this.validateUser(); // validate and navigate to role profile page
if (this.authService.isLoggedIn()) {
this.validateUserAndRedirectToProfile(); // validate and navigate to role profile page
}
}

Expand All @@ -61,20 +58,20 @@ export class UserRegisterComponent {
localStorage.setItem('role', res.user.role);
this.registerError = '';
this.registerForm.reset();
this.navigateDashboard(res.user.role);
AlertMessage.addSuccessAlert("Account registration is successfull !");
this.authService.navigateDashboard(res.user.role);
this.alertMessage.addSuccessAlert("Account registration is successfull !");
},
error: (err: any) => {
const msg = ((err.error && err.error.message) ? err.error.message : err.message);
this.registerError = err.status + ' - ' + msg;
console.error('Login Error:', err);
AlertMessage.addErrorAlert(msg);
this.alertMessage.addErrorAlert(msg);
},
});
}
}

validateUser(): any {
validateUserAndRedirectToProfile(): any {
this.loading = true; // Start the loading spinner
this.authService
.validateToken()
Expand All @@ -86,24 +83,17 @@ export class UserRegisterComponent {
.subscribe({
next: (res: any) => {
console.log('Response:', res);
this.navigateDashboard(res.user.role);
this.authService.navigateDashboard(res.user.role);
},
error: (err: any) => {
const msg = ((err.error && err.error.message) ? err.error.message : err.message);
this.registerError = err.status + ' - ' + msg;
console.error('Token validation Error:', err);
AlertMessage.addErrorAlert(msg);
this.alertMessage.addErrorAlert(msg);
},
});
}

navigateDashboard(role: string): void {
const dashboardRoute =
role === 'admin' ? '/account/admin-profile' : '/account/profile';
this.router.navigate([dashboardRoute]);
console.log(`${role} dashboard route`);
}

ConfirmedValidator(controlName: string, matchingControlName: string) {
return (formGroup: FormGroup) => {
const control = formGroup.controls[controlName];
Expand Down
Loading

0 comments on commit c6748dd

Please sign in to comment.