Commit 0d68aa1b authored by hasan khaddour's avatar hasan khaddour

fix token storing

parent f32c313a
......@@ -23,6 +23,7 @@
"@ngx-translate/core": "^15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
"@popperjs/core": "^2.11.8",
"angular-jwt": "^0.1.11",
"bootstrap": "^5.3.3",
"dhtmlx-gantt": "^8.0.10",
"dom-to-image": "^2.6.0",
......@@ -34,6 +35,7 @@
"jspdf": "^2.5.1",
"material": "^0.9.15",
"moment": "^2.30.1",
"ngx-cookie-service": "^18.0.0",
"ngx-pagination": "^6.0.3",
"ngx-toastr": "^19.0.0",
"rxjs": "~7.8.0",
......@@ -4844,6 +4846,14 @@
"ajv": "^8.8.2"
}
},
"node_modules/angular-jwt": {
"version": "0.1.11",
"resolved": "https://registry.npmjs.org/angular-jwt/-/angular-jwt-0.1.11.tgz",
"integrity": "sha512-793dv5vXOXaW5/cweMd+sqSf9dPhbazDya3szTVOQ84MDEj1nYLJrixBBa7WNtZeMqz7ylWX7djnFgqLjEWcHw==",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
......@@ -9934,6 +9944,18 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"node_modules/ngx-cookie-service": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-18.0.0.tgz",
"integrity": "sha512-hkkUckzZTXXWtFgvVkT2hg6mwYMLXioXDZWBsVCOy9gYkADjsj0N5VViO7eo2izQ0VcMPd/Etog1trf/T4oZMQ==",
"dependencies": {
"tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/common": "^18.0.0-rc.0",
"@angular/core": "^18.0.0-rc.0"
}
},
"node_modules/ngx-i18nsupport": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/ngx-i18nsupport/-/ngx-i18nsupport-0.17.1.tgz",
......
......@@ -5,8 +5,6 @@ import { AuthenticationService } from './services/authentication/authentication.
import { ConfigurationService } from './services/configuration/configuration.service';
import { UserService } from './services/authentication/user.service';
import { PdfDownloaderService } from './services/pdfDownloader/pdf-downloader.service';
@NgModule({
declarations: [],
imports: [
......
......@@ -10,7 +10,7 @@ export class JwtInterceptor implements HttpInterceptor {
constructor(private authService : AuthenticationService ,) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = this.authService.getAuthorizationToken();
const token = this.authService.getToken();
if (token) {
request = request.clone({
......
//#region Imports
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { LoginRequest } from '../../models/authentication/loginRequest';
import { RegisterRequest } from '../../models/authentication/registerRequest';
import { AuthenticationResponse } from '../../models/authentication/authenticationResponse';
import { catchError, Observable, throwError } from 'rxjs';
import { catchError, Observable, tap, throwError } from 'rxjs';
import { ConfigurationService } from '../configuration/configuration.service';
import { DataStorageService } from '../dataStorage/data-storage.service';
import { CookieService } from 'ngx-cookie-service';
//#endregion Imports
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
constructor(private http : HttpClient,private config : ConfigurationService, private dataStorage : DataStorageService) { }
//#region Consrtuctor
constructor(
private http : HttpClient,
private config : ConfigurationService,
private dataStorage : DataStorageService,
private cookieService :CookieService
getAuthorizationToken() {
return this.dataStorage.getItem("token");
}
) { }
//#endregion Consrtuctor
//#region Login
Login(loginRequest : LoginRequest ) :Observable<AuthenticationResponse>{
return this.http
.post<AuthenticationResponse>(
this.config.getServerUrl()+ "/Authentication/Login",loginRequest)
this.config.getServerUrl()+ "/Authentication/Login",loginRequest).pipe(
tap(response => {
// Store JWT token in cookie
this.cookieService.set('token', response.token,1); // Expires in days
})
)
}
Register(registerRequest : RegisterRequest ) :Observable<AuthenticationResponse>{
//#endregion Login
return this.http
.post<AuthenticationResponse>(
this.config.getServerUrl()+ "/Authentication/register",registerRequest)
.pipe(
catchError(error => {
return throwError(() => error.error);
})
);
}
//#region Un used Registeration
// in our domain there are no registeration
// Register(registerRequest : RegisterRequest ) :Observable<AuthenticationResponse>{
// return this.http
// .post<AuthenticationResponse>(
// this.config.getServerUrl()+ "/Authentication/register",registerRequest)
// .pipe(
// catchError(error => {
// return throwError(() => error.error);
// })
// );
// }
//#endregion Un used Registeration
//#region Authentication
isAuthenticated():Boolean{
if(this.dataStorage.getItem("token")){
if(this.getToken()){
return true ;
}else{
return false ;
}
}
logou(){
this.dataStorage.removeItem("token");
getToken(): string | null {
return this.cookieService.get('token');
}
//#endregion Authentication
//#region Logout
logout(){
this.cookieService.delete('token');
this.dataStorage.removeItem("userDetails");
}
//#endregion Logout
}
......@@ -21,7 +21,7 @@
<input type="checkbox" value="remember-me"> Stay logged in </label>
</div> -->
<button class="btn btn-primary btn-block" (click)="onLogin()">Let me in</button>
<button class="btn btn-primary btn-block" (click)="onLogin()">تسجيل الدخول</button>
<p class="mt-5 mb-3 text-muted">© 2024</p>
</form>
......
......@@ -14,12 +14,19 @@ import { ToastrService } from 'ngx-toastr';
styleUrl: './login.component.css'
})
export class LoginComponent implements OnInit {
//login request
loginRequest:LoginRequest = {
email :"",
passWord:""
}
ngOnInit(): void {
// check if the user already exist
if(this.authService.isAuthenticated()){
this.toastr.info('أنت مسجل بالفعل لاداعي لإعادة التسجيل', ' ')
this.router.navigateByUrl('/home');
}
......@@ -35,32 +42,37 @@ export class LoginComponent implements OnInit {
}
// handel login
//#region Login handler
onLogin() {
this.authService
.Login(this.loginRequest)
.subscribe({
next: (res:AuthenticationResponse)=>{
if(res.email) {
this.dataStorage.setItem('userDetails', JSON.stringify(res));
this.dataStorage.setItem('token', JSON.stringify(res.token));
this.toastr.info('مرحبا بك مجددا يا ' + res.firstName+" " +res.lastName);
this.router.navigateByUrl('/home');
this
.authService
.Login(this.loginRequest)
.subscribe(
{
next: (res:AuthenticationResponse)=>{
if(res.email) {
this.dataStorage.setItem('userDetails', JSON.stringify(res));
this.dataStorage.setItem('token', JSON.stringify(res.token));
this.toastr.info('مرحبا بك مجددا يا ' + res.firstName+" " +res.lastName);
this.router.navigateByUrl('/home');
} else {
}
},
error: (err)=>{
console.log(err);
this.showErrors(err.errors || ['An unexpected error occurred.']);
// this.router.navigateByUrl('/home');
}
});
}
},
error: (err)=>{
console.log(err);
this.showErrors(err.errors || ['لقد حدث خطاء ما']);
}
});
}
}
private showErrors(errors: string[]): void {
errors.forEach(error => this.toastr.error(error, 'Login Failed'));
}
//#endregion Login handler
//#region Error Show
private showErrors(errors: string[]): void {
errors.forEach(error => this.toastr.error(error, 'Login Failed'));
}
//#endregion Error Show
}
<div class="modal fade" id="addParticipantModal" tabindex="-1" aria-labelledby="addParticipantModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<div class="modal-header">
<h5 class="modal-title" id="addParticipantModalLabel">إضافة مشارك في المشروع</h5>
<button type="button" class="mr-4 ml-4 btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<button type="button" class="mr-4 ml-4 btn-close" (click)="onClose()" ></button>
</div>
<div class="modal-body">
<form [formGroup]="addParticipantForm" (ngSubmit)="onSubmit()">
......@@ -30,9 +28,9 @@
<label for="role" class="form-label">صفة المساهمة</label>
<input type="text" id="role" formControlName="role" class="form-control" required />
</div>
<button type="submit" class="col-4 offset-2 btn btn-success" [disabled]="!addParticipantForm.valid">إضافة المشارك</button>
<button type="submit" class="col-4 m-4 offset-2 btn btn-primary" [disabled]="!addParticipantForm.valid">إضافة المشارك</button>
<div class="col-4 m-4 btn btn-secondary" (click)="onClose()" >إلغاء</div>
</form>
</div>
</div>
</div>
</div>
\ No newline at end of file
......@@ -8,6 +8,7 @@ import { Modal } from 'bootstrap';
import { EmployeeParticipate } from '../../../../employees/models/responses/employeeParticipate';
import { ProjectService } from '../../../services/project.service';
import { ToastrService } from 'ngx-toastr';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'add-participant-modal',
......@@ -28,7 +29,8 @@ export class AddParticipantModalComponent {
private fb: FormBuilder,
private employeeService: EmployeesService,
private projectService : ProjectService,
private toastr :ToastrService
private toastr :ToastrService,
private activeModal: NgbActiveModal
) {
......@@ -60,7 +62,8 @@ export class AddParticipantModalComponent {
)
);
formatter = (x: Employee) => x != undefined ? x.email +" / "+ x.personalInfo?.firstName+" " + x.personalInfo?.lastName : "";
formatter = (x: Employee) => {
return x != undefined && x.personalInfo != undefined ? x.email +" / "+ x.personalInfo!.firstName+" " + x.personalInfo!.lastName : ""};
onEmployeeSelected(employee: Employee) {
debugger
......@@ -74,6 +77,8 @@ export class AddParticipantModalComponent {
const existingEmails = new Set(this.paticipants.map(p => p.employeeId));
return employees.filter(employee => !existingEmails.has(employee.id));
}
onSubmit() {
if (this.addParticipantForm.valid) {
......@@ -94,6 +99,7 @@ export class AddParticipantModalComponent {
next : ()=>{
this.participantAdded.emit(participantData);
this.activeModal.close();
}
......@@ -106,13 +112,8 @@ export class AddParticipantModalComponent {
}
}
onClose():void {
this.activeModal.close();
}
closeModal() {
const modal = document.getElementById('addParticipantModal');
if (modal) {
// Use Bootstrap 5 JavaScript API to hide modal
const bsModal = new Modal(modal);
bsModal.hide();
}
}
}
......@@ -3,6 +3,7 @@ import { EmployeeParticipate } from '../../../../employees/models/responses/empl
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { ProjectService } from '../../../services/project.service';
import { ChangeEmployeeParticipationRequest } from '../../../models/requests/project-requests/ChangeEmployeeParticipationRequest';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'edit-participant-modal',
......@@ -15,7 +16,11 @@ export class EditParticipantModalComponent {
editParticipantForm: FormGroup;
constructor(private fb: FormBuilder, private projectService: ProjectService) {
constructor(
private fb: FormBuilder,
private projectService: ProjectService,
private activeModal : NgbModal
) {
this.editParticipantForm = this.fb.group({
role: ['', Validators.required],
partialTimeRatio: [0, [Validators.required, Validators.min(0)]],
......@@ -50,9 +55,6 @@ export class EditParticipantModalComponent {
}
closeModal() {
const modal = document.getElementById('editParticipantModal');
if (modal) {
(modal as any).modal('hide');
}
this.activeModal.dismissAll();
}
}
......@@ -24,12 +24,7 @@
<button [routerLink]="['/projects',participant.projectId,'history','participationChange',participant.employeeId]" class="btn btn-secondary">التبدلات</button>
</small>
</div>
<div class="col text-center">
<small>
<button [routerLink]="['/reports/contributions',participant.projectId,'employee',participant.employeeId]" class="btn btn-secondary">المساهمات</button>
</small>
</div>
</div>
</div> <!-- /.card-footer -->
......
......@@ -63,7 +63,7 @@
</div>
<!-- .row -->
</div>
<div class="col-md-6 col-lg-4" [routerLink]="['/rerports/history',project.id]">
<div class="col-md-6 col-lg-4" [routerLink]="['/reports/history',project.id]">
<div class="card shadow mb-4">
<div class="card-body file-list">
<div class="d-flex align-items-center">
......
<section *ngIf="participants" class="row">
<add-participant-modal
<!-- <add-participant-modal
[projectId]="projectId"
[paticipants]="participants"
(participantAdded)="onParticipantAdded()"
>
</add-participant-modal>
</add-participant-modal> -->
<div class="row justify-content-center" *ngIf="!isDetailMode">
<div class="col-12">
......@@ -15,9 +15,8 @@
<div class="col-auto">
<button
type="button"
data-bs-toggle="modal"
data-bs-target="#addParticipantModal"
class="btn btn-primary"
(click)="openAddModal()"
>
<span class="fe fe-file-plus fe-12 mr-2"></span>إضافة مشارك
</button>
......@@ -78,16 +77,13 @@
</div>
</div>
<div class="col-8 ">
<div class="small mb-2 d-flex">
</div>
<div class="col-auto">
<div class="col-10">
<button type="button" class="btn m-2 btn-sm btn-primary">استعراض تاريخ تبدلاته </button>
<button type="button" data-bs-toggle="modal" data-bs-target="#editParticipantModal" class="btn m-2 btn-sm btn-secondary">تعديل معلومات المشاركة</button>
<button type="button" data-bs-toggle="modal" data-bs-target="#removeParticipantModal" class="btn m-2 btn-sm btn-danger">إزالة</button>
</div>
<button type="button" [routerLink]="['/reports/contributions',selectedParticipant.projectId,'employee',selectedParticipant.employeeId]" class="btn btn-sm btn-secondary">المساهمات</button>
</div>
</div>
</div> <!-- / .card-body -->
......
......@@ -4,6 +4,10 @@ import { ProjectService } from '../../services/project.service';
import { ActivatedRoute, Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { Modal } from 'bootstrap';
import { NgbActiveModal, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { AddParticipantModalComponent } from '../../components/modals/add-participant-modal/add-participant-modal.component';
import { ModalService } from '../../../core/services/modals/modal.service';
import { NgModel } from '@angular/forms';
@Component({
selector: 'participants-list',
......@@ -21,6 +25,7 @@ export class ParticipantsListComponent {
private projectService :ProjectService,
private toastr : ToastrService,
private route: ActivatedRoute,
private activeModal : NgbModal,
public router :Router
) {
......@@ -33,7 +38,7 @@ export class ParticipantsListComponent {
}
onParticipantAdded(){
this.closeModal('addParticipantModal')
this.activeModal.dismissAll();
this.loadParticipations();
}
......@@ -43,13 +48,14 @@ export class ParticipantsListComponent {
}
onParticipantUpdated(): void {
this.closeModal('editParticipantModal')
this.activeModal.dismissAll();
this.loadParticipations();
}
onParticipantRemoved(): void {
// this.closeModal('removeParticipantModal')
this.activeModal.dismissAll();
this.isDetailMode=false ;
this.closeModal('removeParticipantModal')
this.loadParticipations();
}
......@@ -78,12 +84,35 @@ export class ParticipantsListComponent {
this.isDetailMode=true;
}
openAddModal(): void {
const modalRef = this.activeModal.open(AddParticipantModalComponent );
modalRef.componentInstance.projectId =this.projectId;
modalRef.componentInstance.paticipants = this.participants;
modalRef.componentInstance.participantAdded
.subscribe({
next: ()=>{
this.activeModal.dismissAll();
this.loadParticipations();
}
});
modalRef.result.then((result) => {
if (result) {
// Add the new project to the list
this.loadParticipations();
}
}, (reason) => {
});
}
closeModal(name :string) {
const modal = document.getElementById(name);
if (modal) {
(modal as any).modal('hide');
}
this.activeModal.dismissAll();
}
}
......@@ -31,7 +31,7 @@ import { FinancialSpendingComponent } from './pages/financial-spending/financial
import { FinancialItemComponent } from './components/financial-item/financial-item.component';
import { ReportControllComponent } from './components/project-controll/report-controll/report-controll.component';
import { AddParticipantModalComponent } from './components/modals/add-participant-modal/add-participant-modal.component';
import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
import { NgbModule, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
import { EditParticipantModalComponent } from './components/modals/edit-participant-modal/edit-participant-modal.component';
import { RemoveParticipantModalComponent } from './components/modals/remove-participant-modal/remove-participant-modal.component';
import { ParticipantChangesComponent } from './pages/participant-changes/participant-changes.component';
......@@ -91,6 +91,7 @@ import { EditWeightModalComponent } from './components/step-modals/edit-weight-m
],
imports: [
CommonModule,
NgbModule,
FormsModule,
MatFormFieldModule,
MatCommonModule,
......
......@@ -39,7 +39,7 @@ export class HeaderComponent implements OnInit {
logout() {
this.toastr.info("بانتظارك في المرة القادمة");
this.auth.logou();
this.auth.logout();
this.router.navigate(['/login']);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment