Commit b75eec55 by Ooh-Ao

tokenservice httpinceptor

parent aff91f9f
...@@ -5,11 +5,7 @@ ...@@ -5,11 +5,7 @@
<div class="header-left"> <div class="header-left">
<!-- Navigation Toggle --> <!-- Navigation Toggle -->
<div class=""> <div class="">
<button <button type="button" class="sidebar-toggle !w-100 !h-100" (click)="toggleSidebar()">
type="button"
class="sidebar-toggle !w-100 !h-100"
(click)="toggleSidebar()"
>
<span class="sr-only">Toggle Navigation</span> <span class="sr-only">Toggle Navigation</span>
<i class="ri-arrow-right-circle-line header-icon"></i> <i class="ri-arrow-right-circle-line header-icon"></i>
</button> </button>
...@@ -41,29 +37,17 @@ ...@@ -41,29 +37,17 @@
<div class="header-right"> <div class="header-right">
<div class="responsive-headernav"> <div class="responsive-headernav">
<div class="header-nav-right"> <div class="header-nav-right">
<div <div class="header-country hs-dropdown ti-dropdown hidden sm:block"
class="header-country hs-dropdown ti-dropdown hidden sm:block" data-hs-dropdown-placement="bottom-right">
data-hs-dropdown-placement="bottom-right" <button id="dropdown-flag" type="button"
> class="hs-dropdown-toggle ti-dropdown-toggle p-0 flex-shrink-0 h-[2.375rem] w-[2.375rem] border-0 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10">
<button <i class="flag-icon flag-icon-th h-[1.375rem] w-[1.375rem]"></i>
id="dropdown-flag"
type="button"
class="hs-dropdown-toggle ti-dropdown-toggle p-0 flex-shrink-0 h-[2.375rem] w-[2.375rem] border-0 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10"
>
<i class="flag-icon flag-icon-th h-[1.375rem] w-[1.375rem]"></i>
</button> </button>
<div <div class="hs-dropdown-menu ti-dropdown-menu min-w-[10rem]" aria-labelledby="dropdown-flag">
class="hs-dropdown-menu ti-dropdown-menu min-w-[10rem]" <div class="ti-dropdown-divider divide-y divide-gray-200 dark:divide-white/10">
aria-labelledby="dropdown-flag"
>
<div
class="ti-dropdown-divider divide-y divide-gray-200 dark:divide-white/10"
>
<div class="py-2 first:pt-0 last:pb-0"> <div class="py-2 first:pt-0 last:pb-0">
<div class="ti-dropdown-item"> <div class="ti-dropdown-item">
<div <div class="flex items-center space-x-2 rtl:space-x-reverse w-full">
class="flex items-center space-x-2 rtl:space-x-reverse w-full"
>
<div class="h-[1.375rem] w-[1.375rem] rounded-sm"> <div class="h-[1.375rem] w-[1.375rem] rounded-sm">
<i class="flag-icon flag-icon-th"></i> <i class="flag-icon flag-icon-th"></i>
</div> </div>
...@@ -73,9 +57,7 @@ ...@@ -73,9 +57,7 @@
</div> </div>
</div> </div>
<div class="ti-dropdown-item"> <div class="ti-dropdown-item">
<div <div class="flex items-center space-x-2 rtl:space-x-reverse w-full">
class="flex items-center space-x-2 rtl:space-x-reverse w-full"
>
<div class="h-[1.375rem] w-[1.375rem] rounded-sm"> <div class="h-[1.375rem] w-[1.375rem] rounded-sm">
<i class="flag-icon flag-icon-us"></i> <i class="flag-icon flag-icon-us"></i>
</div> </div>
...@@ -84,9 +66,9 @@ ...@@ -84,9 +66,9 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
...@@ -681,40 +663,25 @@ ...@@ -681,40 +663,25 @@
</div> </div>
</div> </div>
</div> --> </div> -->
<div <div class="header-profile hs-dropdown ti-dropdown" data-hs-dropdown-placement="bottom-right">
class="header-profile hs-dropdown ti-dropdown" <button id="dropdown-profile" type="button"
data-hs-dropdown-placement="bottom-right" class="hs-dropdown-toggle ti-dropdown-toggle gap-2 p-0 flex-shrink-0 h-8 w-8 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10">
> <img class="inline-block rounded-full ring-2 ring-white dark:ring-white/10"
<button src="./assets/img/users/1.jpg" alt="Image Description" />
id="dropdown-profile"
type="button"
class="hs-dropdown-toggle ti-dropdown-toggle gap-2 p-0 flex-shrink-0 h-8 w-8 rounded-full shadow-none focus:ring-gray-400 text-xs dark:focus:ring-white/10"
>
<img
class="inline-block rounded-full ring-2 ring-white dark:ring-white/10"
src="./assets/img/users/1.jpg"
alt="Image Description"
/>
</button> </button>
<div <div class="hs-dropdown-menu ti-dropdown-menu border-0 w-[20rem]" aria-labelledby="dropdown-profile">
class="hs-dropdown-menu ti-dropdown-menu border-0 w-[20rem]"
aria-labelledby="dropdown-profile"
>
<div class="ti-dropdown-header !bg-primary flex"> <div class="ti-dropdown-header !bg-primary flex">
<div class="ltr:mr-3 rtl:ml-3"> <div class="ltr:mr-3 rtl:ml-3">
<img <img class="avatar shadow-none rounded-full !ring-transparent" src="./assets/img/users/1.jpg"
class="avatar shadow-none rounded-full !ring-transparent" alt="profile-img" />
src="./assets/img/users/1.jpg"
alt="profile-img"
/>
</div> </div>
<div> <div>
<p class="ti-dropdown-header-title !text-white"> <p class="ti-dropdown-header-title !text-white">
{{this.employeeProfile.thFullName?this.employeeProfile.thFullName:''}} {{this.employeeProfile.thFullName?this.employeeProfile.thFullName:''}}
</p> </p>
<p class="ti-dropdown-header-content !text-white/50 " style="font-size: 12px;"> <p class="ti-dropdown-header-content !text-white/50 " style="font-size: 12px;">
{{tokenService.getUser().iss?tokenService.getUser().iss:''}} {{tokenService.getUserData().position?tokenService.getUserData().position:'-'}}
</p> </p>
</div> </div>
</div> </div>
...@@ -750,12 +717,9 @@ ...@@ -750,12 +717,9 @@
</div> </div>
</div> </div>
<div class="switcher-icon"> <div class="switcher-icon">
<button <button aria-label="button" type="button"
aria-label="button"
type="button"
class="hs-dropdown-toggle inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-gray-100 hover:bg-gray-200 text-gray-500 align-middle focus:outline-none focus-visible:outline-none focus:ring-0 focus:ring-gray-400 focus:ring-offset-0 focus:ring-offset-white transition-all text-xs dark:bg-bgdark dark:hover:bg-black/20 dark:text-white/70 dark:hover:text-white dark:focus:ring-white/10 dark:focus:ring-offset-white/10" class="hs-dropdown-toggle inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-gray-100 hover:bg-gray-200 text-gray-500 align-middle focus:outline-none focus-visible:outline-none focus:ring-0 focus:ring-gray-400 focus:ring-offset-0 focus:ring-offset-white transition-all text-xs dark:bg-bgdark dark:hover:bg-black/20 dark:text-white/70 dark:hover:text-white dark:focus:ring-white/10 dark:focus:ring-offset-white/10"
data-hs-overlay="#hs-overlay-switcher" data-hs-overlay="#hs-overlay-switcher">
>
<i class="ri-settings-5-line header-icon animate-spin"></i> <i class="ri-settings-5-line header-icon animate-spin"></i>
</button> </button>
</div> </div>
...@@ -778,13 +742,8 @@ ...@@ -778,13 +742,8 @@
<div class="search-btn"> <div class="search-btn">
<i class="ri ri-search-2-line search-btn-icon"></i> <i class="ri ri-search-2-line search-btn-icon"></i>
</div> </div>
<input <input type="text" id="icon" name="icon" class="py-2 ltr:pl-11 rtl:pr-11 ti-form-input focus:z-10"
type="text" placeholder="Search by No. or Name" />
id="icon"
name="icon"
class="py-2 ltr:pl-11 rtl:pr-11 ti-form-input focus:z-10"
placeholder="Search by No. or Name"
/>
<div class="voice-search"> <div class="voice-search">
<i class="ri ri-mic-2-line voice-btn-icon"></i> <i class="ri ri-mic-2-line voice-btn-icon"></i>
</div> </div>
...@@ -794,140 +753,72 @@ ...@@ -794,140 +753,72 @@
</div> </div>
</div> </div>
<div class="mt-5"> <div class="mt-5">
<p <p class="font-semibold text-[13px] text-gray-400 dark:text-gray-200 mb-2">
class="font-semibold text-[13px] text-gray-400 dark:text-gray-200 mb-2"
>
Are You Looking For... Are You Looking For...
</p> </p>
<div <div class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1" id="badge1">
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1" <a routerLink="/page/team" class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
id="badge1" <span class="inline-block text-secondary mr-1"><i class="ri ri-user-line text-sm"></i></span>
>
<a
routerLink="/page/team"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-user-line text-sm"></i
></span>
Team Team
</a> </a>
<a <a href="javascript:void(0);"
href="javascript:void(0);"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white" class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
(click)="removeRow('badge1')" (click)="removeRow('badge1')">
>
<span class="sr-only">Remove badge</span> <span class="sr-only">Remove badge</span>
<svg <svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
class="h-4 w-4 hover:fill-white" fill="currentColor" viewBox="0 0 16 16">
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path <path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
></path> </path>
</svg> </svg>
</a> </a>
</div> </div>
<div <div id="badge2" class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1">
id="badge2" <a routerLink="/form-module/form-elements"
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1" class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
> <span class="inline-block text-secondary mr-1"><i class="ri ri-file-text-line text-sm"></i></span>
<a
routerLink="/form-module/form-elements"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-file-text-line text-sm"></i
></span>
Forms Forms
</a> </a>
<a <a href="javascript:void(0);" (click)="removeRow('badge2')"
href="javascript:void(0);" class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white">
(click)="removeRow('badge2')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
>
<span class="sr-only">Remove badge</span> <span class="sr-only">Remove badge</span>
<svg <svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
class="h-4 w-4 hover:fill-white" fill="currentColor" viewBox="0 0 16 16">
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path <path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
></path> </path>
</svg> </svg>
</a> </a>
</div> </div>
<div <div id="badge3" class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1">
id="badge3" <a routerLink="/maps/leaflet" class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1" <span class="inline-block text-secondary mr-1"><i class="ri ri-map-pin-line text-sm"></i></span>
>
<a
routerLink="/maps/leaflet"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-map-pin-line text-sm"></i
></span>
Maps Maps
</a> </a>
<a <a href="javascript:void(0);" (click)="removeRow('badge3')"
href="javascript:void(0);" class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white">
(click)="removeRow('badge3')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
>
<span class="sr-only">Remove badge</span> <span class="sr-only">Remove badge</span>
<svg <svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
class="h-4 w-4 hover:fill-white" fill="currentColor" viewBox="0 0 16 16">
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path <path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
></path> </path>
</svg> </svg>
</a> </a>
</div> </div>
<div <div id="badge4" class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1">
id="badge4" <a routerLink="/widgets" class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse">
class="badge rounded-sm bg-secondary/20 text-secondary relative header-box me-1" <span class="inline-block text-secondary mr-1"><i class="ri ri-server-line text-sm"></i></span>
>
<a
routerLink="/widgets"
class="w-full my-auto items-center flex space-x-2 rtl:space-x-reverse"
>
<span class="inline-block text-secondary mr-1"
><i class="ri ri-server-line text-sm"></i
></span>
Widgets Widgets
</a> </a>
<a <a href="javascript:void(0);" (click)="removeRow('badge4')"
href="javascript:void(0);" class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white">
(click)="removeRow('badge4')"
class="header-remove-btn flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-secondary hover:bg-secondary hover:text-secondary focus:outline-none focus:bg-secondary focus:text-white"
>
<span class="sr-only">Remove badge</span> <span class="sr-only">Remove badge</span>
<svg <svg class="h-4 w-4 hover:fill-white" xmlns="http://www.w3.org/2000/svg" width="16" height="16"
class="h-4 w-4 hover:fill-white" fill="currentColor" viewBox="0 0 16 16">
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
viewBox="0 0 16 16"
>
<path <path
d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z">
></path> </path>
</svg> </svg>
</a> </a>
</div> </div>
...@@ -936,57 +827,33 @@ ...@@ -936,57 +827,33 @@
<p class="font-semibold text-sm text-gray-500 mb-2"> <p class="font-semibold text-sm text-gray-500 mb-2">
Recent Search : Recent Search :
</p> </p>
<div <div id="not1"
id="not1" class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box">
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box" <a routerLink="/advanced/notifications" (click)="removetheModal()" class="w-full my-auto items-center flex">
>
<a
routerLink="/advanced/notifications" (click)="removetheModal()"
class="w-full my-auto items-center flex"
>
<span class="text-sm">Notifications</span> <span class="text-sm">Notifications</span>
</a> </a>
<a <a aria-label="anchor" href="javascript:void(0);"
aria-label="anchor" class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn">
href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn"
>
<i class="ri-close-line" (click)="removeRow('not1')"></i> <i class="ri-close-line" (click)="removeRow('not1')"></i>
</a> </a>
</div> </div>
<div <div id="not2"
id="not2" class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box">
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 mb-1 relative header-box" <a routerLink="/components/alerts" (click)="removetheModal()" class="w-full my-auto items-center flex">
>
<a
routerLink="/components/alerts" (click)="removetheModal()"
class="w-full my-auto items-center flex"
>
<span class="text-sm">Alerts</span> <span class="text-sm">Alerts</span>
</a> </a>
<a <a aria-label="anchor" href="javascript:void(0);"
aria-label="anchor" class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn">
href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn"
>
<i class="ri-close-line" (click)="removeRow('not2')"></i> <i class="ri-close-line" (click)="removeRow('not2')"></i>
</a> </a>
</div> </div>
<div <div id="not3"
id="not3" class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 relative header-box">
class="p-2 border dark:border-white/10 rounded-sm flex items-center text-gray-500 relative header-box" <a routerLink="/tables/basictables" (click)="removetheModal()" class="w-full my-auto items-center flex">
>
<a
routerLink="/tables/basictables" (click)="removetheModal()"
class="w-full my-auto items-center flex"
>
<span class="text-sm">Tables</span> <span class="text-sm">Tables</span>
</a> </a>
<a <a aria-label="anchor" href="javascript:void(0);"
aria-label="anchor" class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn">
href="javascript:void(0);"
class="ltr:ml-auto rtl:mr-auto flex-shrink-0 h-4 w-4 inline-flex items-center justify-center rounded-full text-gray-500 focus:outline-none header-remove-btn"
>
<i class="ri-close-line" (click)="removeRow('not3')"></i> <i class="ri-close-line" (click)="removeRow('not3')"></i>
</a> </a>
</div> </div>
...@@ -994,16 +861,10 @@ ...@@ -994,16 +861,10 @@
</div> </div>
<div class="ti-modal-footer"> <div class="ti-modal-footer">
<div class="inline-flex rounded-md shadow-sm"> <div class="inline-flex rounded-md shadow-sm">
<button <button type="button" class="ti-btn-group py-1 ti-btn-soft-primary dark:border-white/10">
type="button"
class="ti-btn-group py-1 ti-btn-soft-primary dark:border-white/10"
>
Search Search
</button> </button>
<button <button type="button" class="ti-btn-group py-1 ti-btn-primary dark:border-white/10">
type="button"
class="ti-btn-group py-1 ti-btn-primary dark:border-white/10"
>
Clear Recents Clear Recents
</button> </button>
</div> </div>
......
...@@ -10,23 +10,15 @@ import { environment } from 'src/environments/environment'; ...@@ -10,23 +10,15 @@ import { environment } from 'src/environments/environment';
}) })
export class AuthService { export class AuthService {
authState: any; authState: any;
api = "/auth" apiBaseUrl = "/auth";
urlApi = environment.baseUrl + this.api
constructor(private router: Router, private http: HttpClient) {
constructor( private router: Router, private http: HttpClient) {
} }
refreshToken(): Observable<{ accessToken: string; refreshToken: string }> { refreshToken(token: string) {
return this.http.post<{ accessToken: string; refreshToken: string }>( return this.http.post<any>(this.apiBaseUrl + "/refresh-token", {
`${this.urlApi}/refresh-token`, "refreshToken": token
{ refreshToken: sessionStorage.getItem('refreshToken') } });
).pipe(
tap(response => {
sessionStorage.setItem('accessToken', response.accessToken);
sessionStorage.setItem('refreshToken', response.refreshToken);
})
);
} }
get isUserAnonymousLoggedIn(): boolean { get isUserAnonymousLoggedIn(): boolean {
...@@ -53,17 +45,18 @@ export class AuthService { ...@@ -53,17 +45,18 @@ export class AuthService {
} }
} }
loginWithUserPass(username: string, password: string): Observable<{ accessToken: string ,refreshToken:string}> { loginWithUserPass(username: string, password: string): Observable<{ accessToken: string, refreshToken: string }> {
const body = { const body = {
username: username, username: username,
password: password password: password
} }
return this.http.post<{ accessToken: string, refreshToken: string }>(this.urlApi + "/login", body) return this.http.post<{ accessToken: string, refreshToken: string }>(this.apiBaseUrl + "/login", body)
} }
logout(){
logout() {
sessionStorage.clear() sessionStorage.clear()
localStorage.clear() localStorage.clear()
this.router.navigate(['/auth/login']); this.router.navigate(['/auth/login']);
} }
} }
...@@ -9,91 +9,80 @@ import { ...@@ -9,91 +9,80 @@ import {
import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; import { BehaviorSubject, Observable, of, throwError } from 'rxjs';
import { catchError, filter, switchMap, take, tap } from 'rxjs/operators'; import { catchError, filter, switchMap, take, tap } from 'rxjs/operators';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { environment } from 'src/environments/environment';
import { TokenService } from './token.service';
const TOKEN_HEADER_KEY = 'Authorization';
@Injectable() @Injectable()
export class HttpRequestInterceptor { export class HttpRequestInterceptor {
private isRefreshing = false; private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<string | null> = new BehaviorSubject<string | null>(null); private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
private responseCache = new Map<string, any>(); // ใช้เก็บ cache ของ response constructor(private tokenService: TokenService, private authService: AuthService) { }
constructor(private authService: AuthService) { }
// intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// if (req.url.startsWith("./") || !sessionStorage.getItem("accessToken")) {
// return next.handle(req);
// } else {
// const authHeader = 'Bearer ' + sessionStorage.getItem("accessToken")
// const overideReq = {
// headers: req.headers.set('Authorization', authHeader),
// url: req.url,
// };
// const authReq = req.clone(overideReq);
// return next.handle(authReq).pipe(tap(response => {
// this.responseCache.set(req.urlWithParams, response)
// }));
// }
// }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.includes('/api/auth/refresh-token') || req.url.startsWith('./') || !sessionStorage.getItem('accessToken')) { if (req.url.startsWith("./")) {
return next.handle(req); return next.handle(req);
} else {
let authReq = req;
const fullUrl = req.url.startsWith("http") ? req.url : environment.baseUrl + req.url;
const token = this.tokenService.getToken()
if (token != null && !req.url.includes("/refresh-token")) {
authReq = this.addTokenHeader(req, token ,fullUrl);
}else{
const overideReq = {
url: fullUrl,
};
authReq = req.clone(overideReq);
}
return next.handle(authReq).pipe(catchError(error => {
if (error instanceof HttpErrorResponse && error.status === 403 && !fullUrl.includes("login")) {
return this.handle403Error(authReq, next ,fullUrl);
}
return throwError(error);
}));
} }
const authHeader = 'Bearer ' + sessionStorage.getItem('accessToken');
const clonedReq = req.clone({
headers: req.headers.set('Authorization', authHeader)
});
return next.handle(clonedReq).pipe(
tap(response => {
this.responseCache.set(req.urlWithParams, response); // เก็บ response cache
}),
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
return this.handle401Error(req, next);
}
return throwError(() => error);
})
);
} }
private handle401Error(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { private handle403Error(request: HttpRequest<any>, next: HttpHandler , fullUrl : string) {
if (this.isRefreshing) { if (!this.isRefreshing) {
return this.refreshTokenSubject.pipe(
filter(token => token !== null),
take(1),
switchMap(token => {
const clonedReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${token}`)
});
return next.handle(clonedReq);
})
);
} else {
this.isRefreshing = true; this.isRefreshing = true;
this.refreshTokenSubject.next(null); this.refreshTokenSubject.next(null);
return this.authService.refreshToken().pipe( const token = this.tokenService.getRefreshToken();
switchMap(newTokens => {
this.isRefreshing = false;
this.refreshTokenSubject.next(newTokens.accessToken);
const clonedReq = req.clone({ if (token)
headers: req.headers.set('Authorization', `Bearer ${newTokens.accessToken}`) return this.authService.refreshToken(token.replace("Bearer ","")).pipe(
}); switchMap((token: any) => {
return next.handle(clonedReq); this.isRefreshing = false;
}), this.tokenService.saveToken(token.accessToken);
catchError(err => { this.tokenService.saveRefreshToken(token.refreshToken);
this.isRefreshing = false; this.refreshTokenSubject.next(token.accessToken);
this.authService.logout();
return throwError(() => new Error('Session expired, please log in again')); return next.handle(this.addTokenHeader(request, token.accessToken ,fullUrl));
}) }),
); catchError((err) => {
this.isRefreshing = false;
this.tokenService.signOut();
return throwError(err);
})
);
} }
}
} return this.refreshTokenSubject.pipe(
filter(token => token !== null),
take(1),
switchMap((token) => next.handle(this.addTokenHeader(request, token ,fullUrl)))
);
}
private addTokenHeader(request: HttpRequest<any>, token: string ,fullUrl :string) {
/* for Spring Boot back-end */
// return request.clone({ headers: request.headers.set(TOKEN_HEADER_KEY, 'Bearer ' + token) });
/* for Node.js Express back-end */
return request.clone({ headers: request.headers.set(TOKEN_HEADER_KEY, token) , url : fullUrl });
}
}
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { EmployeeModel, MyEmployeeModel } from '../model/employee.model';
import { Router } from '@angular/router';
import { UserModel } from '../model/user.model';
const TOKEN_KEY = 'auth-token';
const REFRESHTOKEN_KEY = 'auth-refreshtoken';
const USER_KEY = 'auth-user';
const USER_DATA_KEY = 'auth-user-data';
export class UserLoginModel {
public username: string = "";
public accessToken: string = "";
public refreshToken: string = "";
}
const TOKEN_KEY = 'accessToken';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: "root",
}) })
export class TokenService { export class TokenService {
constructor(private router: Router) { }
constructor() { signOut(): void {
window.localStorage.clear();
localStorage.clear();
this.router.navigate(["/auth/splash"]);
} }
public saveToken(token: string): void {
window.localStorage.removeItem(TOKEN_KEY);
window.localStorage.setItem(TOKEN_KEY, token);
const user = this.getUser();
if (user.accessToken) {
this.saveUser({ ...user, accessToken: token });
}
}
public getUser(): any { public saveUser(user: any): void {
const user = this.decodeJWT(window.sessionStorage.getItem(TOKEN_KEY)!) window.localStorage.removeItem(USER_KEY);
window.localStorage.setItem(USER_KEY, JSON.stringify(user));
}
public getUser(): UserLoginModel {
const user = window.localStorage.getItem(USER_KEY);
if (user) { if (user) {
return user; return JSON.parse(user);
} }
return ; return new UserLoginModel();
}
public getToken(): string | null {
return window.localStorage.getItem(TOKEN_KEY);
} }
decodeJWT(token: string) { public saveRefreshToken(token: string): void {
let base64Url = token.split('.')[1]; // ดึงส่วนที่เป็น Payload window.localStorage.removeItem(REFRESHTOKEN_KEY);
let base64 = base64Url.replace('-', '+').replace('_', '/'); // แก้ไข base64 ให้ถูกต้อง window.localStorage.setItem(REFRESHTOKEN_KEY, token);
let jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
} }
public getRefreshToken(): string | null {
return window.localStorage.getItem(REFRESHTOKEN_KEY);
}
public saveUserData(user: string): void {
window.localStorage.removeItem(USER_DATA_KEY);
window.localStorage.setItem(USER_DATA_KEY, user);
}
public getUserData(): EmployeeModel {
// return window.localStorage.getItem(USER_DATA_KEY);
const user = window.localStorage.getItem(USER_DATA_KEY);
if (user) {
return new MyEmployeeModel(JSON.parse(user));
}
return new MyEmployeeModel();
}
} }
...@@ -3,18 +3,7 @@ ...@@ -3,18 +3,7 @@
// The list of file replacements can be found in `angular.json`. // The list of file replacements can be found in `angular.json`.
export const environment = { export const environment = {
production: false, production: false,
firebase: { baseUrl: ' https://myskill-x-uat.myhr.co.th/api',
apiKey: '********************************',
authDomain: '********************************',
projectId: '********************************',
storageBucket: '********************************',
messagingSenderId: '********************************',
appId: '********************************',
measurementId: '********************************',
},
// baseUrl: 'https://hrplus-std.myhr.co.th/plus',
// baseUrl: 'https://192.168.10.165/plus',
baseUrl: ' https://myskill-x.myhr.co.th/api',
}; };
/* /*
......
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