fix(qr): ServicePass Link URL-Handling & APPKILL Token Ablaufprüfung
All checks were successful
Build and Deploy / build (push) Successful in 52s
All checks were successful
Build and Deploy / build (push) Successful in 52s
This commit is contained in:
62
posClient.js
62
posClient.js
@@ -60,20 +60,58 @@ async function processQrSetup(qrPayload) {
|
||||
|
||||
const cleanUrl = url.replace(/\/$/, '');
|
||||
|
||||
// 1. GET ServicePass: GET {url}/@LNK{servicepasslink}
|
||||
const linkUrl = `${cleanUrl}/@LNK${servicepasslink}`;
|
||||
const resLink = await fetch(linkUrl, {
|
||||
method: 'GET',
|
||||
headers: { 'User-Agent': 'Getraenkekarte-POS-Client/1.0' }
|
||||
});
|
||||
// Endpunkt-Varianten für ServicePass Link (Cloud-Instanzen unterstützen @LNK... oder @...)
|
||||
const candidateUrls = [
|
||||
`${cleanUrl}/@${servicepasslink}`,
|
||||
`${cleanUrl}/@LNK${servicepasslink}`,
|
||||
`${cleanUrl}/LNK${servicepasslink}`,
|
||||
`${cleanUrl}/@LNK/${servicepasslink}`,
|
||||
`${cleanUrl}/WWSVC/@LNK${servicepasslink}`
|
||||
];
|
||||
|
||||
if (!resLink.ok) {
|
||||
throw new Error(`Fehler beim Abruf von ServicePass (@LNK): ${resLink.status} ${resLink.statusText}`);
|
||||
let resLink = null;
|
||||
let responseText = '';
|
||||
let usedUrl = '';
|
||||
|
||||
for (const cUrl of candidateUrls) {
|
||||
try {
|
||||
const res = await fetch(cUrl, {
|
||||
method: 'GET',
|
||||
headers: { 'User-Agent': 'Getraenkekarte-POS-Client/1.0' }
|
||||
});
|
||||
if (res.ok) {
|
||||
resLink = res;
|
||||
responseText = await res.text();
|
||||
usedUrl = cUrl;
|
||||
break;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
const passData = await resLink.json();
|
||||
const passId = passData.passId || passData.PassId || passData.id;
|
||||
const appId = passData.appId || passData.AppId || passData.key;
|
||||
if (!resLink) {
|
||||
throw new Error(`Fehler beim Abruf von ServicePass (@LNK): 404 Resource not found`);
|
||||
}
|
||||
|
||||
let passId = '';
|
||||
let appId = '';
|
||||
|
||||
try {
|
||||
const passData = JSON.parse(responseText);
|
||||
passId = passData.passId || passData.PassId || passData.id;
|
||||
appId = passData.appId || passData.AppId || passData.key;
|
||||
} catch (e) {
|
||||
// Falls Text / Delimiter Format
|
||||
if (responseText.includes('APPKILL')) {
|
||||
throw new Error(`QR-Code Token abgelaufen oder bereits verbraucht (Server meldet: APPKILL). Bitte neuen QR-Code im Kassensystem erzeugen.`);
|
||||
}
|
||||
const parts = responseText.split('@)').map(s => s.trim()).filter(Boolean);
|
||||
if (parts.length >= 2) {
|
||||
passId = parts[0];
|
||||
appId = parts[1];
|
||||
} else {
|
||||
throw new Error(`Unerwartete Antwort von ServicePass: ${responseText}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (!passId || !appId) {
|
||||
throw new Error('Antwort von ServicePass enthält keine gültige passId/appId');
|
||||
@@ -86,7 +124,7 @@ async function processQrSetup(qrPayload) {
|
||||
upsert.run('pos_app_id', appId);
|
||||
if (mdcDeviceId) upsert.run('pos_cash_register', String(mdcDeviceId));
|
||||
|
||||
// 3. Pass aktivieren (PUT /WWSVC/EXECURL/{passId}/CASPOS.PUT/REGISTERID={mdcDeviceId}/ENTITY=SERVICEPASS/SERVICEPASS_ID={passId})
|
||||
// 3. Pass aktivieren
|
||||
const devId = mdcDeviceId || '1';
|
||||
const activatePath = `/WWSVC/EXECURL/${passId}/CASPOS.PUT/REGISTERID=${devId}/ENTITY=SERVICEPASS/SERVICEPASS_ID=${passId}`;
|
||||
const activateUrl = `${cleanUrl}${activatePath}`;
|
||||
|
||||
Reference in New Issue
Block a user