@kreiseck/kasseneck-api 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +2 -0
  3. package/README.md +206 -0
  4. package/dist/cjs/client/api.d.ts +75 -0
  5. package/dist/cjs/client/api.js +40 -0
  6. package/dist/cjs/client/auth.d.ts +52 -0
  7. package/dist/cjs/client/auth.js +72 -0
  8. package/dist/cjs/client/cashregisters.d.ts +21 -0
  9. package/dist/cjs/client/cashregisters.js +36 -0
  10. package/dist/cjs/client/errors.d.ts +159 -0
  11. package/dist/cjs/client/errors.js +226 -0
  12. package/dist/cjs/client/index.d.ts +8 -0
  13. package/dist/cjs/client/index.js +44 -0
  14. package/dist/cjs/client/receipts.d.ts +245 -0
  15. package/dist/cjs/client/receipts.js +452 -0
  16. package/dist/cjs/client/reports.d.ts +43 -0
  17. package/dist/cjs/client/reports.js +73 -0
  18. package/dist/cjs/client/status.d.ts +43 -0
  19. package/dist/cjs/client/status.js +47 -0
  20. package/dist/cjs/client/transport.d.ts +117 -0
  21. package/dist/cjs/client/transport.js +312 -0
  22. package/dist/cjs/enums/credit-card-provider.d.ts +22 -0
  23. package/dist/cjs/enums/credit-card-provider.js +23 -0
  24. package/dist/cjs/enums/define-enum.d.ts +15 -0
  25. package/dist/cjs/enums/define-enum.js +16 -0
  26. package/dist/cjs/enums/index.d.ts +7 -0
  27. package/dist/cjs/enums/index.js +17 -0
  28. package/dist/cjs/enums/keck-payment-method.d.ts +57 -0
  29. package/dist/cjs/enums/keck-payment-method.js +23 -0
  30. package/dist/cjs/enums/receipt-type.d.ts +41 -0
  31. package/dist/cjs/enums/receipt-type.js +18 -0
  32. package/dist/cjs/enums/stripe-link-mode.d.ts +17 -0
  33. package/dist/cjs/enums/stripe-link-mode.js +18 -0
  34. package/dist/cjs/enums/vat-rate.d.ts +40 -0
  35. package/dist/cjs/enums/vat-rate.js +19 -0
  36. package/dist/cjs/enums/voucher-action.d.ts +10 -0
  37. package/dist/cjs/enums/voucher-action.js +11 -0
  38. package/dist/cjs/enums/voucher-type.d.ts +9 -0
  39. package/dist/cjs/enums/voucher-type.js +10 -0
  40. package/dist/cjs/index.d.ts +5 -0
  41. package/dist/cjs/index.js +97 -0
  42. package/dist/cjs/kasse/artikel.d.ts +83 -0
  43. package/dist/cjs/kasse/artikel.js +79 -0
  44. package/dist/cjs/kasse/client.d.ts +10 -0
  45. package/dist/cjs/kasse/client.js +38 -0
  46. package/dist/cjs/kasse/drucker.d.ts +54 -0
  47. package/dist/cjs/kasse/drucker.js +41 -0
  48. package/dist/cjs/kasse/index.d.ts +11 -0
  49. package/dist/cjs/kasse/index.js +38 -0
  50. package/dist/cjs/kasse/settings.d.ts +115 -0
  51. package/dist/cjs/kasse/settings.js +62 -0
  52. package/dist/cjs/models/cancellation.d.ts +51 -0
  53. package/dist/cjs/models/cancellation.js +45 -0
  54. package/dist/cjs/models/cashregister.d.ts +77 -0
  55. package/dist/cjs/models/cashregister.js +53 -0
  56. package/dist/cjs/models/enum-payload.d.ts +26 -0
  57. package/dist/cjs/models/enum-payload.js +50 -0
  58. package/dist/cjs/models/hobex-receipt.d.ts +63 -0
  59. package/dist/cjs/models/hobex-receipt.js +86 -0
  60. package/dist/cjs/models/index.d.ts +10 -0
  61. package/dist/cjs/models/index.js +46 -0
  62. package/dist/cjs/models/receipt-company.d.ts +71 -0
  63. package/dist/cjs/models/receipt-company.js +52 -0
  64. package/dist/cjs/models/receipt-item.d.ts +100 -0
  65. package/dist/cjs/models/receipt-item.js +108 -0
  66. package/dist/cjs/models/receipt-summary.d.ts +92 -0
  67. package/dist/cjs/models/receipt-summary.js +54 -0
  68. package/dist/cjs/models/receipt.d.ts +108 -0
  69. package/dist/cjs/models/receipt.js +119 -0
  70. package/dist/cjs/models/report-month.d.ts +32 -0
  71. package/dist/cjs/models/report-month.js +65 -0
  72. package/dist/cjs/models/stripe-url-session.d.ts +18 -0
  73. package/dist/cjs/models/stripe-url-session.js +20 -0
  74. package/dist/cjs/models/voucher.d.ts +41 -0
  75. package/dist/cjs/models/voucher.js +56 -0
  76. package/dist/cjs/money.d.ts +23 -0
  77. package/dist/cjs/money.js +35 -0
  78. package/dist/cjs/package.json +1 -0
  79. package/dist/cjs/payments/hobex.d.ts +87 -0
  80. package/dist/cjs/payments/hobex.js +167 -0
  81. package/dist/cjs/payments/index.d.ts +33 -0
  82. package/dist/cjs/payments/index.js +42 -0
  83. package/dist/cjs/payments/stripe.d.ts +61 -0
  84. package/dist/cjs/payments/stripe.js +157 -0
  85. package/dist/cjs/printing/escpos.d.ts +219 -0
  86. package/dist/cjs/printing/escpos.js +636 -0
  87. package/dist/cjs/printing/index.d.ts +3 -0
  88. package/dist/cjs/printing/index.js +33 -0
  89. package/dist/cjs/printing/printable.d.ts +27 -0
  90. package/dist/cjs/printing/printable.js +90 -0
  91. package/dist/cjs/printing/webusb.d.ts +89 -0
  92. package/dist/cjs/printing/webusb.js +110 -0
  93. package/dist/cjs/react/index.d.ts +46 -0
  94. package/dist/cjs/react/index.js +51 -0
  95. package/dist/cjs/receipt/discount.d.ts +12 -0
  96. package/dist/cjs/receipt/discount.js +54 -0
  97. package/dist/cjs/receipt/epos.d.ts +53 -0
  98. package/dist/cjs/receipt/epos.js +95 -0
  99. package/dist/cjs/receipt/grid.d.ts +47 -0
  100. package/dist/cjs/receipt/grid.js +122 -0
  101. package/dist/cjs/receipt/index.d.ts +4 -0
  102. package/dist/cjs/receipt/index.js +29 -0
  103. package/dist/cjs/receipt/layout-escpos.d.ts +35 -0
  104. package/dist/cjs/receipt/layout-escpos.js +67 -0
  105. package/dist/cjs/receipt/layout.d.ts +180 -0
  106. package/dist/cjs/receipt/layout.js +594 -0
  107. package/dist/cjs/register/index.d.ts +51 -0
  108. package/dist/cjs/register/index.js +61 -0
  109. package/dist/cjs/register/pairing.d.ts +248 -0
  110. package/dist/cjs/register/pairing.js +279 -0
  111. package/dist/cjs/register/session.d.ts +37 -0
  112. package/dist/cjs/register/session.js +52 -0
  113. package/dist/cjs/vienna-time.d.ts +23 -0
  114. package/dist/cjs/vienna-time.js +114 -0
  115. package/dist/esm/client/api.d.ts +75 -0
  116. package/dist/esm/client/api.js +37 -0
  117. package/dist/esm/client/auth.d.ts +52 -0
  118. package/dist/esm/client/auth.js +68 -0
  119. package/dist/esm/client/cashregisters.d.ts +21 -0
  120. package/dist/esm/client/cashregisters.js +33 -0
  121. package/dist/esm/client/errors.d.ts +159 -0
  122. package/dist/esm/client/errors.js +212 -0
  123. package/dist/esm/client/index.d.ts +8 -0
  124. package/dist/esm/client/index.js +8 -0
  125. package/dist/esm/client/receipts.d.ts +245 -0
  126. package/dist/esm/client/receipts.js +438 -0
  127. package/dist/esm/client/reports.d.ts +43 -0
  128. package/dist/esm/client/reports.js +69 -0
  129. package/dist/esm/client/status.d.ts +43 -0
  130. package/dist/esm/client/status.js +43 -0
  131. package/dist/esm/client/transport.d.ts +117 -0
  132. package/dist/esm/client/transport.js +307 -0
  133. package/dist/esm/enums/credit-card-provider.d.ts +22 -0
  134. package/dist/esm/enums/credit-card-provider.js +20 -0
  135. package/dist/esm/enums/define-enum.d.ts +15 -0
  136. package/dist/esm/enums/define-enum.js +13 -0
  137. package/dist/esm/enums/index.d.ts +7 -0
  138. package/dist/esm/enums/index.js +7 -0
  139. package/dist/esm/enums/keck-payment-method.d.ts +57 -0
  140. package/dist/esm/enums/keck-payment-method.js +20 -0
  141. package/dist/esm/enums/receipt-type.d.ts +41 -0
  142. package/dist/esm/enums/receipt-type.js +15 -0
  143. package/dist/esm/enums/stripe-link-mode.d.ts +17 -0
  144. package/dist/esm/enums/stripe-link-mode.js +15 -0
  145. package/dist/esm/enums/vat-rate.d.ts +40 -0
  146. package/dist/esm/enums/vat-rate.js +16 -0
  147. package/dist/esm/enums/voucher-action.d.ts +10 -0
  148. package/dist/esm/enums/voucher-action.js +8 -0
  149. package/dist/esm/enums/voucher-type.d.ts +9 -0
  150. package/dist/esm/enums/voucher-type.js +7 -0
  151. package/dist/esm/index.d.ts +5 -0
  152. package/dist/esm/index.js +5 -0
  153. package/dist/esm/kasse/artikel.d.ts +83 -0
  154. package/dist/esm/kasse/artikel.js +70 -0
  155. package/dist/esm/kasse/client.d.ts +10 -0
  156. package/dist/esm/kasse/client.js +33 -0
  157. package/dist/esm/kasse/drucker.d.ts +54 -0
  158. package/dist/esm/kasse/drucker.js +36 -0
  159. package/dist/esm/kasse/index.d.ts +11 -0
  160. package/dist/esm/kasse/index.js +13 -0
  161. package/dist/esm/kasse/settings.d.ts +115 -0
  162. package/dist/esm/kasse/settings.js +58 -0
  163. package/dist/esm/models/cancellation.d.ts +51 -0
  164. package/dist/esm/models/cancellation.js +40 -0
  165. package/dist/esm/models/cashregister.d.ts +77 -0
  166. package/dist/esm/models/cashregister.js +50 -0
  167. package/dist/esm/models/enum-payload.d.ts +26 -0
  168. package/dist/esm/models/enum-payload.js +44 -0
  169. package/dist/esm/models/hobex-receipt.d.ts +63 -0
  170. package/dist/esm/models/hobex-receipt.js +80 -0
  171. package/dist/esm/models/index.d.ts +10 -0
  172. package/dist/esm/models/index.js +10 -0
  173. package/dist/esm/models/receipt-company.d.ts +71 -0
  174. package/dist/esm/models/receipt-company.js +48 -0
  175. package/dist/esm/models/receipt-item.d.ts +100 -0
  176. package/dist/esm/models/receipt-item.js +101 -0
  177. package/dist/esm/models/receipt-summary.d.ts +92 -0
  178. package/dist/esm/models/receipt-summary.js +49 -0
  179. package/dist/esm/models/receipt.d.ts +108 -0
  180. package/dist/esm/models/receipt.js +113 -0
  181. package/dist/esm/models/report-month.d.ts +32 -0
  182. package/dist/esm/models/report-month.js +58 -0
  183. package/dist/esm/models/stripe-url-session.d.ts +18 -0
  184. package/dist/esm/models/stripe-url-session.js +16 -0
  185. package/dist/esm/models/voucher.d.ts +41 -0
  186. package/dist/esm/models/voucher.js +51 -0
  187. package/dist/esm/money.d.ts +23 -0
  188. package/dist/esm/money.js +31 -0
  189. package/dist/esm/payments/hobex.d.ts +87 -0
  190. package/dist/esm/payments/hobex.js +162 -0
  191. package/dist/esm/payments/index.d.ts +33 -0
  192. package/dist/esm/payments/index.js +33 -0
  193. package/dist/esm/payments/stripe.d.ts +61 -0
  194. package/dist/esm/payments/stripe.js +153 -0
  195. package/dist/esm/printing/escpos.d.ts +219 -0
  196. package/dist/esm/printing/escpos.js +616 -0
  197. package/dist/esm/printing/index.d.ts +3 -0
  198. package/dist/esm/printing/index.js +3 -0
  199. package/dist/esm/printing/printable.d.ts +27 -0
  200. package/dist/esm/printing/printable.js +87 -0
  201. package/dist/esm/printing/webusb.d.ts +89 -0
  202. package/dist/esm/printing/webusb.js +101 -0
  203. package/dist/esm/react/index.d.ts +46 -0
  204. package/dist/esm/react/index.js +47 -0
  205. package/dist/esm/receipt/discount.d.ts +12 -0
  206. package/dist/esm/receipt/discount.js +51 -0
  207. package/dist/esm/receipt/epos.d.ts +53 -0
  208. package/dist/esm/receipt/epos.js +86 -0
  209. package/dist/esm/receipt/grid.d.ts +47 -0
  210. package/dist/esm/receipt/grid.js +116 -0
  211. package/dist/esm/receipt/index.d.ts +4 -0
  212. package/dist/esm/receipt/index.js +4 -0
  213. package/dist/esm/receipt/layout-escpos.d.ts +35 -0
  214. package/dist/esm/receipt/layout-escpos.js +64 -0
  215. package/dist/esm/receipt/layout.d.ts +180 -0
  216. package/dist/esm/receipt/layout.js +583 -0
  217. package/dist/esm/register/index.d.ts +51 -0
  218. package/dist/esm/register/index.js +51 -0
  219. package/dist/esm/register/pairing.d.ts +248 -0
  220. package/dist/esm/register/pairing.js +270 -0
  221. package/dist/esm/register/session.d.ts +37 -0
  222. package/dist/esm/register/session.js +48 -0
  223. package/dist/esm/vienna-time.d.ts +23 -0
  224. package/dist/esm/vienna-time.js +110 -0
  225. package/fixtures/belege/langer-artikelname.json +43 -0
  226. package/fixtures/belege/null-ausfall.json +41 -0
  227. package/fixtures/belege/null-jahr.json +41 -0
  228. package/fixtures/belege/null-monat.json +41 -0
  229. package/fixtures/belege/null-pruef.json +41 -0
  230. package/fixtures/belege/null-schluss.json +41 -0
  231. package/fixtures/belege/null-start.json +40 -0
  232. package/fixtures/belege/rabattzeilen.json +61 -0
  233. package/fixtures/belege/signaturausfall-verkauf.json +49 -0
  234. package/fixtures/belege/storno-teil.json +48 -0
  235. package/fixtures/belege/storno-voll.json +54 -0
  236. package/fixtures/belege/testkasse-verkauf.json +50 -0
  237. package/fixtures/belege/testsignatur-verkauf.json +50 -0
  238. package/fixtures/belege/training.json +49 -0
  239. package/fixtures/belege/verkauf-bar.json +49 -0
  240. package/fixtures/belege/verkauf-karte.json +49 -0
  241. package/fixtures/belege/verkauf-kleinunternehmer.json +42 -0
  242. package/fixtures/erwartet/langer-artikelname.grid32.txt +25 -0
  243. package/fixtures/erwartet/langer-artikelname.grid48.txt +24 -0
  244. package/fixtures/erwartet/langer-artikelname.lines.json +216 -0
  245. package/fixtures/erwartet/null-ausfall.grid32.txt +28 -0
  246. package/fixtures/erwartet/null-ausfall.grid48.txt +25 -0
  247. package/fixtures/erwartet/null-ausfall.lines.json +220 -0
  248. package/fixtures/erwartet/null-jahr.grid32.txt +29 -0
  249. package/fixtures/erwartet/null-jahr.grid48.txt +25 -0
  250. package/fixtures/erwartet/null-jahr.lines.json +220 -0
  251. package/fixtures/erwartet/null-monat.grid32.txt +28 -0
  252. package/fixtures/erwartet/null-monat.grid48.txt +25 -0
  253. package/fixtures/erwartet/null-monat.lines.json +220 -0
  254. package/fixtures/erwartet/null-pruef.grid32.txt +28 -0
  255. package/fixtures/erwartet/null-pruef.grid48.txt +25 -0
  256. package/fixtures/erwartet/null-pruef.lines.json +220 -0
  257. package/fixtures/erwartet/null-schluss.grid32.txt +28 -0
  258. package/fixtures/erwartet/null-schluss.grid48.txt +25 -0
  259. package/fixtures/erwartet/null-schluss.lines.json +220 -0
  260. package/fixtures/erwartet/null-start.grid32.txt +28 -0
  261. package/fixtures/erwartet/null-start.grid48.txt +25 -0
  262. package/fixtures/erwartet/null-start.lines.json +220 -0
  263. package/fixtures/erwartet/rabattzeilen.grid32.txt +27 -0
  264. package/fixtures/erwartet/rabattzeilen.grid48.txt +26 -0
  265. package/fixtures/erwartet/rabattzeilen.lines.json +286 -0
  266. package/fixtures/erwartet/signaturausfall-verkauf.grid32.txt +28 -0
  267. package/fixtures/erwartet/signaturausfall-verkauf.grid48.txt +26 -0
  268. package/fixtures/erwartet/signaturausfall-verkauf.lines.json +266 -0
  269. package/fixtures/erwartet/storno-teil.grid32.txt +27 -0
  270. package/fixtures/erwartet/storno-teil.grid48.txt +26 -0
  271. package/fixtures/erwartet/storno-teil.lines.json +237 -0
  272. package/fixtures/erwartet/storno-voll.grid32.txt +29 -0
  273. package/fixtures/erwartet/storno-voll.grid48.txt +28 -0
  274. package/fixtures/erwartet/storno-voll.lines.json +277 -0
  275. package/fixtures/erwartet/testkasse-verkauf.grid32.txt +28 -0
  276. package/fixtures/erwartet/testkasse-verkauf.grid48.txt +27 -0
  277. package/fixtures/erwartet/testkasse-verkauf.lines.json +270 -0
  278. package/fixtures/erwartet/testsignatur-verkauf.grid32.txt +30 -0
  279. package/fixtures/erwartet/testsignatur-verkauf.grid48.txt +27 -0
  280. package/fixtures/erwartet/testsignatur-verkauf.lines.json +270 -0
  281. package/fixtures/erwartet/training.grid32.txt +33 -0
  282. package/fixtures/erwartet/training.grid48.txt +30 -0
  283. package/fixtures/erwartet/training.lines.json +277 -0
  284. package/fixtures/erwartet/verkauf-bar.grid32.txt +25 -0
  285. package/fixtures/erwartet/verkauf-bar.grid48.txt +24 -0
  286. package/fixtures/erwartet/verkauf-bar.lines.json +256 -0
  287. package/fixtures/erwartet/verkauf-karte.grid32.txt +25 -0
  288. package/fixtures/erwartet/verkauf-karte.grid48.txt +24 -0
  289. package/fixtures/erwartet/verkauf-karte.lines.json +256 -0
  290. package/fixtures/erwartet/verkauf-kleinunternehmer.grid32.txt +26 -0
  291. package/fixtures/erwartet/verkauf-kleinunternehmer.grid48.txt +25 -0
  292. package/fixtures/erwartet/verkauf-kleinunternehmer.lines.json +226 -0
  293. package/fixtures/manifest.json +107 -0
  294. package/package.json +135 -0
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ /**
3
+ * Unterpfad `@kreiseck/kasseneck-api/register` — die **Anmeldung der
4
+ * Browser-Kasse**: ein Geraet koppeln, seine Kassen-Benutzer auflisten, einen
5
+ * davon per PIN anmelden (mit oder ohne Benutzerauswahl), und die entstandene
6
+ * Sitzung erneuern bzw. beenden.
7
+ *
8
+ * Diese Aufrufe stehen vor allen anderen: ohne sie gibt es keine
9
+ * Identitaet, mit der ein Beleg entstehen koennte.
10
+ *
11
+ * **Sie zerfallen in zwei Haelften, und der Unterschied ist wesentlich:**
12
+ *
13
+ * | Aufruf | Anmeldung |
14
+ * |---|---|
15
+ * | [pairRegisterDevice] | **keine** — der Kopplungs-Code ist der Nachweis |
16
+ * | [listRegisterUsersForDevice] | **keine** — der Ausweis des Geraets ist der Nachweis |
17
+ * | [unpairRegisterDevice] | **keine** — der Ausweis des Geraets; sperrt es im Backend (Entkoppeln) |
18
+ * | [registerUserLogin] | **keine** — dieser Aufruf erzeugt sie |
19
+ * | [registerPinLogin] | **keine** — wie registerUserLogin, nur ohne Benutzerauswahl (Geraete-Modus `pin`) |
20
+ * | [renewRegisterSession] | Kassen-Benutzer (`registerUserAuth`) |
21
+ * | [endRegisterSession] | Kassen-Benutzer (`registerUserAuth`) |
22
+ *
23
+ * Die ersten drei nehmen deshalb **keinen Transport** entgegen, sondern nur
24
+ * die Verbindungsangaben, und bauen ihn selbst — die anmeldungsfreie Anmeldung
25
+ * dahinter wird bewusst nicht exportiert, sonst liesse sich damit jeder Aufruf
26
+ * des Pakets ohne Anmeldung bauen (ausfuehrlich in pairing.ts). Die letzten
27
+ * beiden nehmen den Transport wie jeder andere Endpunkt-Aufruf und stehen
28
+ * zusaetzlich in `createKasseneckApi`.
29
+ *
30
+ * Der uebliche Ablauf einer Browser-Kasse:
31
+ *
32
+ * ```ts
33
+ * import {
34
+ * pairRegisterDevice, listRegisterUsersForDevice, registerUserLogin,
35
+ * } from '@kreiseck/kasseneck-api/register';
36
+ *
37
+ * // Einmalig: Code aus dem Panel gegen den Geraeteausweis tauschen.
38
+ * const geraet = await pairRegisterDevice({ code: 'K7NPQR34', label: 'Schank' });
39
+ *
40
+ * // Bei jedem Schichtwechsel: auswaehlen und per PIN anmelden.
41
+ * const { users } = await listRegisterUsersForDevice(geraet);
42
+ * const sitzung = await registerUserLogin({
43
+ * ...geraet, userId: users[0]!.id, pin: '1234', cashregisterId: geraet.cashregisterId,
44
+ * });
45
+ * ```
46
+ *
47
+ * Mit `sitzung.customToken` meldet sich der Verbraucher bei Firebase an; das
48
+ * daraus entstehende ID-Token und `sitzung.sessionId` ergeben zusammen
49
+ * `registerUserAuth` — ab da laeuft alles Weitere ueber den ueblichen Weg.
50
+ */
51
+ Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.endRegisterSession = exports.renewRegisterSession = exports.registerPinLogin = exports.registerUserLogin = exports.unpairRegisterDevice = exports.listRegisterUsersForDevice = exports.pairRegisterDevice = void 0;
53
+ var pairing_js_1 = require("./pairing.js");
54
+ Object.defineProperty(exports, "pairRegisterDevice", { enumerable: true, get: function () { return pairing_js_1.pairRegisterDevice; } });
55
+ Object.defineProperty(exports, "listRegisterUsersForDevice", { enumerable: true, get: function () { return pairing_js_1.listRegisterUsersForDevice; } });
56
+ Object.defineProperty(exports, "unpairRegisterDevice", { enumerable: true, get: function () { return pairing_js_1.unpairRegisterDevice; } });
57
+ Object.defineProperty(exports, "registerUserLogin", { enumerable: true, get: function () { return pairing_js_1.registerUserLogin; } });
58
+ Object.defineProperty(exports, "registerPinLogin", { enumerable: true, get: function () { return pairing_js_1.registerPinLogin; } });
59
+ var session_js_1 = require("./session.js");
60
+ Object.defineProperty(exports, "renewRegisterSession", { enumerable: true, get: function () { return session_js_1.renewRegisterSession; } });
61
+ Object.defineProperty(exports, "endRegisterSession", { enumerable: true, get: function () { return session_js_1.endRegisterSession; } });
@@ -0,0 +1,248 @@
1
+ import { type TransportOptions } from '../client/transport.js';
2
+ import { type ReceiptCompany } from '../models/receipt-company.js';
3
+ import { type KasseSettings } from '../kasse/settings.js';
4
+ /**
5
+ * Verbindungsangaben ohne Anmeldung — alles, was [TransportOptions] ausser der
6
+ * Anmeldung fuehrt. Alle Felder sind wahlfrei: ohne Angabe gelten Basis-URL und
7
+ * Zeitlimit der Produktion und das globale `fetch`.
8
+ */
9
+ export type RegisterDeviceConnection = Omit<TransportOptions, 'auth'>;
10
+ /** Ausweis eines gekoppelten Geraets — Nachweis der beiden Folgeaufrufe. */
11
+ export interface RegisterDeviceCredentials {
12
+ /** Kunde, unter dem das Geraet haengt (aus der Kopplung). */
13
+ ownerUid: string;
14
+ /** Dieses Geraet (aus der Kopplung). */
15
+ deviceId: string;
16
+ /** Geheimnis dieses Geraets; das Backend liefert es genau einmal aus. */
17
+ deviceSecret: string;
18
+ }
19
+ /** Was das Geraet ueber sich sagt -- fuer das Panel (welches Geraet ist das?). Alles optional. */
20
+ export interface RegisterClientInfo {
21
+ userAgent?: string;
22
+ platform?: string;
23
+ language?: string;
24
+ /** IANA-Zeitzone, z. B. Europe/Vienna. */
25
+ tz?: string;
26
+ screen?: {
27
+ w: number;
28
+ h: number;
29
+ };
30
+ }
31
+ /** Standort aus der Browser-Ortung (freiwillig); Grundlage der Standortsperre. */
32
+ export interface RegisterGeo {
33
+ lat: number;
34
+ lng: number;
35
+ /** Genauigkeit in Metern. */
36
+ acc?: number;
37
+ }
38
+ /** Angaben, die Kopplung und Login zusaetzlich mitschicken duerfen. */
39
+ export interface RegisterGeraeteAngaben {
40
+ client?: RegisterClientInfo;
41
+ geo?: RegisterGeo | null;
42
+ }
43
+ export interface PairRegisterDeviceOptions extends RegisterDeviceConnection, RegisterGeraeteAngaben {
44
+ /**
45
+ * Achtstelliger Kopplungs-Code aus dem Panel. Er ist 15 Minuten gueltig,
46
+ * genau **einmal** verwendbar und gilt fuer eine bestimmte Kasse.
47
+ *
48
+ * Gross-/Kleinschreibung und Leerzeichen an den Raendern sind gleichgueltig:
49
+ * das Backend beschneidet und schreibt gross. Dieses Paket prueft das Format
50
+ * **nicht** — es kennt das Alphabet nicht und wuerde eine spaetere Erweiterung
51
+ * ausschliessen.
52
+ */
53
+ code: string;
54
+ /** Bezeichnung dieses Geraets in der Geraeteliste; ohne Angabe "Kasse". */
55
+ label?: string;
56
+ }
57
+ /** Ergebnis der Kopplung — der vollstaendige Ausweis dieses Geraets. */
58
+ export interface PairedRegisterDevice extends RegisterDeviceCredentials {
59
+ /** Kasse, an die die Kopplung dieses Geraet gebunden hat. */
60
+ cashregisterId: string;
61
+ /** Firmenname des Betriebs (Backend: `betrieb`) — Anzeige, kann leer sein. */
62
+ companyName: string;
63
+ /** Bezeichnung der Kasse (Backend: `kasse`) — Anzeige, kann leer sein. */
64
+ cashregisterLabel: string;
65
+ }
66
+ /**
67
+ * Art eines Kassen-Benutzers: eine Person oder ein Geraet (Sammelkonto). Ein
68
+ * kuenftiger, hier noch unbekannter Wert kommt unveraendert durch, statt still
69
+ * zu "person" zu werden — beim Lesen ist dieses Paket tolerant.
70
+ */
71
+ export type RegisterUserKind = 'person' | 'device' | (string & {});
72
+ /** Ein Kassen-Benutzer, wie ihn der Anmeldebildschirm zeigt. */
73
+ export interface RegisterUserSummary {
74
+ id: string;
75
+ /** Anzeigename; kann leer sein. */
76
+ name: string;
77
+ kind: RegisterUserKind;
78
+ /**
79
+ * Die PIN dieses Benutzers wurde noch nicht unter der aktuellen Regel des
80
+ * Betriebs gesetzt: die Kasse zeigt ihm das Freifeld statt der Kaestchen.
81
+ * Das Backend sendet das Feld nur, wenn es zutrifft; gelesen ist es immer da.
82
+ */
83
+ altbestand: boolean;
84
+ }
85
+ /** PIN-Regel des Betriebs — daraus baut die Kasse Kaestchen und Tastatur. */
86
+ export interface RegisterPinPolicy {
87
+ /** Feste Stellenzahl (Backend: 3 bis 6). */
88
+ stellen: number;
89
+ /** `ziffern` (nur 0-9) oder `zeichen` (0-9 plus Kopplungs-Alphabet). */
90
+ zeichen: 'ziffern' | 'zeichen' | (string & {});
91
+ }
92
+ /** Anmeldemodus des Geraets; ein unbekannter kuenftiger Wert kommt durch. */
93
+ export type RegisterLoginMode = 'auswahl' | 'pin' | (string & {});
94
+ /** Antwort von [listRegisterUsersForDevice]: Benutzer, Regel, Modus. */
95
+ export interface RegisterDeviceUsers {
96
+ /** Im Modus `pin` bewusst leer — Namen haben am nur-PIN-Geraet nichts verloren. */
97
+ users: RegisterUserSummary[];
98
+ /** Kassen-Einstellungen (betriebsweit + Geraet), gemischt mit den Standardwerten. */
99
+ settings: KasseSettings;
100
+ /** Belegkopf-Daten des Betriebs (Name, Anschrift, UID, Fusszeilen) -- ohne Geheimnisse. */
101
+ betriebsdaten: ReceiptCompany | null;
102
+ /**
103
+ * `null`, wenn das Backend (noch) keine Regel nennt — dann zeigt die Kasse
104
+ * das Freifeld, statt Kaestchen mit einer erratenen Stellenzahl.
105
+ */
106
+ policy: RegisterPinPolicy | null;
107
+ loginMode: RegisterLoginMode;
108
+ /** Der Betrieb verlangt die Ortung beim Login (Standortsperre an). */
109
+ standortsperre: boolean;
110
+ }
111
+ /**
112
+ * Rechte eines Kassen-Benutzers (Backend: `perms`, Vorlagen `PERMS_KASSIER`
113
+ * und `PERMS_CHEF`). Der Inhaber kann einzelne Rechte abweichend setzen,
114
+ * deshalb sind weitere Schluessel zugelassen.
115
+ *
116
+ * **Ein fehlendes Recht gilt als nicht erteilt.** Die Oberflaeche soll im
117
+ * Zweifel weniger anbieten, nicht mehr; die tatsaechliche Grenze zieht ohnehin
118
+ * das Backend.
119
+ */
120
+ /** Reichweite eines Rechts: keine | nur eigene Belege | alle. */
121
+ export type RegisterScope = 'none' | 'own' | 'all';
122
+ export interface RegisterUserPerms {
123
+ /** Belege ausstellen. */
124
+ sell: boolean;
125
+ /** Belege stornieren (Schalter, gespiegelt aus cancelScope !== 'none'). */
126
+ cancel: boolean;
127
+ /** Artikelstamm bearbeiten. */
128
+ articles: boolean;
129
+ /** Beleglayout/Kassen-Einstellungen bearbeiten (Chef). */
130
+ layout: boolean;
131
+ /** Berichte ansehen. */
132
+ reports: boolean;
133
+ /** Eine belegte Kasse uebernehmen (nur Kassen-Chef). */
134
+ takeover: boolean;
135
+ /** Storno-Reichweite; fehlt bei Altbestand (dann zaehlt `cancel`: true = all). */
136
+ cancelScope?: RegisterScope;
137
+ /** Belege ansehen; fehlt bei Altbestand (= all). */
138
+ receiptsScope?: RegisterScope;
139
+ /** Kassenlade ohne Verkauf oeffnen. */
140
+ drawer?: boolean;
141
+ /** Rabatt geben. */
142
+ discount?: boolean;
143
+ /** Trinkgeld anderen zuweisen. */
144
+ tipAssign?: boolean;
145
+ [weiteresRecht: string]: boolean | RegisterScope | undefined;
146
+ }
147
+ /** Reichweite lesen, mit der Migration des Backends (register-auth.js). */
148
+ export declare function cancelScopeOf(perms: RegisterUserPerms | null | undefined): RegisterScope;
149
+ export declare function receiptsScopeOf(perms: RegisterUserPerms | null | undefined): RegisterScope;
150
+ /** Der angemeldete Kassen-Benutzer. */
151
+ export interface RegisterUser {
152
+ id: string;
153
+ name: string;
154
+ perms: RegisterUserPerms;
155
+ }
156
+ /** Ergebnis der PIN-Anmeldung. */
157
+ export interface RegisterUserSession {
158
+ /**
159
+ * Firebase-Custom-Token. Damit meldet der Verbraucher sich bei Firebase an
160
+ * und bekommt das ID-Token, das `registerUserAuth` braucht; dieses Paket
161
+ * kennt Firebase nicht.
162
+ */
163
+ customToken: string;
164
+ /** Laufende Sitzung — Kopfzeile `register-session` jedes weiteren Aufrufs. */
165
+ sessionId: string;
166
+ /**
167
+ * Ablauf der Sitzung in Millisekunden seit 1970 (das Backend rechnet hier mit
168
+ * `Date.now()`, nicht mit Wiener Wanduhrzeit). Die Sitzung lebt 90 Sekunden
169
+ * und will alle 30 Sekunden erneuert werden.
170
+ */
171
+ expiresAt: number;
172
+ user: RegisterUser;
173
+ }
174
+ export interface ListRegisterUsersForDeviceOptions extends RegisterDeviceConnection, RegisterDeviceCredentials {
175
+ }
176
+ export interface RegisterUserLoginOptions extends RegisterDeviceConnection, RegisterDeviceCredentials, RegisterGeraeteAngaben {
177
+ /** Kassen-Benutzer aus [listRegisterUsersForDevice]. */
178
+ userId: string;
179
+ /**
180
+ * PIN dieses Benutzers. Das Format prueft dieses Paket **nicht**: eine zu
181
+ * strenge Pruefung im Client sperrte Benutzer aus, deren PIN das Panel anders
182
+ * gesetzt hat.
183
+ */
184
+ pin: string;
185
+ /** Kasse, an der die Sitzung eroeffnet wird. */
186
+ cashregisterId: string;
187
+ /**
188
+ * Eine belegte Kasse uebernehmen. Nur mit dem Recht `takeover` (Kassen-Chef);
189
+ * die aelteste laufende Sitzung wird dabei verdraengt. Ohne das Recht bleibt
190
+ * es bei der Abweisung "Kasse wird gerade auf … verwendet".
191
+ */
192
+ takeover?: boolean;
193
+ }
194
+ export interface RegisterPinLoginOptions extends RegisterDeviceConnection, RegisterDeviceCredentials, RegisterGeraeteAngaben {
195
+ /**
196
+ * Die PIN allein — sie identifiziert UND authentifiziert (Geraete-Modus
197
+ * `pin`; das Backend haelt PINs je Betrieb eindeutig). Das Format prueft
198
+ * dieses Paket **nicht** — dieselbe Zurueckhaltung wie bei
199
+ * [RegisterUserLoginOptions.pin].
200
+ */
201
+ pin: string;
202
+ /** Kasse, an der die Sitzung eroeffnet wird. */
203
+ cashregisterId: string;
204
+ /** Wie [RegisterUserLoginOptions.takeover]. */
205
+ takeover?: boolean;
206
+ }
207
+ /**
208
+ * Geraet koppeln: der Kopplungs-Code wird gegen den dauerhaften Ausweis dieses
209
+ * Geraets getauscht. **Ohne Anmeldung** — der Code ist der Nachweis.
210
+ *
211
+ * Er wird dabei verbraucht, auch wenn der Aufrufer das Ergebnis verliert: eine
212
+ * unvollstaendige Antwort ist deshalb ein Fehler und kein halbes Geraet (siehe
213
+ * [PairedRegisterDevice]).
214
+ */
215
+ export declare function pairRegisterDevice(options: PairRegisterDeviceOptions): Promise<PairedRegisterDevice>;
216
+ /**
217
+ * Kassen-Benutzer dieses Betriebs auflisten — die Auswahl des
218
+ * Anmeldebildschirms. **Ohne Anmeldung**; der Ausweis des Geraets ist der
219
+ * Nachweis.
220
+ *
221
+ * Die Antwort traegt ausschliesslich Kennung, Name und Art: keine Rechte, keine
222
+ * Kassen, keine Hashes. Gesperrte Benutzer fehlen bereits in der Antwort.
223
+ */
224
+ /**
225
+ * „Geraet entkoppeln“ an der Kasse selbst: das Geraet weist sich mit seinem
226
+ * Geheimnis aus und sperrt sich im Backend — damit sieht das Panel den
227
+ * Widerruf und keine Sitzung laeuft nach. Idempotent: ein schon gesperrtes
228
+ * Geraet meldet Erfolg. Danach das Geraet lokal vergessen.
229
+ */
230
+ export declare function unpairRegisterDevice(options: ListRegisterUsersForDeviceOptions): Promise<void>;
231
+ export declare function listRegisterUsersForDevice(options: ListRegisterUsersForDeviceOptions): Promise<RegisterDeviceUsers>;
232
+ /**
233
+ * Kassen-Benutzer per PIN anmelden. **Ohne Anmeldung** — dieser Aufruf
234
+ * erzeugt sie: das Custom Token der Antwort wird zum ID-Token, die `sessionId`
235
+ * zur Kopfzeile `register-session`. Beides zusammen ergibt `registerUserAuth`.
236
+ *
237
+ * Das Backend prueft in dieser Reihenfolge: Geraet, Benutzer, Sperre, PIN,
238
+ * Kassenzuweisung, Kopplungsbindung, Lizenzplatz. Fehlversuche zaehlen und
239
+ * sperren gestaffelt (ab dem fuenften 30 Sekunden, ab dem neunten 15 Minuten).
240
+ */
241
+ export declare function registerUserLogin(options: RegisterUserLoginOptions): Promise<RegisterUserSession>;
242
+ /**
243
+ * Kassen-Benutzer allein mit der PIN anmelden (Geraete-Modus `pin`). **Ohne
244
+ * Anmeldung** — wie [registerUserLogin], nur ohne Benutzerauswahl: das Backend
245
+ * ermittelt den Benutzer ueber die betriebsweit eindeutige PIN. Fehlversuche
246
+ * zaehlen und sperren dort am **Geraet**, nicht an einem Benutzer.
247
+ */
248
+ export declare function registerPinLogin(options: RegisterPinLoginOptions): Promise<RegisterUserSession>;
@@ -0,0 +1,279 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cancelScopeOf = cancelScopeOf;
4
+ exports.receiptsScopeOf = receiptsScopeOf;
5
+ exports.pairRegisterDevice = pairRegisterDevice;
6
+ exports.unpairRegisterDevice = unpairRegisterDevice;
7
+ exports.listRegisterUsersForDevice = listRegisterUsersForDevice;
8
+ exports.registerUserLogin = registerUserLogin;
9
+ exports.registerPinLogin = registerPinLogin;
10
+ const errors_js_1 = require("../client/errors.js");
11
+ const transport_js_1 = require("../client/transport.js");
12
+ const receipt_company_js_1 = require("../models/receipt-company.js");
13
+ const settings_js_1 = require("../kasse/settings.js");
14
+ /**
15
+ * Die drei Aufrufe, die **ohne jede Identitaet** laufen: Kopplung eines
16
+ * Geraets, Benutzerliste dieses Geraets, PIN-Anmeldung. Sie sind der Weg, auf
17
+ * dem eine Identitaet ueberhaupt erst entsteht — vor ihnen gibt es weder
18
+ * ID-Token noch Sitzung noch `api_key`.
19
+ *
20
+ * **Warum sie keine Anmeldung und keinen Transport entgegennehmen.** Alle
21
+ * uebrigen Endpunkt-Aufrufe dieses Pakets bekommen einen fertigen
22
+ * [KasseneckTransport] als ersten Parameter. Hier ginge das nur mit einer
23
+ * anmeldungsfreien Anmeldung — und die muesste dann exportiert sein. Genau das
24
+ * waere ein Schlupfloch: mit ihr liesse sich `createTransport` bzw.
25
+ * `createKasseneckApi` bauen und damit **jeder** Aufruf des Pakets ohne
26
+ * Anmeldung absetzen, auch `createReceipt`. Das Backend wiese das ab, aber ein
27
+ * Paket, das den Weg anbietet, sagt damit, dass es ihn gibt.
28
+ *
29
+ * Deshalb nehmen diese drei nur die **Verbindungsangaben** (Basis-URL,
30
+ * Zeitlimit, `fetch`) entgegen und bauen ihren Transport selbst — mit einer
31
+ * Anmeldung, die diese Datei nicht verlaesst. Damit gibt es im ganzen Paket
32
+ * keinen Weg, einen anmeldungsfreien Transport in die Hand zu bekommen.
33
+ *
34
+ * **Geheimnisse in der Nutzlast.** Diese drei Aufrufe fuehren Kopplungs-Code,
35
+ * Geraetegeheimnis und PIN — nicht in Kopfzeilen, sondern im Rumpf. Der
36
+ * Transport schuetzt seine Fehler von sich aus nur gegen die Werte, die er als
37
+ * Kopfzeilen gesendet hat (siehe client/errors.ts, `causeDigest`); hier ist
38
+ * diese Liste leer. Die Aufrufe nennen ihm ihre Geheimnisse deshalb
39
+ * ausdruecklich, sonst kaeme ein bezeichner-foermiges Geraetegeheimnis ueber
40
+ * die verdichtete Ursache eines Netzfehlers doch noch ins Protokoll.
41
+ */
42
+ /**
43
+ * Anmeldung, die keine ist: weder Kopfzeilen noch Zusatzparameter.
44
+ *
45
+ * **Nicht exportiert und niemals exportieren** — der Grund steht im
46
+ * Modulkommentar. Pro Aufruf ein frisches Objekt, wie die echten Anmeldungen
47
+ * es auch halten.
48
+ */
49
+ const ohneAnmeldung = () => ({ headers: {}, params: {} });
50
+ /** Reichweite lesen, mit der Migration des Backends (register-auth.js). */
51
+ function cancelScopeOf(perms) {
52
+ if (!perms)
53
+ return 'none';
54
+ if (perms.cancelScope !== undefined)
55
+ return ['none', 'own', 'all'].includes(perms.cancelScope) ? perms.cancelScope : 'none';
56
+ return perms.cancel === true ? 'all' : 'none';
57
+ }
58
+ function receiptsScopeOf(perms) {
59
+ if (!perms)
60
+ return 'none';
61
+ if (perms.receiptsScope === undefined)
62
+ return 'all';
63
+ return ['none', 'own', 'all'].includes(perms.receiptsScope) ? perms.receiptsScope : 'none';
64
+ }
65
+ /**
66
+ * Geraet koppeln: der Kopplungs-Code wird gegen den dauerhaften Ausweis dieses
67
+ * Geraets getauscht. **Ohne Anmeldung** — der Code ist der Nachweis.
68
+ *
69
+ * Er wird dabei verbraucht, auch wenn der Aufrufer das Ergebnis verliert: eine
70
+ * unvollstaendige Antwort ist deshalb ein Fehler und kein halbes Geraet (siehe
71
+ * [PairedRegisterDevice]).
72
+ */
73
+ async function pairRegisterDevice(options) {
74
+ const { code, label, client, geo, ...verbindung } = options;
75
+ pflicht('pairRegisterDevice', 'code', code);
76
+ // Der Code ist das Geheimnis dieses Aufrufs — siehe Modulkommentar.
77
+ const daten = await transportFuer(verbindung)('pairRegisterDevice', { code, label, client, geo: geo ?? undefined }, undefined, [code]);
78
+ return {
79
+ deviceId: pflichtfeld('pairRegisterDevice', daten, 'deviceId'),
80
+ deviceSecret: pflichtfeld('pairRegisterDevice', daten, 'deviceSecret'),
81
+ ownerUid: pflichtfeld('pairRegisterDevice', daten, 'ownerUid'),
82
+ cashregisterId: pflichtfeld('pairRegisterDevice', daten, 'cashregisterId'),
83
+ companyName: text(daten?.['betrieb']),
84
+ cashregisterLabel: text(daten?.['kasse']),
85
+ };
86
+ }
87
+ /**
88
+ * Kassen-Benutzer dieses Betriebs auflisten — die Auswahl des
89
+ * Anmeldebildschirms. **Ohne Anmeldung**; der Ausweis des Geraets ist der
90
+ * Nachweis.
91
+ *
92
+ * Die Antwort traegt ausschliesslich Kennung, Name und Art: keine Rechte, keine
93
+ * Kassen, keine Hashes. Gesperrte Benutzer fehlen bereits in der Antwort.
94
+ */
95
+ /**
96
+ * „Geraet entkoppeln“ an der Kasse selbst: das Geraet weist sich mit seinem
97
+ * Geheimnis aus und sperrt sich im Backend — damit sieht das Panel den
98
+ * Widerruf und keine Sitzung laeuft nach. Idempotent: ein schon gesperrtes
99
+ * Geraet meldet Erfolg. Danach das Geraet lokal vergessen.
100
+ */
101
+ async function unpairRegisterDevice(options) {
102
+ const { ownerUid, deviceId, deviceSecret, ...verbindung } = options;
103
+ const name = 'unpairRegisterDevice';
104
+ pflicht(name, 'ownerUid', ownerUid);
105
+ pflicht(name, 'deviceId', deviceId);
106
+ pflicht(name, 'deviceSecret', deviceSecret);
107
+ await transportFuer(verbindung)(name, { ownerUid, deviceId, deviceSecret }, undefined, [deviceSecret]);
108
+ }
109
+ async function listRegisterUsersForDevice(options) {
110
+ const { ownerUid, deviceId, deviceSecret, ...verbindung } = options;
111
+ const name = 'listRegisterUsersForDevice';
112
+ pflicht(name, 'ownerUid', ownerUid);
113
+ pflicht(name, 'deviceId', deviceId);
114
+ pflicht(name, 'deviceSecret', deviceSecret);
115
+ const daten = await transportFuer(verbindung)(name, { ownerUid, deviceId, deviceSecret }, undefined, [deviceSecret]);
116
+ const liste = daten?.users;
117
+ if (!Array.isArray(liste)) {
118
+ throw antwortfehler(name, 'Antwort enthaelt keine Benutzerliste (data.users fehlt)');
119
+ }
120
+ const users = liste.map((eintrag) => {
121
+ const roh = (typeof eintrag === 'object' && eintrag !== null ? eintrag : {});
122
+ return {
123
+ // Ein Eintrag ohne Kennung ist nicht anmeldbar — ihn anzuzeigen hiesse,
124
+ // dem Kassier eine Schaltflaeche zu geben, die nichts tun kann.
125
+ id: pflichtfeld(name, roh, 'id'),
126
+ name: text(roh['name']),
127
+ kind: typeof roh['kind'] === 'string' && roh['kind'] ? roh['kind'] : 'person',
128
+ altbestand: roh['altbestand'] === true,
129
+ };
130
+ });
131
+ const settingsRoh = (daten?.settings ?? {});
132
+ const settings = {
133
+ betrieb: (0, settings_js_1.mergeKasseSettings)(settings_js_1.KASSE_BETRIEB_STANDARD, (settingsRoh.betrieb ?? null)),
134
+ geraet: (0, settings_js_1.mergeKasseSettings)(settings_js_1.KASSE_GERAET_STANDARD, (settingsRoh.geraet ?? null)),
135
+ };
136
+ const bd = daten?.betriebsdaten;
137
+ const betriebsdaten = bd && typeof bd === 'object' ? (0, receipt_company_js_1.fromReceiptCompanyPayload)(bd) : null;
138
+ return { users, policy: regel(daten?.policy), loginMode: daten?.loginMode === 'pin' ? 'pin' : 'auswahl', settings, betriebsdaten, standortsperre: daten?.standortsperre === true };
139
+ }
140
+ /** Die Regel aus der Antwort — oder `null`, wenn keine brauchbare kommt. */
141
+ function regel(wert) {
142
+ if (typeof wert !== 'object' || wert === null || Array.isArray(wert))
143
+ return null;
144
+ const roh = wert;
145
+ const stellen = roh['stellen'];
146
+ const zeichen = roh['zeichen'];
147
+ if (typeof stellen !== 'number' || !Number.isInteger(stellen) || stellen < 1)
148
+ return null;
149
+ if (typeof zeichen !== 'string' || zeichen === '')
150
+ return null;
151
+ return { stellen, zeichen: zeichen };
152
+ }
153
+ /**
154
+ * Kassen-Benutzer per PIN anmelden. **Ohne Anmeldung** — dieser Aufruf
155
+ * erzeugt sie: das Custom Token der Antwort wird zum ID-Token, die `sessionId`
156
+ * zur Kopfzeile `register-session`. Beides zusammen ergibt `registerUserAuth`.
157
+ *
158
+ * Das Backend prueft in dieser Reihenfolge: Geraet, Benutzer, Sperre, PIN,
159
+ * Kassenzuweisung, Kopplungsbindung, Lizenzplatz. Fehlversuche zaehlen und
160
+ * sperren gestaffelt (ab dem fuenften 30 Sekunden, ab dem neunten 15 Minuten).
161
+ */
162
+ async function registerUserLogin(options) {
163
+ const { ownerUid, deviceId, deviceSecret, userId, pin, cashregisterId, takeover, client, geo, ...verbindung } = options;
164
+ const name = 'registerUserLogin';
165
+ pflicht(name, 'ownerUid', ownerUid);
166
+ pflicht(name, 'deviceId', deviceId);
167
+ pflicht(name, 'deviceSecret', deviceSecret);
168
+ pflicht(name, 'userId', userId);
169
+ pflicht(name, 'pin', pin);
170
+ pflicht(name, 'cashregisterId', cashregisterId);
171
+ const daten = await transportFuer(verbindung)(name, {
172
+ ownerUid,
173
+ deviceId,
174
+ deviceSecret,
175
+ userId,
176
+ pin,
177
+ cashregisterId,
178
+ // Nur die ausdrueckliche Uebernahme geht mit: das Backend prueft auf
179
+ // `=== true`, und ein mitgesendetes `false` waere nur Rauschen.
180
+ takeover: takeover === true ? true : undefined,
181
+ client, geo: geo ?? undefined,
182
+ }, undefined, [pin, deviceSecret]);
183
+ return sitzungAusAntwort(name, daten);
184
+ }
185
+ /**
186
+ * Kassen-Benutzer allein mit der PIN anmelden (Geraete-Modus `pin`). **Ohne
187
+ * Anmeldung** — wie [registerUserLogin], nur ohne Benutzerauswahl: das Backend
188
+ * ermittelt den Benutzer ueber die betriebsweit eindeutige PIN. Fehlversuche
189
+ * zaehlen und sperren dort am **Geraet**, nicht an einem Benutzer.
190
+ */
191
+ async function registerPinLogin(options) {
192
+ const { ownerUid, deviceId, deviceSecret, pin, cashregisterId, takeover, client, geo, ...verbindung } = options;
193
+ const name = 'registerPinLogin';
194
+ pflicht(name, 'ownerUid', ownerUid);
195
+ pflicht(name, 'deviceId', deviceId);
196
+ pflicht(name, 'deviceSecret', deviceSecret);
197
+ pflicht(name, 'pin', pin);
198
+ pflicht(name, 'cashregisterId', cashregisterId);
199
+ const daten = await transportFuer(verbindung)(name, {
200
+ ownerUid,
201
+ deviceId,
202
+ deviceSecret,
203
+ pin,
204
+ cashregisterId,
205
+ // Nur die ausdrueckliche Uebernahme geht mit — wie bei registerUserLogin.
206
+ takeover: takeover === true ? true : undefined,
207
+ client, geo: geo ?? undefined,
208
+ }, undefined, [pin, deviceSecret]);
209
+ return sitzungAusAntwort(name, daten);
210
+ }
211
+ /** Die Sitzungsantwort beider Anmeldewege — ein Vertrag, eine Lesart. */
212
+ function sitzungAusAntwort(name, daten) {
213
+ const roherBenutzer = daten?.['user'];
214
+ if (typeof roherBenutzer !== 'object' || roherBenutzer === null || Array.isArray(roherBenutzer)) {
215
+ throw antwortfehler(name, 'Antwort enthaelt keinen Benutzer (data.user fehlt)');
216
+ }
217
+ const benutzer = roherBenutzer;
218
+ const expiresAt = daten?.['expiresAt'];
219
+ if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt)) {
220
+ throw antwortfehler(name, 'Antwort enthaelt keinen Ablaufzeitpunkt (data.expiresAt fehlt)');
221
+ }
222
+ return {
223
+ customToken: pflichtfeld(name, daten, 'customToken'),
224
+ sessionId: pflichtfeld(name, daten, 'sessionId'),
225
+ expiresAt,
226
+ user: {
227
+ id: pflichtfeld(name, benutzer, 'id'),
228
+ name: text(benutzer['name']),
229
+ perms: rechte(benutzer['perms']),
230
+ },
231
+ };
232
+ }
233
+ /** Transport ohne Anmeldung; `auth` steht zuletzt und ist damit nicht zu ueberschreiben. */
234
+ function transportFuer(verbindung) {
235
+ return (0, transport_js_1.createTransport)({ ...verbindung, auth: ohneAnmeldung });
236
+ }
237
+ /**
238
+ * Pflichtangabe des Aufrufers. Die Meldung nennt das **Feld**, nie seinen Wert
239
+ * — das Feld heisst `pin`, `deviceSecret` oder `code`.
240
+ */
241
+ function pflicht(functionName, feld, wert) {
242
+ if (typeof wert !== 'string' || wert.trim() === '') {
243
+ throw new errors_js_1.KasseneckValidationError(functionName, `${feld} fehlt`, 'request');
244
+ }
245
+ }
246
+ /**
247
+ * Pflichtfeld der Antwort. Auch hier wandert **nichts aus der Antwort** in die
248
+ * Meldung; genannt wird nur, welches Feld fehlt.
249
+ */
250
+ function pflichtfeld(functionName, daten, feld) {
251
+ const wert = daten?.[feld];
252
+ if (typeof wert !== 'string' || wert === '') {
253
+ throw antwortfehler(functionName, `Antwort enthaelt kein Feld "${feld}"`);
254
+ }
255
+ return wert;
256
+ }
257
+ /** Rechte lesen: nur Wahrheitswerte, alles Fehlende gilt als nicht erteilt. */
258
+ function rechte(wert) {
259
+ const roh = (typeof wert === 'object' && wert !== null && !Array.isArray(wert) ? wert : {});
260
+ const gelesen = {};
261
+ for (const [name, inhalt] of Object.entries(roh)) {
262
+ gelesen[name] = inhalt === true;
263
+ }
264
+ return {
265
+ sell: false,
266
+ cancel: false,
267
+ articles: false,
268
+ layout: false,
269
+ reports: false,
270
+ takeover: false,
271
+ ...gelesen,
272
+ };
273
+ }
274
+ /** Leere Zeichenkette statt `undefined` — Anzeigefelder duerfen leer sein. */
275
+ const text = (wert) => (typeof wert === 'string' ? wert : '');
276
+ /** Die Antwort meldete Erfolg, trug aber nicht, was der Aufruf zusagt. */
277
+ function antwortfehler(functionName, grund) {
278
+ return new errors_js_1.KasseneckValidationError(functionName, grund, 'response');
279
+ }
@@ -0,0 +1,37 @@
1
+ import type { KasseneckTransport } from '../client/transport.js';
2
+ /**
3
+ * Die beiden Aufrufe der **laufenden** Kassen-Sitzung. Anders als die drei in
4
+ * pairing.ts haben sie eine Identitaet: sie laufen ueber `registerUserAuth`
5
+ * (ID-Token als Bearer, Sitzung als Kopfzeile `register-session`) und nehmen
6
+ * darum einen fertigen [KasseneckTransport] entgegen wie jeder andere
7
+ * Endpunkt-Aufruf dieses Pakets.
8
+ *
9
+ * Beide fuehren **keinen einzigen Parameter**: welche Sitzung gemeint ist,
10
+ * steht im Token und in der Kopfzeile. Der Parameter `cashregisterId`, den man
11
+ * im Rumpf sieht, kommt aus der Anmeldung.
12
+ *
13
+ * Das Backend setzt fuer beide `allowRegisterUser`; mit `apiKeyAuth` sind sie
14
+ * nicht erreichbar (dieses Paket bildet das nicht nach — wer darf, entscheidet
15
+ * das Backend).
16
+ */
17
+ /**
18
+ * Sitzung verlaengern und den neuen Ablaufzeitpunkt liefern (Millisekunden
19
+ * seit 1970).
20
+ *
21
+ * Die Sitzung lebt 90 Sekunden; die Browser-Kasse erneuert alle 30. Ist sie
22
+ * bereits beendet oder uebernommen, antwortet das Backend fachlich ("Sitzung
23
+ * beendet — bitte neu anmelden.") — dann hilft nur eine neue Anmeldung ueber
24
+ * `registerUserLogin`.
25
+ */
26
+ export declare function renewRegisterSession(rufen: KasseneckTransport): Promise<number>;
27
+ /**
28
+ * Sitzung beenden und den Lizenzplatz sofort freigeben — der regulaere Weg des
29
+ * Abmeldens.
30
+ *
31
+ * Das Backend antwortet mit `{ok:true}`; dieser Aufruf prueft das Feld
32
+ * **nicht**: dass der Vorgang gelang, sagt bereits die Erfolgshuelle, die der
33
+ * Transport auswertet. Eine zweite Pruefung derselben Aussage braeche nur an
34
+ * einer harmlosen Vertragsaenderung — ausgerechnet beim Abmelden, dem Aufruf,
35
+ * der auch dann durchgehen soll, wenn sonst nichts mehr geht.
36
+ */
37
+ export declare function endRegisterSession(rufen: KasseneckTransport): Promise<void>;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renewRegisterSession = renewRegisterSession;
4
+ exports.endRegisterSession = endRegisterSession;
5
+ const errors_js_1 = require("../client/errors.js");
6
+ /**
7
+ * Die beiden Aufrufe der **laufenden** Kassen-Sitzung. Anders als die drei in
8
+ * pairing.ts haben sie eine Identitaet: sie laufen ueber `registerUserAuth`
9
+ * (ID-Token als Bearer, Sitzung als Kopfzeile `register-session`) und nehmen
10
+ * darum einen fertigen [KasseneckTransport] entgegen wie jeder andere
11
+ * Endpunkt-Aufruf dieses Pakets.
12
+ *
13
+ * Beide fuehren **keinen einzigen Parameter**: welche Sitzung gemeint ist,
14
+ * steht im Token und in der Kopfzeile. Der Parameter `cashregisterId`, den man
15
+ * im Rumpf sieht, kommt aus der Anmeldung.
16
+ *
17
+ * Das Backend setzt fuer beide `allowRegisterUser`; mit `apiKeyAuth` sind sie
18
+ * nicht erreichbar (dieses Paket bildet das nicht nach — wer darf, entscheidet
19
+ * das Backend).
20
+ */
21
+ /**
22
+ * Sitzung verlaengern und den neuen Ablaufzeitpunkt liefern (Millisekunden
23
+ * seit 1970).
24
+ *
25
+ * Die Sitzung lebt 90 Sekunden; die Browser-Kasse erneuert alle 30. Ist sie
26
+ * bereits beendet oder uebernommen, antwortet das Backend fachlich ("Sitzung
27
+ * beendet — bitte neu anmelden.") — dann hilft nur eine neue Anmeldung ueber
28
+ * `registerUserLogin`.
29
+ */
30
+ async function renewRegisterSession(rufen) {
31
+ const daten = await rufen('renewRegisterSession');
32
+ const expiresAt = daten?.expiresAt;
33
+ if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt)) {
34
+ // Ohne brauchbaren Ablaufzeitpunkt weiss die Kasse nicht, wann sie das
35
+ // naechste Mal erneuern muss — das ist ein Antwortfehler und kein Erfolg.
36
+ throw new errors_js_1.KasseneckValidationError('renewRegisterSession', 'Antwort enthaelt keinen Ablaufzeitpunkt (data.expiresAt fehlt)', 'response');
37
+ }
38
+ return expiresAt;
39
+ }
40
+ /**
41
+ * Sitzung beenden und den Lizenzplatz sofort freigeben — der regulaere Weg des
42
+ * Abmeldens.
43
+ *
44
+ * Das Backend antwortet mit `{ok:true}`; dieser Aufruf prueft das Feld
45
+ * **nicht**: dass der Vorgang gelang, sagt bereits die Erfolgshuelle, die der
46
+ * Transport auswertet. Eine zweite Pruefung derselben Aussage braeche nur an
47
+ * einer harmlosen Vertragsaenderung — ausgerechnet beim Abmelden, dem Aufruf,
48
+ * der auch dann durchgehen soll, wenn sonst nichts mehr geht.
49
+ */
50
+ async function endRegisterSession(rufen) {
51
+ await rufen('endRegisterSession');
52
+ }