Compare commits

..

4 Commits

Author SHA1 Message Date
7c51525841 [update] - add token exprire 2024-10-04 16:54:41 +07:00
6b1be7c793 [update] - test mirror 2024-10-04 15:32:50 +07:00
cb7eb81dc9 [test] - test mirror 2024-10-04 15:05:41 +07:00
925963e384 [test] - test morror 2024-10-04 14:56:33 +07:00
16 changed files with 8272 additions and 81 deletions

View File

@@ -25,3 +25,4 @@ Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To u
## Further help ## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page. To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
git push --mirror https://gitea.71dev.com/Phet/mirror-cathay.git

20
package-lock.json generated
View File

@@ -18,6 +18,7 @@
"@angular/platform-browser": "^15.2.0", "@angular/platform-browser": "^15.2.0",
"@angular/platform-browser-dynamic": "^15.2.0", "@angular/platform-browser-dynamic": "^15.2.0",
"@angular/router": "^15.2.0", "@angular/router": "^15.2.0",
"@auth0/angular-jwt": "^5.2.0",
"@ng-select/ng-select": "^10.0.3", "@ng-select/ng-select": "^10.0.3",
"bootstrap-icons": "^1.10.3", "bootstrap-icons": "^1.10.3",
"date-fns": "^2.29.3", "date-fns": "^2.29.3",
@@ -729,6 +730,17 @@
"integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==",
"dev": true "dev": true
}, },
"node_modules/@auth0/angular-jwt": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.2.0.tgz",
"integrity": "sha512-9FS2L0QwGNlxA/zgeehCcsR9CZscouyXkoIj1fODM36A8BLfdzg9k9DWAXUQ2Drjk0AypGAFzeNZR4vsLMhdeQ==",
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"@angular/common": ">=14.0.0"
}
},
"node_modules/@babel/code-frame": { "node_modules/@babel/code-frame": {
"version": "7.18.6", "version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
@@ -13155,6 +13167,14 @@
"integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==", "integrity": "sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==",
"dev": true "dev": true
}, },
"@auth0/angular-jwt": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.2.0.tgz",
"integrity": "sha512-9FS2L0QwGNlxA/zgeehCcsR9CZscouyXkoIj1fODM36A8BLfdzg9k9DWAXUQ2Drjk0AypGAFzeNZR4vsLMhdeQ==",
"requires": {
"tslib": "^2.0.0"
}
},
"@babel/code-frame": { "@babel/code-frame": {
"version": "7.18.6", "version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",

View File

@@ -20,6 +20,7 @@
"@angular/platform-browser": "^15.2.0", "@angular/platform-browser": "^15.2.0",
"@angular/platform-browser-dynamic": "^15.2.0", "@angular/platform-browser-dynamic": "^15.2.0",
"@angular/router": "^15.2.0", "@angular/router": "^15.2.0",
"@auth0/angular-jwt": "^5.2.0",
"@ng-select/ng-select": "^10.0.3", "@ng-select/ng-select": "^10.0.3",
"bootstrap-icons": "^1.10.3", "bootstrap-icons": "^1.10.3",
"date-fns": "^2.29.3", "date-fns": "^2.29.3",

8141
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -5,25 +5,25 @@ import { AppService } from './app.service';
@Injectable() @Injectable()
export class AppGuard implements CanActivate, CanActivateChild { export class AppGuard implements CanActivate, CanActivateChild {
constructor(private router: Router, private app: AppService) { constructor(private router: Router, private app: AppService) {
} }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.isLogin(); return this.isLogin();
} }
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this.isLogin(); return this.isLogin();
} }
isLogin() { isLogin() {
return true; const user = this.app.auth();
// const user = this.app.auth(); if (!user) {
// if (!user) { this.router.navigate(['/auth/login'], { replaceUrl: true });
// this.router.navigate(['/auth/login']); localStorage.clear()
// return false; return false;
// }
// return true;
} }
return true;
}
} }

View File

@@ -1,14 +1,15 @@
import {NgModule} from '@angular/core'; import { NgModule } from '@angular/core';
import {BrowserModule} from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import {AppRoutingComponents, AppRoutingModule} from './app-routing.module'; import { AppRoutingComponents, AppRoutingModule } from './app-routing.module';
import {AppComponent} from './app.component'; import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import {FormsModule, ReactiveFormsModule} from "@angular/forms"; import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import {HTTP_INTERCEPTORS, HttpClientModule} from "@angular/common/http"; import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http";
import {AppService} from "./app.service"; import { AppService } from "./app.service";
import {AppGuard} from "./app.guard"; import { AppGuard } from "./app.guard";
import {AppRequestInterceptor} from "./app.request.interceptor"; import { AppRequestInterceptor } from "./app.request.interceptor";
import {AppSharedModule} from "./app.shared"; import { AppSharedModule } from "./app.shared";
import { JwtModule } from '@auth0/angular-jwt';
@NgModule({ @NgModule({
@@ -24,7 +25,8 @@ import {AppSharedModule} from "./app.shared";
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
HttpClientModule, HttpClientModule,
AppSharedModule AppSharedModule,
JwtModule
], ],
providers: [ providers: [
AppService, AppService,

View File

@@ -1,23 +1,40 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http'; import { HttpContextToken, HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { catchError, Observable, throwError } from 'rxjs'; import { catchError, Observable, throwError } from 'rxjs';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
import { SathonCathayPayService } from './sathon-cathay-pay.service'; import { SathonCathayPayService } from './sathon-cathay-pay.service';
import { JwtHelperService } from '@auth0/angular-jwt';
export const SKIP_INTERCEP = new HttpContextToken<boolean>(() => false);
@Injectable() @Injectable()
export class AppRequestInterceptor implements HttpInterceptor { export class AppRequestInterceptor implements HttpInterceptor {
constructor( constructor(
private router: Router, private router: Router,
private appService: AppService, private appService: AppService,
private sathonSV: SathonCathayPayService // private sathonSV: SathonCathayPayService
) { ) { }
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (request.context.get(SKIP_INTERCEP)) {
return next.handle(request)
}
const token = this.appService.token(); const token = this.appService.token();
const appsathonAPpToken = this.appService.getsathonToken()
const helper = new JwtHelperService();
const isAppTokenExpired = helper.isTokenExpired(token);
const isSathonAppTokenExpired = helper.isTokenExpired(appsathonAPpToken)
if (isAppTokenExpired || isSathonAppTokenExpired) {
this.router.navigate(['/auth'], { replaceUrl: true });
localStorage.clear()
return
}
if (token) { if (token) {
request = request.clone({ request = request.clone({
@@ -29,7 +46,7 @@ export class AppRequestInterceptor implements HttpInterceptor {
catchError((err) => { catchError((err) => {
if (err instanceof HttpErrorResponse) { if (err instanceof HttpErrorResponse) {
if (err.status === 401) { if (err.status === 401) {
this.router.navigate(['/auth']); this.router.navigate(['/auth'], { replaceUrl: true });
} }
} }
return throwError(err); return throwError(err);

View File

@@ -4,8 +4,6 @@ import { DOCUMENT, Location } from '@angular/common';
import { from, Observable } from 'rxjs'; import { from, Observable } from 'rxjs';
import Swal, { SweetAlertResult } from 'sweetalert2' import Swal, { SweetAlertResult } from 'sweetalert2'
import { EAction } from "./@config/app"; import { EAction } from "./@config/app";
@Injectable() @Injectable()
export class AppService { export class AppService {

View File

@@ -55,7 +55,7 @@ export class LoginComponent implements OnInit {
isAdmin: isAdmin isAdmin: isAdmin
} }
this.appService.setToken(cathayResult.token.token) this.appService.setToken(cathayResult.token)
this.appService.setSathonToken(sathonToken.token) this.appService.setSathonToken(sathonToken.token)
this.appService.setAuth(cathayResult); this.appService.setAuth(cathayResult);

View File

@@ -1,9 +1,9 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { import {
HttpRequest, HttpRequest,
HttpHandler, HttpHandler,
HttpEvent, HttpEvent,
HttpInterceptor HttpInterceptor
} from '@angular/common/http'; } from '@angular/common/http';
import { Observable, throwError } from 'rxjs'; import { Observable, throwError } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators'; import { catchError, finalize } from 'rxjs/operators';
@@ -12,26 +12,23 @@ import { Router } from '@angular/router';
@Injectable() @Injectable()
export class TokenIntercepterInterceptor implements HttpInterceptor { export class TokenIntercepterInterceptor implements HttpInterceptor {
constructor( constructor() { }
private router: Router,
) {
}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
const customReq = request.clone({ const customReq = request.clone({
setHeaders: { setHeaders: {
// Authorization: request.url.includes('app_tokens') ? `${this.odicSV.getAuthorizationHeaderValue()}` : `Bearer ${this.appTokenSV.getToken()}` // Authorization: request.url.includes('app_tokens') ? `${this.odicSV.getAuthorizationHeaderValue()}` : `Bearer ${this.appTokenSV.getToken()}`
} }
}); });
return next.handle(customReq) return next.handle(customReq)
// return next.handle(customReq).pipe( // return next.handle(customReq).pipe(
// finalize(() => this.progress.ref('progressBar').complete()), // finalize(() => this.progress.ref('progressBar').complete()),
// catchError(err => { // catchError(err => {
// if (err.status == 401) { // if (err.status == 401) {
// this.router.navigate(['./'], { replaceUrl: true }) // this.router.navigate(['./'], { replaceUrl: true })
// } // }
// return throwError(err) // return throwError(err)
// }) // })
// ); // );
} }
} }

View File

@@ -1,20 +1,21 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient, HttpContext } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { SKIP_INTERCEP } from 'src/app/app.request.interceptor';
import { BaseService } from 'src/app/core/base/base-service'; import { BaseService } from 'src/app/core/base/base-service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class AuthService extends BaseService{ export class AuthService extends BaseService {
constructor( constructor(
public http: HttpClient public http: HttpClient
) { ) {
super('/common/user_login', http) super('/common/user_login', http)
} }
login(payload : {'loginname': string , 'password' : string}){ login(payload: { 'loginname': string, 'password': string }) {
return this.http.get(`${this.prefix}/common/user_login/login/${payload.loginname}/${payload.password}`) return this.http.get(`${this.prefix}/common/user_login/login/${payload.loginname}/${payload.password}`)
} }
} }

View File

@@ -1,5 +1,6 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient, HttpContext, HttpContextToken } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { SKIP_INTERCEP } from 'src/app/app.request.interceptor';
import { BaseService } from 'src/app/core/base/base-service'; import { BaseService } from 'src/app/core/base/base-service';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@@ -16,11 +17,11 @@ export class CathayAuthService extends BaseService {
} }
login(payload: { 'mobileDeviceId': string, 'userName': string, 'password': string }) { login(payload: { 'mobileDeviceId': string, 'userName': string, 'password': string }) {
return this.http.post(`${this.fullUrl}/login`, payload) return this.http.post(`${this.fullUrl}/login`, payload, { context: new HttpContext().set(SKIP_INTERCEP, true) })
} }
// https://sathorn.cathay-pay.com/api/v3/User/login // https://sathorn.cathay-pay.com/api/v3/User/login
genToken() { genToken() {
return this.http.get(`${environment.APIURL}/api/common/user_login/token`) return this.http.get(`${environment.APIURL}/api/common/user_login/token`, { context: new HttpContext().set(SKIP_INTERCEP, true) })
} }
} }

View File

@@ -38,7 +38,7 @@ export class PagesLayoutsComponent implements OnInit {
// console.log(this.auth) // console.log(this.auth)
// console.log(this.auth.isAdmin) // console.log(this.auth.isAdmin)
this.menus = this.menus.map(r => { this.menus = this.menus.map(r => {
if (this.auth.isAdmin) { if (this.auth?.isAdmin) {
if (r.roles.includes(ROLE_ADMIN)) return { if (r.roles.includes(ROLE_ADMIN)) return {
...r, ...r,
children: r.children.length ? r.children.filter(c => r.roles.includes(ROLE_ADMIN)) : [] children: r.children.length ? r.children.filter(c => r.roles.includes(ROLE_ADMIN)) : []

View File

@@ -1,6 +1,7 @@
export const environment = { export const environment = {
production: false, production: false,
hideForm: false, hideForm: false,
APIURL: 'https://cathaypay.71dev.com/cathaypay-api', // test mirror
CATHAYAPIURL: 'https://sathorn.cathay-pay.com/api' APIURL: 'https://cathaypay.71dev.com/cathaypay-api',
CATHAYAPIURL: 'https://sathorn.cathay-pay.com/api'
}; };

View File

@@ -1,5 +1,6 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Cathaypay</title> <title>Cathaypay</title>
@@ -8,10 +9,13 @@
<link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@100;200;300;400;500&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Thai:wght@100;200;300;400;500&display=swap"
rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head> </head>
<body class="mat-typography"> <body class="mat-typography">
<app-root></app-root> <app-root></app-root>
</body> </body>
</html> </html>

View File

@@ -280,6 +280,13 @@
resolved "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz" resolved "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.10.1.tgz"
integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg== integrity sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==
"@auth0/angular-jwt@^5.2.0":
version "5.2.0"
resolved "https://registry.npmjs.org/@auth0/angular-jwt/-/angular-jwt-5.2.0.tgz"
integrity sha512-9FS2L0QwGNlxA/zgeehCcsR9CZscouyXkoIj1fODM36A8BLfdzg9k9DWAXUQ2Drjk0AypGAFzeNZR4vsLMhdeQ==
dependencies:
tslib "^2.0.0"
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6":
version "7.18.6" version "7.18.6"
resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz"
@@ -6622,7 +6629,7 @@ tslib@^1.9.0:
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@2.5.0: tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@2.5.0:
version "2.5.0" version "2.5.0"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==