fix : error in login {removed docker login}
This commit is contained in:
parent
37755fdc6a
commit
389ffe6555
@ -15,7 +15,8 @@ import {
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router } from '@angular/router';
|
||||
import { BtcService } from '../service/btc.service';
|
||||
import { HttpClientModule, HttpResponse } from '@angular/common/http';
|
||||
import { HttpClientModule, HttpClient } from '@angular/common/http';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
@ -44,7 +45,8 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
private fb: FormBuilder,
|
||||
private cdRef: ChangeDetectorRef,
|
||||
private router: Router,
|
||||
private btcService: BtcService
|
||||
private btcService: BtcService,
|
||||
private http: HttpClient
|
||||
) {
|
||||
this.loginForm = this.fb.group({
|
||||
email: ['', Validators.required],
|
||||
@ -108,10 +110,10 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
private toPrintableChar(ev: KeyboardEvent): string {
|
||||
if (ev.key.length === 1) return ev.key;
|
||||
if (ev.key === 'Process') {
|
||||
if (ev.keyCode >= 48 && ev.keyCode <= 57)
|
||||
return String.fromCharCode(ev.keyCode);
|
||||
if (ev.keyCode >= 65 && ev.keyCode <= 90)
|
||||
return String.fromCharCode(ev.keyCode);
|
||||
// @ts-ignore - keyCode legacy
|
||||
const kc = ev.keyCode;
|
||||
if (kc >= 48 && kc <= 57) return String.fromCharCode(kc);
|
||||
if (kc >= 65 && kc <= 90) return String.fromCharCode(kc);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@ -212,101 +214,149 @@ export class LoginComponent implements OnInit, OnDestroy {
|
||||
resetUserPassMessage() {
|
||||
this.passwordStatus = true;
|
||||
}
|
||||
//--------------------------------------NEW LOGIN LOGIC ----------------------------------------//
|
||||
//--------------------------------------NEW LOGIN LOGIC ----------------------------------------//
|
||||
async onSubmit(): Promise<void> {
|
||||
if (this.loginForm.invalid) {
|
||||
this.loginForm.markAllAsTouched();
|
||||
return;
|
||||
}
|
||||
|
||||
const { email, password } = this.loginForm.value;
|
||||
/**
|
||||
* COMPLETE LOGIN LOGIC - NO FALLBACKS
|
||||
* Will fail if BTID cannot be fetched from Electron API
|
||||
*/
|
||||
async onSubmit(): Promise<void> {
|
||||
// validate form
|
||||
if (this.loginForm.invalid) {
|
||||
this.loginForm.markAllAsTouched();
|
||||
return;
|
||||
}
|
||||
|
||||
// ✅ Await service (since it’s async)
|
||||
(await this.btcService.userLogin(email, password)).subscribe({
|
||||
next: (response) => {
|
||||
const employee = response.body;
|
||||
console.log('🧠 Raw employee response:', employee);
|
||||
this.loginError = null;
|
||||
this.passwordStatus = true;
|
||||
|
||||
const userName = employee?.userName || 'Unknown User';
|
||||
const employeeId = employee?.userIdNumber || email;
|
||||
const email = (this.loginForm.get('email')!.value || '').toString().trim();
|
||||
const password = (this.loginForm.get('password')!.value || '').toString();
|
||||
|
||||
console.log('✅ Parsed name:', userName);
|
||||
console.log('✅ Parsed ID:', employeeId);
|
||||
// ✅ CRITICAL: Load BTID FIRST - This will throw if fails
|
||||
let fetchedBtid: string;
|
||||
try {
|
||||
console.log('🔄 Fetching BTID from Electron API...');
|
||||
await this.btcService.loadBtid();
|
||||
|
||||
fetchedBtid = this.btcService.btid!;
|
||||
if (!fetchedBtid) {
|
||||
throw new Error('BTID is null after fetch');
|
||||
}
|
||||
|
||||
console.log('✅ BTID successfully fetched:', fetchedBtid);
|
||||
} catch (btidError: any) {
|
||||
console.error('❌ BTID fetch failed:', btidError);
|
||||
this.loginError = `Failed to load BTID: ${btidError.message}. Please check Electron connection and try again.`;
|
||||
this.passwordStatus = false;
|
||||
return; // STOP LOGIN - No fallback allowed
|
||||
}
|
||||
|
||||
this.passwordStatus = true;
|
||||
// ✅ Build payload with REAL BTID - NO FALLBACK
|
||||
const payload = {
|
||||
opCard: email,
|
||||
password: password,
|
||||
btId: fetchedBtid, // Real BTID only
|
||||
usrId: '',
|
||||
btMake: 0,
|
||||
};
|
||||
|
||||
// ✅ Get the BTID the service fetched
|
||||
const btid = this.btcService.btid;
|
||||
console.log("📦 BTID from file (via service):", btid);
|
||||
console.log('📦 Login payload being sent:', payload);
|
||||
|
||||
try {
|
||||
// 1) POST to login endpoint
|
||||
const loginUrl = 'http://localhost:8080/login';
|
||||
const loginResp: any = await lastValueFrom(
|
||||
this.http.post(loginUrl, payload, { observe: 'body' })
|
||||
);
|
||||
|
||||
console.log('🧠 Login response:', loginResp);
|
||||
|
||||
// Store response safely
|
||||
try {
|
||||
localStorage.setItem('loginRes', JSON.stringify(loginResp));
|
||||
console.log('✅ Full login response saved');
|
||||
} catch (e) {
|
||||
console.error('❌ Failed to stringify login response:', e);
|
||||
localStorage.setItem('loginRes', JSON.stringify(loginResp, Object.getOwnPropertyNames(loginResp)));
|
||||
}
|
||||
|
||||
// Parse username from response
|
||||
const rawLoginRes = localStorage.getItem('loginRes');
|
||||
if (rawLoginRes) {
|
||||
try {
|
||||
const parsed = JSON.parse(rawLoginRes);
|
||||
const username = parsed?.log?.cUsrNm || 'Unknown User';
|
||||
console.log('🧑 Username from loginRes:', username);
|
||||
localStorage.setItem('userName', username);
|
||||
} catch (e) {
|
||||
console.error('❌ Failed to parse loginRes from localStorage', e);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Save REAL BTID to localStorage for second screen
|
||||
localStorage.setItem('btid', fetchedBtid);
|
||||
console.log('💾 BTID saved to localStorage:', fetchedBtid);
|
||||
|
||||
// Prepare print payload
|
||||
const printData = {
|
||||
name: userName,
|
||||
employeeId: employeeId,
|
||||
name: localStorage.getItem('userName') || 'Unknown User',
|
||||
employeeId: email, // Use email as employee ID
|
||||
action: 'login',
|
||||
type: 'login'
|
||||
type: 'login',
|
||||
};
|
||||
|
||||
// ✅ Store in localStorage
|
||||
localStorage.setItem('userName', userName);
|
||||
localStorage.setItem('employeeId', employeeId);
|
||||
localStorage.setItem('password', password);
|
||||
localStorage.setItem('btid', btid || "unknown");
|
||||
// 2) Print (commented out - uncomment if needed)
|
||||
/*
|
||||
const printRes = await fetch('http://localhost:9100/print', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(printData),
|
||||
});
|
||||
|
||||
// ✅ Fetch race card after login success
|
||||
this.btcService
|
||||
.fetchRaceCard("021804111066", password, btid || "0483") // pass correct payload here
|
||||
.subscribe({
|
||||
next: (rpinfo) => {
|
||||
console.log("📦 Race Card:", rpinfo);
|
||||
if (!printRes.ok) {
|
||||
throw new Error(`Print failed (${printRes.status})`);
|
||||
}
|
||||
console.log('🖨️ Print successful');
|
||||
*/
|
||||
|
||||
// Save in localStorage for later use
|
||||
localStorage.setItem('rpinfo', JSON.stringify(rpinfo));
|
||||
// 3) Fetch race card with DYNAMIC values - NO FALLBACKS
|
||||
console.log('🔄 Fetching race card with:', { opCard: email, password, btId: fetchedBtid });
|
||||
const rpInfo = await lastValueFrom(
|
||||
this.btcService.fetchRaceCard(email, password, fetchedBtid) // Dynamic opCard, real BTID
|
||||
);
|
||||
|
||||
// ✅ Navigate once race card stored
|
||||
(window as any).electronAPI?.openSecondScreen?.();
|
||||
this.router.navigate(['/home']);
|
||||
},
|
||||
error: (err) => {
|
||||
console.error("‼️ Failed to fetch race card", err);
|
||||
this.loginError = "Could not load race card.";
|
||||
}
|
||||
});
|
||||
// ✅ Print first — login only if printing succeeds
|
||||
fetch('http://localhost:9100/print', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(printData),
|
||||
})
|
||||
.then((res) => {
|
||||
if (!res.ok) throw new Error('Print failed');
|
||||
console.log('🖨️ Print successful');
|
||||
console.log('📦 Race Card fetched successfully:', rpInfo);
|
||||
localStorage.setItem('rpinfo', JSON.stringify(rpInfo));
|
||||
|
||||
// ✅ Only here we allow login
|
||||
(window as any).electronAPI?.openSecondScreen?.();
|
||||
this.router.navigate(['/home']);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('‼️ Print failed', err);
|
||||
this.loginError = 'Login failed: printing service unavailable.';
|
||||
this.passwordStatus = false; // reset status
|
||||
});
|
||||
|
||||
},
|
||||
error: () => {
|
||||
this.loginError = 'Invalid login credentials';
|
||||
// 4) Navigate to second screen
|
||||
console.log('🚀 Navigating to home with BTID:', fetchedBtid);
|
||||
(window as any).electronAPI?.openSecondScreen?.();
|
||||
this.router.navigate(['/home']);
|
||||
|
||||
} catch (err: any) {
|
||||
console.error('❌ Login flow failed:', err);
|
||||
|
||||
// Specific error handling
|
||||
if (err?.message?.includes('Print failed')) {
|
||||
this.loginError = 'Login failed: printing service unavailable.';
|
||||
} else if (err?.status === 401 || err?.status === 400) {
|
||||
this.loginError = 'Invalid login credentials';
|
||||
} else if (err?.message?.includes('BTID')) {
|
||||
this.loginError = `BTID Error: ${err.message}`;
|
||||
} else {
|
||||
this.loginError = err?.message || 'Login failed. Please try again.';
|
||||
}
|
||||
|
||||
this.passwordStatus = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
showConfirmModal : boolean = false;
|
||||
showConfirmModal: boolean = false;
|
||||
|
||||
confirmShutdown() : void{
|
||||
this.showConfirmModal = false;
|
||||
this.shutdownSystem();
|
||||
|
||||
}
|
||||
confirmShutdown(): void {
|
||||
this.showConfirmModal = false;
|
||||
this.shutdownSystem();
|
||||
}
|
||||
|
||||
shutdownSystem(): void {
|
||||
fetch('http://localhost:3000/shutdown', {
|
||||
@ -320,4 +370,4 @@ async onSubmit(): Promise<void> {
|
||||
console.error('‼️ Failed to shutdown', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,109 +1,7 @@
|
||||
// import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
// import { Injectable } from '@angular/core';
|
||||
// import { ApplicationHttpRouts } from '../constants/http-routs';
|
||||
|
||||
// @Injectable({
|
||||
// providedIn: 'root',
|
||||
// })
|
||||
|
||||
// // export class BtcService {
|
||||
// // constructor(private http: HttpClient) {}
|
||||
// // btid: string | null = null;
|
||||
// // //user login
|
||||
// // public userLogin(employeeId: string, password: string) {
|
||||
// // console.log('Login route ' + ApplicationHttpRouts.LOG_IN);
|
||||
// // this.btid = localStorage.getItem('btid');
|
||||
// // if (this.btid) {
|
||||
// // employeeId += "," + this.btid;
|
||||
// // } else {
|
||||
// // employeeId += ",null"; // or just "," if you don’t want "null"
|
||||
// // }
|
||||
// // return this.http.get<any>(ApplicationHttpRouts.LOG_IN, {
|
||||
// // headers: this.basicAuthCredentialsBuilder(employeeId, password),
|
||||
// // withCredentials: true,
|
||||
// // observe: 'response',
|
||||
// // });
|
||||
// // }
|
||||
|
||||
// export class BtcService {
|
||||
// constructor(private http: HttpClient) {}
|
||||
// btid: string | null = null;
|
||||
|
||||
// // user login
|
||||
// public async userLogin(employeeId: string, password: string) {
|
||||
// console.log('Login route ' + ApplicationHttpRouts.LOG_IN);
|
||||
|
||||
// try {
|
||||
// if ((window as any).electronAPI?.getBtid) {
|
||||
// this.btid = await (window as any).electronAPI.getBtid();
|
||||
// } else {
|
||||
// console.warn('Electron API not available — fallback to null');
|
||||
// this.btid = null;
|
||||
// }
|
||||
// } catch (err) {
|
||||
// console.error('Error fetching BTID:', err);
|
||||
// this.btid = null;
|
||||
// }
|
||||
|
||||
// // Append BTID after comma
|
||||
// if (this.btid) {
|
||||
// employeeId += ',' + this.btid;
|
||||
// } else {
|
||||
// employeeId += ',null';
|
||||
// }
|
||||
|
||||
// return this.http.get<any>(ApplicationHttpRouts.LOG_IN, {
|
||||
// headers: this.basicAuthCredentialsBuilder(employeeId, password),
|
||||
// withCredentials: true,
|
||||
// observe: 'response',
|
||||
// });
|
||||
// }
|
||||
|
||||
// // what goes to the backend for auth ... is the same as postman's basic auth
|
||||
// private basicAuthCredentialsBuilder(
|
||||
// employeeOrUserId: string,
|
||||
// password: string
|
||||
// ): HttpHeaders {
|
||||
// console.log(`username and password${employeeOrUserId} p = ${password}`);
|
||||
|
||||
// return new HttpHeaders().set(
|
||||
// 'Authorization',
|
||||
// 'basic ' + window.btoa(employeeOrUserId + ':' + password)
|
||||
// );
|
||||
// }
|
||||
|
||||
// public pingLiveStatus() {
|
||||
// return this.http.get<any>(ApplicationHttpRouts.PING, {
|
||||
// withCredentials: true,
|
||||
// observe: 'response',
|
||||
// responseType: 'text' as 'json',
|
||||
// });
|
||||
// }
|
||||
|
||||
// // Fetch all race events today
|
||||
|
||||
// public getAllRaceEventsToday() {
|
||||
// return this.http.get<any>(ApplicationHttpRouts.RACE_EVENTS_TODAY, {
|
||||
// withCredentials: true,
|
||||
// observe: 'response',
|
||||
// responseType: 'json',
|
||||
// });
|
||||
// }
|
||||
|
||||
// public getRaceCard(){
|
||||
// return this.http.get<any>(ApplicationHttpRouts.RACE_CARD, {
|
||||
// withCredentials: true,
|
||||
// observe: 'response',
|
||||
// responseType: 'json',
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ApplicationHttpRouts } from '../constants/http-routs';
|
||||
import { of,Observable, tap } from 'rxjs';
|
||||
import { of, Observable, tap } from 'rxjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@ -111,25 +9,51 @@ import { of,Observable, tap } from 'rxjs';
|
||||
export class BtcService {
|
||||
constructor(private http: HttpClient) {}
|
||||
btid: string | null = null;
|
||||
private raceCard: any = null; // cache race card in memory
|
||||
|
||||
// user login
|
||||
public async userLogin(employeeId: string, password: string) {
|
||||
console.log('Login route ' + ApplicationHttpRouts.LOG_IN);
|
||||
private raceCard: any = null;
|
||||
|
||||
/**
|
||||
* Load BTID from Electron API (no fallback)
|
||||
*/
|
||||
public async loadBtid(): Promise<void> {
|
||||
console.log('Loading BTID...');
|
||||
try {
|
||||
if ((window as any).electronAPI?.getBtid) {
|
||||
this.btid = await (window as any).electronAPI.getBtid();
|
||||
if (!this.btid) {
|
||||
throw new Error('BTID is empty or null from Electron API');
|
||||
}
|
||||
console.log('✅ BTID loaded:', this.btid);
|
||||
} else {
|
||||
console.warn('Electron API not available — fallback to null');
|
||||
this.btid = null;
|
||||
console.warn('Electron API not available');
|
||||
throw new Error('Electron API not available');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error fetching BTID:', err);
|
||||
this.btid = null;
|
||||
throw err; // Propagate error instead of setting fallback
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get BTID from memory or localStorage (for second screen)
|
||||
*/
|
||||
public getBtid(): string | null {
|
||||
if (this.btid) {
|
||||
return this.btid;
|
||||
}
|
||||
const storedBtid = localStorage.getItem('btid');
|
||||
if (storedBtid) {
|
||||
this.btid = storedBtid;
|
||||
return this.btid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async userLogin(employeeId: string, password: string) {
|
||||
console.log('Login route ' + ApplicationHttpRouts.LOG_IN);
|
||||
|
||||
await this.loadBtid(); // Will throw if BTID fetch fails
|
||||
|
||||
// Append BTID after comma
|
||||
if (this.btid) {
|
||||
employeeId += ',' + this.btid;
|
||||
} else {
|
||||
@ -143,20 +67,17 @@ export class BtcService {
|
||||
});
|
||||
}
|
||||
|
||||
// basic auth header
|
||||
private basicAuthCredentialsBuilder(
|
||||
employeeOrUserId: string,
|
||||
password: string
|
||||
): HttpHeaders {
|
||||
console.log(`username and password = ${employeeOrUserId} p = ${password}`);
|
||||
|
||||
return new HttpHeaders().set(
|
||||
'Authorization',
|
||||
'basic ' + window.btoa(employeeOrUserId + ':' + password)
|
||||
);
|
||||
}
|
||||
|
||||
// Ping backend
|
||||
public pingLiveStatus() {
|
||||
return this.http.get<any>(ApplicationHttpRouts.PING, {
|
||||
withCredentials: true,
|
||||
@ -165,7 +86,6 @@ export class BtcService {
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch all race events today
|
||||
public getAllRaceEventsToday() {
|
||||
return this.http.get<any>(ApplicationHttpRouts.RACE_EVENTS_TODAY, {
|
||||
withCredentials: true,
|
||||
@ -174,37 +94,6 @@ export class BtcService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch Race Card from backend (POST /download/rpinfo)
|
||||
* Stores result in memory for reuse
|
||||
// */
|
||||
// public fetchRaceCard(
|
||||
// opCard: string,
|
||||
// password: string,
|
||||
// btId: string,
|
||||
// usrId: string = '',
|
||||
// btMake: number = 0
|
||||
// ): Observable<any> {
|
||||
// const payload = { opCard, password, btId, usrId, btMake };
|
||||
|
||||
// return this.http
|
||||
// .post<any>('http://localhost:8082/download/rpinfo', payload)
|
||||
// .pipe(
|
||||
// tap((data) => {
|
||||
// console.log('📦 Race Card fetched:', data);
|
||||
// this.raceCard = data; // cache it
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Return cached race card (if available)
|
||||
// */
|
||||
// public getRaceCard(): any {
|
||||
// return this.raceCard;
|
||||
// }
|
||||
|
||||
|
||||
public fetchRaceCard(
|
||||
opCard: string,
|
||||
password: string,
|
||||
@ -213,36 +102,26 @@ export class BtcService {
|
||||
btMake: number = 0
|
||||
): Observable<any> {
|
||||
const payload = { opCard, password, btId, usrId, btMake };
|
||||
|
||||
return this.http
|
||||
.post<any>('http://localhost:8082/download/rpinfo', payload)
|
||||
.pipe(
|
||||
tap((data) => {
|
||||
console.log('📦 Race Card fetched:', data);
|
||||
this.raceCard = data; // store in memory
|
||||
localStorage.setItem('rpinfo', JSON.stringify(data)); // store in localStorage
|
||||
this.raceCard = data;
|
||||
localStorage.setItem('rpinfo', JSON.stringify(data));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return cached race card:
|
||||
* - from memory (fastest)
|
||||
* - fallback to localStorage (if reloaded)
|
||||
*/
|
||||
public getRaceCard(): Observable<any> {
|
||||
if (this.raceCard) {
|
||||
return of(this.raceCard);
|
||||
}
|
||||
|
||||
const cached = localStorage.getItem('rpinfo');
|
||||
if (cached) {
|
||||
this.raceCard = JSON.parse(cached);
|
||||
return of(this.raceCard);
|
||||
}
|
||||
|
||||
// Nothing available, return empty object
|
||||
return of(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user