implement refresh token

This commit is contained in:
Fuzi_fauzia 2024-07-16 13:46:58 +07:00
parent fa12fcec50
commit 6b91c937ab
27 changed files with 113 additions and 65 deletions

View File

@ -54,7 +54,8 @@ export class CostManagementComponent implements OnInit {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Cost Management", mainlabel: "Cost Management",
links: [ links: [

View File

@ -30,7 +30,8 @@ export class ModalAddActualComponent {
} }
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
const currentDate = new Date(); const currentDate = new Date();
this.dateCurrent = currentDate.toISOString().slice(0, 7); this.dateCurrent = currentDate.toISOString().slice(0, 7);
this.dateFormat(); this.dateFormat();

View File

@ -30,7 +30,8 @@ export class ModalExportComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
const dateRow = this.convertToUTC7(this.dataRow.endDate) const dateRow = this.convertToUTC7(this.dataRow.endDate)
this.formattedEndDate = dateRow.slice(0, 7); this.formattedEndDate = dateRow.slice(0, 7);
} }

View File

@ -41,7 +41,8 @@ export class AddEditDeviceComponent implements OnInit{
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.route.params.subscribe(params => { this.route.params.subscribe(params => {
const id = params['id']; const id = params['id'];
this.deviceId = id; this.deviceId = id;
@ -79,27 +80,27 @@ export class AddEditDeviceComponent implements OnInit{
const dataCategory = data.data.find( const dataCategory = data.data.find(
(item) => item.name === "master_category" (item) => item.name === "master_category"
).headerDetailParam; ).headerDetailParam;
this.dataMasterCategori = dataCategory.filter(item => item.statusName.toLowerCase() === "aktif") this.dataMasterCategori = dataCategory.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71")
const dataVoltage = data.data.find( const dataVoltage = data.data.find(
(item) => item.name === "master_voltage" (item) => item.name === "master_voltage"
).headerDetailParam; ).headerDetailParam;
this.dataMasterVoltage = dataVoltage.filter(item => item.statusName.toLowerCase() === "aktif") this.dataMasterVoltage = dataVoltage.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71")
const dataType = data.data.find( const dataType = data.data.find(
(item) => item.name === "master_type" (item) => item.name === "master_type"
).headerDetailParam; ).headerDetailParam;
this.dataMasterType = dataType.filter(item => item.statusName.toLowerCase() === "aktif") this.dataMasterType = dataType.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71")
const dataDuration = data.data.find( const dataDuration = data.data.find(
(item) => item.name === "master_duration" (item) => item.name === "master_duration"
).headerDetailParam; ).headerDetailParam;
this.dataMasterDuration = dataDuration.filter(item => item.statusName.toLowerCase() === "aktif") this.dataMasterDuration = dataDuration.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71")
const dataStatus = data.data.find( const dataStatus = data.data.find(
(item) => item.name === "master_status" (item) => item.name === "master_status"
).headerDetailParam; ).headerDetailParam;
this.dataMasterStatus = dataStatus.filter(item => item.statusName.toLowerCase() === "aktif") this.dataMasterStatus = dataStatus.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71")
}); });
} }

View File

@ -38,7 +38,8 @@ export class DeviceControlComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Device", mainlabel: "Device",
links: [ links: [

View File

@ -53,7 +53,8 @@ export class DeviceComponent implements OnInit {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Device", mainlabel: "Device",
links: [ links: [

View File

@ -41,7 +41,8 @@ export class AddEditListComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.route.data.subscribe((data) => { this.route.data.subscribe((data) => {
this.mode = data.mode; this.mode = data.mode;
}); });
@ -211,7 +212,7 @@ export class AddEditListComponent {
const dataStatus = data.data.find( const dataStatus = data.data.find(
(item) => item.name === "master_status" (item) => item.name === "master_status"
).headerDetailParam; ).headerDetailParam;
this.dataMasterStatus = dataStatus.filter(item => item.statusName.toLowerCase() === "aktif") this.dataMasterStatus = dataStatus.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71")
}); });
} }

View File

@ -25,7 +25,8 @@ export class ListMonitoringComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Cost Management", mainlabel: "Cost Management",
links: [ links: [

View File

@ -27,7 +27,8 @@ export class AddEditMasterComponent implements OnInit {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.createForm(); this.createForm();
this.dataListMaster(); this.dataListMaster();
if (this.mode === "add") { if (this.mode === "add") {
@ -78,7 +79,7 @@ export class AddEditMasterComponent implements OnInit {
const dataCategory = data.data.find( const dataCategory = data.data.find(
(item) => item.name === "master_status" (item) => item.name === "master_status"
).headerDetailParam; ).headerDetailParam;
this.dataMasterStatus = dataCategory.filter(item => item.statusName.toLowerCase() === "aktif"); this.dataMasterStatus = dataCategory.filter(item => item.statusName.toLowerCase() === "aktif" || item.status.toLowerCase() === "71" || item.status.toLowerCase() === "71");
}); });
} }

View File

@ -27,7 +27,8 @@ export class AddEditMasterBuildingComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.createForm(); this.createForm();
this.listDataStatus(); this.listDataStatus();
if (this.mode === "add") { if (this.mode === "add") {

View File

@ -30,7 +30,8 @@ export class MasterBuildingComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Master Building", mainlabel: "Master Building",
links: [ links: [

View File

@ -33,7 +33,6 @@ export class MasterCategoryComponent implements OnInit {
) {} ) {}
ngOnInit() { ngOnInit() {
// this.authService.checkTokenAndRedirect();
this.authService.startTokenCheck(); this.authService.startTokenCheck();
this.authService.startTrackingActivity(); this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {

View File

@ -30,7 +30,6 @@ export class MasterDurationUseComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
// this.authService.checkTokenAndRedirect();
this.authService.startTokenCheck(); this.authService.startTokenCheck();
this.authService.startTrackingActivity(); this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {

View File

@ -30,7 +30,8 @@ export class MasterFloorComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Master Floor", mainlabel: "Master Floor",
links: [ links: [

View File

@ -30,7 +30,8 @@ export class MasterRoleComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Master Role", mainlabel: "Master Role",
links: [ links: [

View File

@ -30,7 +30,8 @@ export class AddEditMasterRoomComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.createForm(); this.createForm();
this.listDataStatus(); this.listDataStatus();
this.listDataBuilding(); this.listDataBuilding();

View File

@ -27,7 +27,8 @@ export class MasterRoomComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Master Room", mainlabel: "Master Room",
links: [ links: [

View File

@ -30,7 +30,8 @@ export class MasterStatusComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Master Status", mainlabel: "Master Status",
links: [ links: [

View File

@ -30,7 +30,8 @@ export class MasterTypeComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Master Type", mainlabel: "Master Type",
links: [ links: [

View File

@ -30,7 +30,8 @@ export class MasterVoltageComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Master Voltage", mainlabel: "Master Voltage",
links: [ links: [

View File

@ -27,7 +27,8 @@ export class BuildingComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.breadcrumb = { this.breadcrumb = {
mainlabel: "Dashboard", mainlabel: "Dashboard",
links: [ links: [

View File

@ -37,7 +37,8 @@ export class ControlDeviceSeemoreComponent {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.route.params.subscribe((params) => { this.route.params.subscribe((params) => {
const buildingId = params["id"]; const buildingId = params["id"];
this.paramsId = buildingId ? buildingId: 0; this.paramsId = buildingId ? buildingId: 0;

View File

@ -140,7 +140,8 @@ export class DetailComponent {
} }
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.route.data.subscribe((data) => { this.route.data.subscribe((data) => {
this.mode = data.mode; this.mode = data.mode;
}); });

View File

@ -25,7 +25,8 @@ export class RoomComponent implements OnInit {
) {} ) {}
ngOnInit() { ngOnInit() {
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.route.data.subscribe((data) => { this.route.data.subscribe((data) => {
this.mode = data.mode; this.mode = data.mode;
console.log(this.mode); console.log(this.mode);

View File

@ -1,7 +1,15 @@
// src/app/services/login.service.ts // src/app/services/login.service.ts
import { Injectable, NgZone } from "@angular/core"; import { Injectable, NgZone } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http"; import { HttpClient, HttpHeaders } from "@angular/common/http";
import { BehaviorSubject, Observable, of, Subject, timer, fromEvent, merge } from "rxjs"; import {
BehaviorSubject,
Observable,
of,
Subject,
timer,
fromEvent,
merge,
} from "rxjs";
import { jwtDecode } from "jwt-decode"; import { jwtDecode } from "jwt-decode";
import { Router } from "@angular/router"; import { Router } from "@angular/router";
import { switchMap, debounceTime, mapTo, startWith } from "rxjs/operators"; import { switchMap, debounceTime, mapTo, startWith } from "rxjs/operators";
@ -93,11 +101,11 @@ export class LoginService {
const tokenData = localStorage.getItem(this.tokenKey); const tokenData = localStorage.getItem(this.tokenKey);
if (tokenData) { if (tokenData) {
const tokenInfo = JSON.parse(tokenData); const tokenInfo = JSON.parse(tokenData);
const decodedToken = jwtDecode<CustomJwtPayload>(tokenInfo.refresh_token); const decodedToken = jwtDecode<CustomJwtPayload>(tokenInfo.access_token);
const expiryDate = decodedToken.exp * 1000; const expiryDate = decodedToken.exp * 1000;
const now = new Date().getTime(); const now = new Date().getTime();
const timeLeft = expiryDate - now; const timeLeft = expiryDate - now;
return of(timeLeft <= 5 * 60 * 1000); return of(timeLeft <= 2 * 60 * 1000);
} }
return of(true); return of(true);
} }
@ -108,12 +116,14 @@ export class LoginService {
this.authService.doLogout().then( this.authService.doLogout().then(
() => { () => {
this.router.navigate(["/login"]); this.router.navigate(["/login"]);
window.location.reload();
}, },
(err) => { (err) => {
console.log(err); console.log(err);
} }
); );
this.router.navigate(["/login"]); this.router.navigate(["/login"]);
window.location.reload();
} else { } else {
console.log("Token is valid, continuing..."); console.log("Token is valid, continuing...");
} }
@ -122,29 +132,43 @@ export class LoginService {
startTokenCheck(): void { startTokenCheck(): void {
timer(0, 2 * 60 * 1000) // Check every 5 minutes timer(0, 2 * 60 * 1000) // Check every 5 minutes
.pipe( .pipe(switchMap(() => this.isTokenExpired()))
switchMap(() => this.isTokenExpired())
)
.subscribe((isExpired) => { .subscribe((isExpired) => {
// console.log(isExpired);
if (isExpired) { if (isExpired) {
this.activity$.subscribe(isActive => { this.activity$.subscribe((isActive) => {
// console.log(isActive);
if (!isActive) { if (!isActive) {
this.checkTokenAndRedirect(); this.checkTokenAndRedirect();
} else { } else {
console.log("Token expired but user is active. Refresh token not implemented."); console.log(
this.updateUserProfile(this.currentUser.refresh_token) "Token expired but user is active. Refresh token not implemented."
.subscribe((resp) => { );
const decodedToken = jwtDecode<CustomJwtPayload>(resp.access_token);
localStorage.setItem("account_info", JSON.stringify(decodedToken)); this.updateUserProfile(this.currentUser.refresh_token).subscribe(
(resp) => {
const decodedToken = jwtDecode<CustomJwtPayload>(
resp.access_token
);
localStorage.setItem(
"account_info",
JSON.stringify(decodedToken)
);
const userProfile = { const userProfile = {
access_token: resp.access_token, access_token: resp.access_token,
refresh_token: resp.refresh_token, refresh_token: resp.refresh_token,
displayName: decodedToken.name, displayName: decodedToken.name,
buildingId: 4, buildingId: 4,
}; };
localStorage.setItem("currentUser", JSON.stringify(userProfile)); localStorage.setItem(
// window.location.reload(); "currentUser",
}); JSON.stringify(userProfile)
);
window.location.reload();
}
);
} }
}); });
} }
@ -154,22 +178,24 @@ export class LoginService {
startTrackingActivity(): void { startTrackingActivity(): void {
this.ngZone.runOutsideAngular(() => { this.ngZone.runOutsideAngular(() => {
const activityEvents$ = merge( const activityEvents$ = merge(
fromEvent(window, 'mousemove'), fromEvent(window, "mousemove"),
fromEvent(window, 'click'), fromEvent(window, "click"),
fromEvent(window, 'keypress'), fromEvent(window, "keypress"),
fromEvent(window, 'scroll') fromEvent(window, "scroll")
); );
activityEvents$ activityEvents$
.pipe( .pipe(
startWith(null), startWith(null),
switchMap(() => merge( switchMap(() =>
merge(
timer(0).pipe(mapTo(true)), timer(0).pipe(mapTo(true)),
timer(5 * 60 * 1000).pipe(mapTo(false)) // 5 minutes of inactivity timer(5 * 60 * 1000).pipe(mapTo(false)) // 5 minutes of inactivity
)), )
),
debounceTime(300) debounceTime(300)
) )
.subscribe(active => { .subscribe((active) => {
this.ngZone.run(() => this.activitySubject.next(active)); this.ngZone.run(() => this.activitySubject.next(active));
}); });
}); });

View File

@ -61,7 +61,8 @@ export class ProfilInformationComponent {
ngOnInit(): void { ngOnInit(): void {
this.storedData = JSON.parse(localStorage.getItem("account_info")); this.storedData = JSON.parse(localStorage.getItem("account_info"));
this.currentUser = JSON.parse(localStorage.getItem("currentUser")); this.currentUser = JSON.parse(localStorage.getItem("currentUser"));
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.profilInfo = this.formBuilder.group({ this.profilInfo = this.formBuilder.group({
firstName: ["", Validators.required], firstName: ["", Validators.required],

View File

@ -40,7 +40,8 @@ export class UpdatePasswordComponent {
ngOnInit(): void { ngOnInit(): void {
this.storedData = JSON.parse(localStorage.getItem("account_info")); this.storedData = JSON.parse(localStorage.getItem("account_info"));
this.authService.checkTokenAndRedirect(); this.authService.startTokenCheck();
this.authService.startTrackingActivity();
this.profilInfo = this.formBuilder.group({ this.profilInfo = this.formBuilder.group({
userid: this.storedData.sub, userid: this.storedData.sub,
currentPass: [""], currentPass: [""],