@coderoftime/fints 0.1.0 → 0.3.0

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 (289) hide show
  1. package/CHANGELOG.md +519 -1
  2. package/README.md +138 -40
  3. package/dist/client.d.ts +49 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +242 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/core/account.d.ts +46 -7
  8. package/dist/core/account.d.ts.map +1 -1
  9. package/dist/core/account.js +143 -24
  10. package/dist/core/account.js.map +1 -1
  11. package/dist/core/amount.d.ts +15 -4
  12. package/dist/core/amount.d.ts.map +1 -1
  13. package/dist/core/amount.js +46 -9
  14. package/dist/core/amount.js.map +1 -1
  15. package/dist/core/balance.d.ts +4 -0
  16. package/dist/core/balance.d.ts.map +1 -1
  17. package/dist/core/balance.js +11 -5
  18. package/dist/core/balance.js.map +1 -1
  19. package/dist/core/bank-info.d.ts +21 -4
  20. package/dist/core/bank-info.d.ts.map +1 -1
  21. package/dist/core/bank-info.js +26 -5
  22. package/dist/core/bank-info.js.map +1 -1
  23. package/dist/core/client.d.ts +81 -19
  24. package/dist/core/client.d.ts.map +1 -1
  25. package/dist/core/config.d.ts +40 -20
  26. package/dist/core/config.d.ts.map +1 -1
  27. package/dist/core/config.js +85 -30
  28. package/dist/core/config.js.map +1 -1
  29. package/dist/core/errors.d.ts +100 -26
  30. package/dist/core/errors.d.ts.map +1 -1
  31. package/dist/core/errors.js +136 -53
  32. package/dist/core/errors.js.map +1 -1
  33. package/dist/core/feedback.d.ts +11 -1
  34. package/dist/core/feedback.d.ts.map +1 -1
  35. package/dist/core/feedback.js +14 -2
  36. package/dist/core/feedback.js.map +1 -1
  37. package/dist/core/transaction.d.ts +11 -1
  38. package/dist/core/transaction.d.ts.map +1 -1
  39. package/dist/core/transaction.js +21 -4
  40. package/dist/core/transaction.js.map +1 -1
  41. package/dist/core/transport.d.ts +48 -6
  42. package/dist/core/transport.d.ts.map +1 -1
  43. package/dist/core/transport.js +126 -29
  44. package/dist/core/transport.js.map +1 -1
  45. package/dist/formats/camt.d.ts +28 -5
  46. package/dist/formats/camt.d.ts.map +1 -1
  47. package/dist/formats/camt.js +132 -50
  48. package/dist/formats/camt.js.map +1 -1
  49. package/dist/formats/mt940.d.ts +29 -5
  50. package/dist/formats/mt940.d.ts.map +1 -1
  51. package/dist/formats/mt940.js +209 -113
  52. package/dist/formats/mt940.js.map +1 -1
  53. package/dist/formats/readers.d.ts +6 -2
  54. package/dist/formats/readers.d.ts.map +1 -1
  55. package/dist/formats/readers.js +28 -29
  56. package/dist/formats/readers.js.map +1 -1
  57. package/dist/formats/record-budget.d.ts +7 -0
  58. package/dist/formats/record-budget.d.ts.map +1 -0
  59. package/dist/formats/record-budget.js +17 -0
  60. package/dist/formats/record-budget.js.map +1 -0
  61. package/dist/formats/sepa-purpose.d.ts +9 -0
  62. package/dist/formats/sepa-purpose.d.ts.map +1 -1
  63. package/dist/formats/sepa-purpose.js +32 -2
  64. package/dist/formats/sepa-purpose.js.map +1 -1
  65. package/dist/index.d.ts +3 -3
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +2 -2
  68. package/dist/index.js.map +1 -1
  69. package/dist/session/app-approval.d.ts +11 -5
  70. package/dist/session/app-approval.d.ts.map +1 -1
  71. package/dist/session/app-approval.js +23 -12
  72. package/dist/session/app-approval.js.map +1 -1
  73. package/dist/session/dialog-runner.d.ts +11 -11
  74. package/dist/session/dialog-runner.d.ts.map +1 -1
  75. package/dist/session/dialog-runner.js +34 -19
  76. package/dist/session/dialog-runner.js.map +1 -1
  77. package/dist/session/login-guard.d.ts +54 -49
  78. package/dist/session/login-guard.d.ts.map +1 -1
  79. package/dist/session/login-guard.js +170 -83
  80. package/dist/session/login-guard.js.map +1 -1
  81. package/dist/session/sepa-accounts.d.ts +20 -14
  82. package/dist/session/sepa-accounts.d.ts.map +1 -1
  83. package/dist/session/sepa-accounts.js +62 -46
  84. package/dist/session/sepa-accounts.js.map +1 -1
  85. package/dist/session/session-setup.d.ts +41 -24
  86. package/dist/session/session-setup.d.ts.map +1 -1
  87. package/dist/session/session-setup.js +106 -63
  88. package/dist/session/session-setup.js.map +1 -1
  89. package/dist/session/session-state.d.ts +10 -6
  90. package/dist/session/session-state.d.ts.map +1 -1
  91. package/dist/session/session-state.js +72 -18
  92. package/dist/session/session-state.js.map +1 -1
  93. package/dist/session/signed-dialog.d.ts +83 -0
  94. package/dist/session/signed-dialog.d.ts.map +1 -0
  95. package/dist/session/signed-dialog.js +185 -0
  96. package/dist/session/signed-dialog.js.map +1 -0
  97. package/dist/session/tan-selection.d.ts +26 -18
  98. package/dist/session/tan-selection.d.ts.map +1 -1
  99. package/dist/session/tan-selection.js +44 -33
  100. package/dist/session/tan-selection.js.map +1 -1
  101. package/dist/session/user-prompts.d.ts +14 -5
  102. package/dist/session/user-prompts.d.ts.map +1 -1
  103. package/dist/session/user-prompts.js +53 -18
  104. package/dist/session/user-prompts.js.map +1 -1
  105. package/dist/tan/challenge.d.ts +47 -24
  106. package/dist/tan/challenge.d.ts.map +1 -1
  107. package/dist/tan/challenge.js +56 -51
  108. package/dist/tan/challenge.js.map +1 -1
  109. package/dist/tan/flicker.d.ts +11 -1
  110. package/dist/tan/flicker.d.ts.map +1 -1
  111. package/dist/tan/flicker.js +70 -24
  112. package/dist/tan/flicker.js.map +1 -1
  113. package/dist/tan/tan-image.d.ts +6 -2
  114. package/dist/tan/tan-image.d.ts.map +1 -1
  115. package/dist/tan/tan-image.js +14 -6
  116. package/dist/tan/tan-image.js.map +1 -1
  117. package/dist/tan/tan-models.d.ts +14 -2
  118. package/dist/tan/tan-models.d.ts.map +1 -1
  119. package/dist/tan/tan-models.js +24 -7
  120. package/dist/tan/tan-models.js.map +1 -1
  121. package/dist/util/arguments.d.ts +13 -0
  122. package/dist/util/arguments.d.ts.map +1 -0
  123. package/dist/util/arguments.js +40 -0
  124. package/dist/util/arguments.js.map +1 -0
  125. package/dist/util/async.d.ts +4 -3
  126. package/dist/util/async.d.ts.map +1 -1
  127. package/dist/util/async.js +6 -7
  128. package/dist/util/async.js.map +1 -1
  129. package/dist/util/bytes.d.ts +3 -4
  130. package/dist/util/bytes.d.ts.map +1 -1
  131. package/dist/util/bytes.js +13 -21
  132. package/dist/util/bytes.js.map +1 -1
  133. package/dist/util/call-context.d.ts.map +1 -1
  134. package/dist/util/call-context.js +3 -2
  135. package/dist/util/call-context.js.map +1 -1
  136. package/dist/util/dates.d.ts +6 -20
  137. package/dist/util/dates.d.ts.map +1 -1
  138. package/dist/util/dates.js +58 -28
  139. package/dist/util/dates.js.map +1 -1
  140. package/dist/util/errors.d.ts +13 -3
  141. package/dist/util/errors.d.ts.map +1 -1
  142. package/dist/util/errors.js +19 -6
  143. package/dist/util/errors.js.map +1 -1
  144. package/dist/util/immutable-map.d.ts +5 -2
  145. package/dist/util/immutable-map.d.ts.map +1 -1
  146. package/dist/util/immutable-map.js +15 -12
  147. package/dist/util/immutable-map.js.map +1 -1
  148. package/dist/util/inspect.d.ts +11 -0
  149. package/dist/util/inspect.d.ts.map +1 -0
  150. package/dist/util/inspect.js +14 -0
  151. package/dist/util/inspect.js.map +1 -0
  152. package/dist/util/json.d.ts +4 -0
  153. package/dist/util/json.d.ts.map +1 -1
  154. package/dist/util/json.js +18 -0
  155. package/dist/util/json.js.map +1 -1
  156. package/dist/util/text.d.ts +38 -5
  157. package/dist/util/text.d.ts.map +1 -1
  158. package/dist/util/text.js +90 -16
  159. package/dist/util/text.js.map +1 -1
  160. package/dist/util/xml.d.ts +9 -6
  161. package/dist/util/xml.d.ts.map +1 -1
  162. package/dist/util/xml.js +129 -56
  163. package/dist/util/xml.js.map +1 -1
  164. package/dist/v3/account-extension.d.ts.map +1 -1
  165. package/dist/v3/account-extension.js +7 -10
  166. package/dist/v3/account-extension.js.map +1 -1
  167. package/dist/v3/bank-connection.d.ts +54 -0
  168. package/dist/v3/bank-connection.d.ts.map +1 -0
  169. package/dist/v3/bank-connection.js +118 -0
  170. package/dist/v3/bank-connection.js.map +1 -0
  171. package/dist/v3/dialog.d.ts +84 -46
  172. package/dist/v3/dialog.d.ts.map +1 -1
  173. package/dist/v3/dialog.js +174 -60
  174. package/dist/v3/dialog.js.map +1 -1
  175. package/dist/v3/message.d.ts +32 -11
  176. package/dist/v3/message.d.ts.map +1 -1
  177. package/dist/v3/message.js +144 -83
  178. package/dist/v3/message.js.map +1 -1
  179. package/dist/v3/parameter-store.d.ts +111 -0
  180. package/dist/v3/parameter-store.d.ts.map +1 -0
  181. package/dist/v3/parameter-store.js +197 -0
  182. package/dist/v3/parameter-store.js.map +1 -0
  183. package/dist/v3/parameters.d.ts +44 -17
  184. package/dist/v3/parameters.d.ts.map +1 -1
  185. package/dist/v3/parameters.js +136 -60
  186. package/dist/v3/parameters.js.map +1 -1
  187. package/dist/v3/protocol.d.ts +50 -50
  188. package/dist/v3/protocol.d.ts.map +1 -1
  189. package/dist/v3/protocol.js +91 -210
  190. package/dist/v3/protocol.js.map +1 -1
  191. package/dist/v3/queries.d.ts +51 -0
  192. package/dist/v3/queries.d.ts.map +1 -0
  193. package/dist/v3/queries.js +128 -0
  194. package/dist/v3/queries.js.map +1 -0
  195. package/dist/v3/segments.d.ts +43 -19
  196. package/dist/v3/segments.d.ts.map +1 -1
  197. package/dist/v3/segments.js +84 -33
  198. package/dist/v3/segments.js.map +1 -1
  199. package/dist/v3/syntax.d.ts +68 -13
  200. package/dist/v3/syntax.d.ts.map +1 -1
  201. package/dist/v3/syntax.js +183 -102
  202. package/dist/v3/syntax.js.map +1 -1
  203. package/package.json +10 -6
  204. package/src/client.ts +293 -0
  205. package/src/core/account.ts +153 -24
  206. package/src/core/amount.ts +45 -10
  207. package/src/core/balance.ts +12 -5
  208. package/src/core/bank-info.ts +29 -5
  209. package/src/core/client.ts +83 -19
  210. package/src/core/config.ts +95 -35
  211. package/src/core/errors.ts +148 -54
  212. package/src/core/feedback.ts +16 -2
  213. package/src/core/transaction.ts +22 -4
  214. package/src/core/transport.ts +153 -32
  215. package/src/formats/camt.ts +153 -45
  216. package/src/formats/mt940.ts +244 -122
  217. package/src/formats/readers.ts +28 -31
  218. package/src/formats/record-budget.ts +18 -0
  219. package/src/formats/sepa-purpose.ts +29 -2
  220. package/src/index.ts +4 -2
  221. package/src/session/app-approval.ts +51 -38
  222. package/src/session/dialog-runner.ts +61 -31
  223. package/src/session/login-guard.ts +189 -87
  224. package/src/session/sepa-accounts.ts +63 -45
  225. package/src/session/session-setup.ts +105 -68
  226. package/src/session/session-state.ts +74 -23
  227. package/src/session/signed-dialog.ts +222 -0
  228. package/src/session/tan-selection.ts +50 -39
  229. package/src/session/user-prompts.ts +62 -18
  230. package/src/tan/challenge.ts +87 -64
  231. package/src/tan/flicker.ts +72 -23
  232. package/src/tan/tan-image.ts +15 -6
  233. package/src/tan/tan-models.ts +26 -7
  234. package/src/util/arguments.ts +40 -0
  235. package/src/util/async.ts +10 -9
  236. package/src/util/bytes.ts +14 -20
  237. package/src/util/call-context.ts +3 -2
  238. package/src/util/dates.ts +64 -33
  239. package/src/util/errors.ts +22 -6
  240. package/src/util/immutable-map.ts +15 -12
  241. package/src/util/inspect.ts +14 -0
  242. package/src/util/json.ts +16 -0
  243. package/src/util/text.ts +87 -15
  244. package/src/util/xml.ts +130 -52
  245. package/src/v3/account-extension.ts +7 -12
  246. package/src/v3/bank-connection.ts +126 -0
  247. package/src/v3/dialog.ts +186 -92
  248. package/src/v3/message.ts +140 -79
  249. package/src/v3/parameter-store.ts +226 -0
  250. package/src/v3/parameters.ts +166 -66
  251. package/src/v3/protocol.ts +103 -253
  252. package/src/v3/queries.ts +198 -0
  253. package/src/v3/segments.ts +86 -31
  254. package/src/v3/syntax.ts +172 -93
  255. package/dist/session/bank-connection.d.ts +0 -28
  256. package/dist/session/bank-connection.d.ts.map +0 -1
  257. package/dist/session/bank-connection.js +0 -48
  258. package/dist/session/bank-connection.js.map +0 -1
  259. package/dist/session/parameter-data.d.ts +0 -83
  260. package/dist/session/parameter-data.d.ts.map +0 -1
  261. package/dist/session/parameter-data.js +0 -68
  262. package/dist/session/parameter-data.js.map +0 -1
  263. package/dist/session/pin-tan-client.d.ts +0 -54
  264. package/dist/session/pin-tan-client.d.ts.map +0 -1
  265. package/dist/session/pin-tan-client.js +0 -153
  266. package/dist/session/pin-tan-client.js.map +0 -1
  267. package/dist/session/pin-tan-dialog.d.ts +0 -71
  268. package/dist/session/pin-tan-dialog.d.ts.map +0 -1
  269. package/dist/session/pin-tan-dialog.js +0 -124
  270. package/dist/session/pin-tan-dialog.js.map +0 -1
  271. package/dist/session/protocol.d.ts +0 -209
  272. package/dist/session/protocol.d.ts.map +0 -1
  273. package/dist/session/protocol.js +0 -75
  274. package/dist/session/protocol.js.map +0 -1
  275. package/dist/session/response-handler.d.ts +0 -48
  276. package/dist/session/response-handler.d.ts.map +0 -1
  277. package/dist/session/response-handler.js +0 -121
  278. package/dist/session/response-handler.js.map +0 -1
  279. package/dist/v3/client.d.ts +0 -24
  280. package/dist/v3/client.d.ts.map +0 -1
  281. package/dist/v3/client.js +0 -16
  282. package/dist/v3/client.js.map +0 -1
  283. package/src/session/bank-connection.ts +0 -51
  284. package/src/session/parameter-data.ts +0 -137
  285. package/src/session/pin-tan-client.ts +0 -186
  286. package/src/session/pin-tan-dialog.ts +0 -160
  287. package/src/session/protocol.ts +0 -311
  288. package/src/session/response-handler.ts +0 -130
  289. package/src/v3/client.ts +0 -29
@@ -1,59 +1,69 @@
1
- import { PinTanDialog } from '../session/pin-tan-dialog.js';
2
- import type { Approval, StartWithOrder } from '../session/protocol.js';
1
+ import { TanChallenge } from '../tan/challenge.js';
3
2
  import { TanMethod } from '../tan/tan-models.js';
4
3
  import { IncomingMessage3 } from './message.js';
5
- import type { Bpd3 } from './parameters.js';
4
+ import type { FinTs3Protocol } from './protocol.js';
6
5
  import type { SegmentSpec } from './syntax.js';
7
- /** How a message is signed: the security function of the TAN method and the customer system ID. */
8
- export interface Signing3 {
9
- readonly securityFunction: string;
10
- readonly systemId: string;
11
- }
12
- /**
13
- * What a dialog needs from the session: the parameter data received so far, the segments that open a dialog, and the
14
- * way to the bank. The `FinTs3Protocol` provides it, and keeps the login data and the PIN to itself.
15
- */
16
- export interface FinTs3DialogHost {
17
- /** The bank parameter data received so far, if any. */
18
- readonly bankParameters: Bpd3 | undefined;
19
- /** The customer system ID the bank assigned; `undefined` before the synchronization. */
20
- readonly systemId: string | undefined;
21
- /** Identification (HKIDN) and processing preparation (HKVVB), which open every dialog. */
22
- initSegments(systemId: string, anonymous?: boolean): SegmentSpec[];
6
+ /** The bank's request to approve a message with a TAN or in a banking app; `R` is the bank's answer. */
7
+ export interface Approval<R> {
8
+ /** What the user is asked. */
9
+ readonly challenge: TanChallenge;
10
+ /** Sends the TAN the user entered. */
11
+ readonly submitTan: (tan: string) => Promise<R>;
12
+ /** Asks the bank whether the user has approved in the banking app. */
13
+ readonly checkStatus: () => Promise<R>;
23
14
  /**
24
- * Sends `segments` as message `number` of the dialog `dialogId` and returns the bank's answer, not yet parsed.
25
- *
26
- * With `signing` the message is signed with the PIN and the `tan`, after `LoginGuard.check`; without, it goes out
27
- * unsigned, as in an anonymous dialog.
15
+ * Whether the bank announces a push message for once the user has approved (return code 3957), before which the
16
+ * status must not be asked. The client has no push channel, so the user reports the approval instead.
28
17
  */
29
- post(message: {
30
- dialogId: string;
31
- number: number;
32
- segments: readonly SegmentSpec[];
33
- signing: Signing3 | undefined;
34
- tan: string | undefined;
35
- }): Promise<Uint8Array>;
18
+ readonly waitForPush: boolean;
19
+ /** The new instructions a status answer gives the user (return code 3956); `undefined` where it gives none. */
20
+ readonly instructionsIn: (response: R) => string | undefined;
36
21
  }
37
- /** One FinTS 3.0 dialog: numbered messages under the dialog ID the bank assigns in its first answer. */
38
- export declare class FinTs3Dialog extends PinTanDialog<IncomingMessage3, SegmentSpec> {
39
- private readonly host;
22
+ /**
23
+ * One FinTS 3.0 dialog: numbered messages under the dialog ID the bank assigns in its first answer, signed with a TAN
24
+ * method and medium, and the approvals the bank asks for. The `FinTs3Protocol` builds the messages and signs them.
25
+ */
26
+ export declare class FinTs3Dialog {
27
+ private readonly protocol;
28
+ readonly method: TanMethod;
29
+ /** The TAN medium the messages name, where the method takes one. */
30
+ readonly tanMedium: string | undefined;
40
31
  private readonly anonymous;
41
32
  private systemId;
42
33
  private id;
34
+ private messageNumber;
35
+ private ended;
36
+ /** When the bank last answered without rejecting the whole message, which shows it still knows the dialog. */
37
+ private lastAnswer;
43
38
  private constructor();
44
- static signed(host: FinTs3DialogHost, method: TanMethod, tanMedium?: string): FinTs3Dialog;
39
+ static signed(protocol: FinTs3Protocol, method: TanMethod, tanMedium?: string): FinTs3Dialog;
45
40
  /** A dialog without login, which only delivers the bank parameter data. */
46
- static anonymous(host: FinTs3DialogHost): FinTs3Dialog;
47
- protected get bankParameters(): Bpd3 | undefined;
41
+ static anonymous(protocol: FinTs3Protocol): FinTs3Dialog;
42
+ /** Whether the bank knows this dialog and it has not ended. */
48
43
  get isActive(): boolean;
44
+ /**
45
+ * Whether the dialog has ended, on either side.
46
+ *
47
+ * The bank ends a dialog idle for longer than its maximum timeout (HIBPA, Formals C.9), or five minutes where it
48
+ * states none. Such a dialog is neither used nor ended again: the bank would refuse any message in it.
49
+ */
50
+ private get hasEnded();
51
+ private get idleTooLong();
52
+ /** Whether the messages are signed with a two-step TAN method, so that the bank may ask for approvals. */
53
+ private get isTwoStep();
49
54
  /** The version of the HKTAN segments: that of the HITANS segment the bank describes the method in. */
50
55
  private get tanVersion();
56
+ /** Opens the dialog; with `synchronize` the bank also assigns a customer system ID. */
51
57
  start(synchronize?: boolean): Promise<IncomingMessage3>;
52
58
  /**
53
- * Opens the dialog, asking strong authentication for `order` with a two-step method, then sends `order` in the next
54
- * message.
59
+ * The messages that open the dialog and send `order` while no TAN medium is chosen yet, as for listing the media:
60
+ * `login` opens the dialog, asking strong authentication for `order` with a two-step method, and `order` sends the
61
+ * order in a message of its own.
55
62
  */
56
- startWith(order: SegmentSpec): StartWithOrder<IncomingMessage3>;
63
+ startWith(order: SegmentSpec): {
64
+ readonly login: () => Promise<IncomingMessage3>;
65
+ readonly order: () => Promise<IncomingMessage3>;
66
+ };
57
67
  /**
58
68
  * Opens the anonymous dialog; the answer carries the bank parameter data.
59
69
  *
@@ -61,18 +71,46 @@ export declare class FinTs3Dialog extends PinTanDialog<IncomingMessage3, Segment
61
71
  * tells the bank so, whereupon the bank may send parameter data suited to it (PIN/TAN, B.4.3.1).
62
72
  */
63
73
  requestBankParameters(announceSca?: boolean): Promise<IncomingMessage3>;
74
+ /** Sends `order`, asking for strong customer authentication where the bank requires it. */
64
75
  send(order: SegmentSpec): Promise<IncomingMessage3>;
65
- protected sendEnd(): Promise<void>;
76
+ /**
77
+ * Ends the dialog at the bank and returns the answer; `undefined` if the dialog is not active or the end failed.
78
+ *
79
+ * Bank and connection errors are ignored, since the bank may have ended the dialog on its side already.
80
+ */
81
+ end(): Promise<IncomingMessage3 | undefined>;
82
+ /** Forgets the dialog without contacting the bank, for example after the bank rejected the PIN. */
83
+ discard(): void;
84
+ /**
85
+ * The approval `response`, the dialog's latest answer, asks for with return code 0030 (TAN) or 3955 (banking app):
86
+ * HITAN of process 4, answered with HKTAN process 2 (TAN) or S (status); `undefined` if it asks for none, or carries
87
+ * only the dummy challenge of a message the bank exempts from strong authentication.
88
+ *
89
+ * The bank has not executed the message then, so a request without a challenge is a `FinTsProtocolError`: read as
90
+ * done, it would report an empty result. So is an app approval with a method of HITANS #6: the status request
91
+ * (process S) came with version 7, along with app approvals (PIN/TAN B.5.2).
92
+ */
93
+ approvalAskedIn(response: IncomingMessage3): Approval<IncomingMessage3> | undefined;
66
94
  private tanRequest;
67
95
  /**
68
- * The approval a HITAN segment of process 4 asks for, answered with HKTAN process 2 (TAN) or S (status).
96
+ * Sends `segments`, with `tan` where they complete an approval, as the next message, and reads the bank's answer. The
97
+ * message counts once the bank has answered, whatever it answered.
98
+ *
99
+ * The bank assigns the dialog ID in its answer to the first message, so the answer to another user's first message
100
+ * passes for it (`ParameterStore.reportedUpdVersion`). Any other answer to another message fails with
101
+ * `FinTsProtocolError` before anything of it is kept: a relay or proxy that mixes up answers would hand the client
102
+ * another user's data, or a page of another query. Only the bank's dialog abort message may name the dialog or the
103
+ * message as unknown instead (`IncomingMessage3.aborts`), so that its text reaches the user.
104
+ *
105
+ * The dialog ends on the client's side, without a dialog end, where it is over for the bank: after a return code that
106
+ * ends it, such as 9800, a dialog abort message, a rejected opening message (Formals C.1.2), or a broken connection
107
+ * (C.6). A request that fails while the client is closing, as one it aborts (`FinTs3Protocol.beginClose`), leaves the
108
+ * dialog active instead, since the bank may have received it: its end follows under the next number. Not so where
109
+ * the request opened the dialog, whose ID only the answer tells.
69
110
  *
70
- * Throws `FinTsProtocolError` for an app approval with a method of HITANS #6: the status request (process S) came with
71
- * version 7, along with app approvals (PIN/TAN B.5.2).
111
+ * Only an answer that does not reject the whole message starts the idle time anew (`hasEnded`): a rejection may come
112
+ * from a bank that has ended the dialog without saying so.
72
113
  */
73
- protected approvalIn(response: IncomingMessage3): Approval<IncomingMessage3> | undefined;
74
114
  private sendSegments;
75
- /** The bank assigns the dialog ID in its answer to the first message. */
76
- protected readDialogData(response: IncomingMessage3): void;
77
115
  }
78
116
  //# sourceMappingURL=dialog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/v3/dialog.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAW/C,mGAAmG;AACnG,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,QAAQ,CAAC,cAAc,EAAE,IAAI,GAAG,SAAS,CAAC;IAE1C,wFAAwF;IACxF,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,0FAA0F;IAC1F,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,WAAW,EAAE,CAAC;IAEnE;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;QACjC,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC;QAC9B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;KACzB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACzB;AAED,wGAAwG;AACxG,qBAAa,YAAa,SAAQ,YAAY,CAAC,gBAAgB,EAAE,WAAW,CAAC;IAKzE,OAAO,CAAC,QAAQ,CAAC,IAAI;IAGrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAP5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,EAAE,CAAc;IAExB,OAAO;IAUP,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY;IAI1F,2EAA2E;IAC3E,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY;IAItD,SAAS,KAAK,cAAc,IAAI,IAAI,GAAG,SAAS,CAE/C;IAED,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,sGAAsG;IACtG,OAAO,KAAK,UAAU,GAErB;IAED,KAAK,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IASrD;;;OAGG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,cAAc,CAAC,gBAAgB,CAAC;IAW/D;;;;;OAKG;IACH,qBAAqB,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAOrE,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC;cAKnC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxC,OAAO,CAAC,UAAU;IAIlB;;;;;OAKG;IACH,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,GAAG,SAAS;IAoBxF,OAAO,CAAC,YAAY;IAgBpB,yEAAyE;IACzE,SAAS,CAAC,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;CAG3D"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/v3/dialog.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB/C,wGAAwG;AACxG,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,8BAA8B;IAC9B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IAEjC,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAEhD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAEvC;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAE9B,+GAA+G;IAC/G,QAAQ,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,CAAC;CAC9D;AAED;;;GAGG;AACH,qBAAa,YAAY;IAUrB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAb5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,KAAK,CAAS;IAEtB,8GAA8G;IAC9G,OAAO,CAAC,UAAU,CAAqB;IAEvC,OAAO;IAUP,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY;IAI5F,2EAA2E;IAC3E,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,YAAY;IAIxD,+DAA+D;IAC/D,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;;OAKG;IACH,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,KAAK,WAAW,GAMtB;IAED,0GAA0G;IAC1G,OAAO,KAAK,SAAS,GAEpB;IAED,sGAAsG;IACtG,OAAO,KAAK,UAAU,GAErB;IAED,uFAAuF;IACvF,KAAK,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IASrD;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG;QAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;QAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,gBAAgB,CAAC,CAAC;KACjD;IAWD;;;;;OAKG;IACH,qBAAqB,CAAC,WAAW,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAOrE,2FAA2F;IAC3F,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAMnD;;;;OAIG;IACG,GAAG,IAAI,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAWlD,mGAAmG;IACnG,OAAO,IAAI,IAAI;IAIf;;;;;;;;OAQG;IACH,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,GAAG,SAAS;IAgCnF,OAAO,CAAC,UAAU;IASlB;;;;;;;;;;;;;;;;;;OAkBG;YACW,YAAY;CAgC3B"}
package/dist/v3/dialog.js CHANGED
@@ -1,63 +1,100 @@
1
1
  // Internal to the package, and named after the FinTS specification. Documentation is where the meaning is not evident.
2
- import { FinTsProtocolError } from '../core/errors.js';
3
- import { FeedbackCodes, hasCode } from '../core/feedback.js';
4
- import { requireBankParameters } from '../session/parameter-data.js';
5
- import { PinTanDialog } from '../session/pin-tan-dialog.js';
2
+ import { FinTsError, FinTsProtocolError, FinTsTransportError, parseBankData } from '../core/errors.js';
3
+ import { endsDialog, FeedbackCodes, hasCode, hasErrors } from '../core/feedback.js';
4
+ import { challengeText, TanChallenge } from '../tan/challenge.js';
6
5
  import { TanMethod } from '../tan/tan-models.js';
7
6
  import { IncomingMessage3 } from './message.js';
8
- import { Segments, TanResponse } from './segments.js';
7
+ import { requireBankParameters } from './parameters.js';
8
+ import { noReference, Segments, TanResponse } from './segments.js';
9
9
  /** Dialog ID of a dialog the bank has not answered yet, and customer system ID before synchronization. */
10
10
  const unassigned = '0';
11
11
  /** The first version of HKTAN that supports strong customer authentication. */
12
12
  const firstScaVersion = 6;
13
13
  /** The first version of HKTAN that supports app approvals, with the status request (process S). */
14
14
  const firstDecoupledVersion = 7;
15
- /** One FinTS 3.0 dialog: numbered messages under the dialog ID the bank assigns in its first answer. */
16
- export class FinTs3Dialog extends PinTanDialog {
17
- host;
15
+ /**
16
+ * How long a dialog may stay idle where the bank states no timeout: on the safe side, since a dialog given up too early
17
+ * only costs a new login, while one kept too long fails the next call.
18
+ */
19
+ const defaultIdleLimitMs = 5 * 60_000;
20
+ /**
21
+ * One FinTS 3.0 dialog: numbered messages under the dialog ID the bank assigns in its first answer, signed with a TAN
22
+ * method and medium, and the approvals the bank asks for. The `FinTs3Protocol` builds the messages and signs them.
23
+ */
24
+ export class FinTs3Dialog {
25
+ protocol;
26
+ method;
27
+ tanMedium;
18
28
  anonymous;
19
29
  systemId;
20
30
  id = unassigned;
21
- constructor(host, method, tanMedium, anonymous) {
22
- super(method, tanMedium);
23
- this.host = host;
31
+ messageNumber = 1;
32
+ ended = false;
33
+ /** When the bank last answered without rejecting the whole message, which shows it still knows the dialog. */
34
+ lastAnswer;
35
+ constructor(protocol, method,
36
+ /** The TAN medium the messages name, where the method takes one. */
37
+ tanMedium, anonymous) {
38
+ this.protocol = protocol;
39
+ this.method = method;
40
+ this.tanMedium = tanMedium;
24
41
  this.anonymous = anonymous;
25
- this.systemId = anonymous ? unassigned : (host.systemId ?? unassigned);
42
+ this.systemId = anonymous ? unassigned : (protocol.parameters.systemId ?? unassigned);
26
43
  }
27
- static signed(host, method, tanMedium) {
28
- return new FinTs3Dialog(host, method, tanMedium, false);
44
+ static signed(protocol, method, tanMedium) {
45
+ return new FinTs3Dialog(protocol, method, tanMedium, false);
29
46
  }
30
47
  /** A dialog without login, which only delivers the bank parameter data. */
31
- static anonymous(host) {
32
- return new FinTs3Dialog(host, TanMethod.oneStep, undefined, true);
33
- }
34
- get bankParameters() {
35
- return this.host.bankParameters;
48
+ static anonymous(protocol) {
49
+ return new FinTs3Dialog(protocol, TanMethod.oneStep, undefined, true);
36
50
  }
51
+ /** Whether the bank knows this dialog and it has not ended. */
37
52
  get isActive() {
38
53
  return this.id !== unassigned && !this.hasEnded;
39
54
  }
55
+ /**
56
+ * Whether the dialog has ended, on either side.
57
+ *
58
+ * The bank ends a dialog idle for longer than its maximum timeout (HIBPA, Formals C.9), or five minutes where it
59
+ * states none. Such a dialog is neither used nor ended again: the bank would refuse any message in it.
60
+ */
61
+ get hasEnded() {
62
+ return this.ended || this.idleTooLong;
63
+ }
64
+ get idleTooLong() {
65
+ const last = this.lastAnswer;
66
+ const timeout = this.protocol.parameters.bankParameters?.bankInfo.maxTimeout;
67
+ // A timeout of 0 or below: the bank keeps idle dialogs without limit.
68
+ const limit = timeout === undefined ? defaultIdleLimitMs : timeout <= 0 ? undefined : timeout * 1000;
69
+ return last !== undefined && limit !== undefined && Date.now() - last > limit;
70
+ }
71
+ /** Whether the messages are signed with a two-step TAN method, so that the bank may ask for approvals. */
72
+ get isTwoStep() {
73
+ return !this.method.isOneStep;
74
+ }
40
75
  /** The version of the HKTAN segments: that of the HITANS segment the bank describes the method in. */
41
76
  get tanVersion() {
42
- return this.bankParameters?.tanVersion(this.method) ?? firstScaVersion;
77
+ return this.protocol.parameters.bankParameters?.tanVersion(this.method) ?? firstScaVersion;
43
78
  }
79
+ /** Opens the dialog; with `synchronize` the bank also assigns a customer system ID. */
44
80
  start(synchronize = false) {
45
81
  if (synchronize)
46
82
  this.systemId = unassigned;
47
83
  return this.sendSegments([
48
- ...this.host.initSegments(this.systemId),
84
+ ...this.protocol.initSegments(this.systemId),
49
85
  ...(this.isTwoStep ? [this.tanRequest('HKIDN')] : []),
50
86
  ...(synchronize ? [Segments.synchronization()] : []),
51
87
  ]);
52
88
  }
53
89
  /**
54
- * Opens the dialog, asking strong authentication for `order` with a two-step method, then sends `order` in the next
55
- * message.
90
+ * The messages that open the dialog and send `order` while no TAN medium is chosen yet, as for listing the media:
91
+ * `login` opens the dialog, asking strong authentication for `order` with a two-step method, and `order` sends the
92
+ * order in a message of its own.
56
93
  */
57
94
  startWith(order) {
58
95
  return {
59
96
  login: () => this.sendSegments([
60
- ...this.host.initSegments(this.systemId),
97
+ ...this.protocol.initSegments(this.systemId),
61
98
  ...(this.isTwoStep ? [this.tanRequest(order.type)] : []),
62
99
  ]),
63
100
  order: () => this.sendSegments([order]),
@@ -71,61 +108,138 @@ export class FinTs3Dialog extends PinTanDialog {
71
108
  */
72
109
  requestBankParameters(announceSca = false) {
73
110
  return this.sendSegments([
74
- ...this.host.initSegments(unassigned, true),
111
+ ...this.protocol.initSegments(unassigned, true),
75
112
  ...(announceSca ? [Segments.tanProcess4(firstScaVersion, 'HKIDN')] : []),
76
113
  ]);
77
114
  }
115
+ /** Sends `order`, asking for strong customer authentication where the bank requires it. */
78
116
  send(order) {
79
- const needsTan = this.isTwoStep && requireBankParameters(this.bankParameters).pinTan.requiresTan(order.type);
117
+ const needsTan = this.isTwoStep && requireBankParameters(this.protocol.parameters.bankParameters).pinTan.requiresTan(order.type);
80
118
  return this.sendSegments([order, ...(needsTan ? [this.tanRequest(order.type)] : [])]);
81
119
  }
82
- async sendEnd() {
83
- await this.sendSegments([Segments.dialogEnd(this.id)]);
120
+ /**
121
+ * Ends the dialog at the bank and returns the answer; `undefined` if the dialog is not active or the end failed.
122
+ *
123
+ * Bank and connection errors are ignored, since the bank may have ended the dialog on its side already.
124
+ */
125
+ async end() {
126
+ if (!this.isActive)
127
+ return undefined;
128
+ this.ended = true;
129
+ try {
130
+ return await this.sendSegments([Segments.dialogEnd(this.id)]);
131
+ }
132
+ catch (error) {
133
+ if (!(error instanceof FinTsError))
134
+ throw error;
135
+ return undefined;
136
+ }
84
137
  }
85
- tanRequest(segmentType) {
86
- return Segments.tanProcess4(this.tanVersion, segmentType, this.mediumName);
138
+ /** Forgets the dialog without contacting the bank, for example after the bank rejected the PIN. */
139
+ discard() {
140
+ this.ended = true;
87
141
  }
88
142
  /**
89
- * The approval a HITAN segment of process 4 asks for, answered with HKTAN process 2 (TAN) or S (status).
143
+ * The approval `response`, the dialog's latest answer, asks for with return code 0030 (TAN) or 3955 (banking app):
144
+ * HITAN of process 4, answered with HKTAN process 2 (TAN) or S (status); `undefined` if it asks for none, or carries
145
+ * only the dummy challenge of a message the bank exempts from strong authentication.
90
146
  *
91
- * Throws `FinTsProtocolError` for an app approval with a method of HITANS #6: the status request (process S) came with
92
- * version 7, along with app approvals (PIN/TAN B.5.2).
147
+ * The bank has not executed the message then, so a request without a challenge is a `FinTsProtocolError`: read as
148
+ * done, it would report an empty result. So is an app approval with a method of HITANS #6: the status request
149
+ * (process S) came with version 7, along with app approvals (PIN/TAN B.5.2).
93
150
  */
94
- approvalIn(response) {
95
- const tan = tanResponseOf(response, '4');
96
- if (tan === undefined || tan.isDummy)
151
+ approvalAskedIn(response) {
152
+ const feedback = response.feedback;
153
+ const decoupled = hasCode(feedback, FeedbackCodes.decoupledPending);
154
+ if (hasErrors(feedback) || !(hasCode(feedback, FeedbackCodes.tanRequired) || decoupled))
97
155
  return undefined;
98
- if (hasCode(response.feedback, FeedbackCodes.decoupledPending) && this.tanVersion < firstDecoupledVersion) {
156
+ const tan = tanResponseOf(response, '4');
157
+ if (tan === undefined || tan.isDummy) {
158
+ throw new FinTsProtocolError('The bank asks for an approval, but sends no challenge');
159
+ }
160
+ if (decoupled && this.tanVersion < firstDecoupledVersion) {
99
161
  throw new FinTsProtocolError('The bank asks for an app approval, which needs HKTAN version 7');
100
162
  }
101
163
  const reference = tan.reference;
102
- return this.approvalOf(response, {
103
- reference,
104
- message: tan.challenge,
105
- hhdUc: tan.hhdUc,
106
- validUntil: tan.validUntil,
107
- tanMediumName: tan.mediumName,
164
+ // The placeholder the dialog that looks up the TAN media sends, and the bank may echo, is no medium.
165
+ const medium = tan.mediumName ?? this.tanMedium;
166
+ return {
167
+ challenge: TanChallenge.create({
168
+ method: this.method,
169
+ reference,
170
+ message: tan.challenge,
171
+ hhdUc: tan.hhdUc,
172
+ isDecoupled: decoupled || this.method.decoupled,
173
+ validUntil: tan.validUntil,
174
+ tanMediumName: medium === noReference ? undefined : medium,
175
+ }),
108
176
  submitTan: (value) => this.sendSegments([Segments.tanProcess2(this.tanVersion, reference)], value),
109
177
  checkStatus: () => this.sendSegments([Segments.tanProcessStatus(this.tanVersion, reference)]),
178
+ waitForPush: hasCode(feedback, FeedbackCodes.decoupledWaitForPush),
110
179
  // A status answer that the approval is still pending may carry new instructions (PIN/TAN B.4.2.2.1, step 2b).
111
- instructionsIn: (status) => tanResponseOf(status, 'S')?.challenge,
112
- });
113
- }
114
- sendSegments(segments, tan) {
115
- return this.transmit((number) => this.host.post({
116
- dialogId: this.id,
117
- number,
118
- segments,
119
- signing: this.anonymous
120
- ? undefined
121
- : { securityFunction: this.method.securityFunction, systemId: this.systemId },
122
- tan,
123
- }), (answer) => IncomingMessage3.parse(answer));
124
- }
125
- /** The bank assigns the dialog ID in its answer to the first message. */
126
- readDialogData(response) {
127
- if (this.id === unassigned)
180
+ instructionsIn: (status) => challengeText(tanResponseOf(status, 'S')?.challenge),
181
+ };
182
+ }
183
+ tanRequest(segmentType) {
184
+ const medium = this.method.mediumRequirement === 'notAllowed' ? undefined : this.tanMedium;
185
+ return Segments.tanProcess4(this.tanVersion, segmentType, medium === undefined ? undefined : this.protocol.parameters.tanMediumToSend(medium));
186
+ }
187
+ /**
188
+ * Sends `segments`, with `tan` where they complete an approval, as the next message, and reads the bank's answer. The
189
+ * message counts once the bank has answered, whatever it answered.
190
+ *
191
+ * The bank assigns the dialog ID in its answer to the first message, so the answer to another user's first message
192
+ * passes for it (`ParameterStore.reportedUpdVersion`). Any other answer to another message fails with
193
+ * `FinTsProtocolError` before anything of it is kept: a relay or proxy that mixes up answers would hand the client
194
+ * another user's data, or a page of another query. Only the bank's dialog abort message may name the dialog or the
195
+ * message as unknown instead (`IncomingMessage3.aborts`), so that its text reaches the user.
196
+ *
197
+ * The dialog ends on the client's side, without a dialog end, where it is over for the bank: after a return code that
198
+ * ends it, such as 9800, a dialog abort message, a rejected opening message (Formals C.1.2), or a broken connection
199
+ * (C.6). A request that fails while the client is closing, as one it aborts (`FinTs3Protocol.beginClose`), leaves the
200
+ * dialog active instead, since the bank may have received it: its end follows under the next number. Not so where
201
+ * the request opened the dialog, whose ID only the answer tells.
202
+ *
203
+ * Only an answer that does not reject the whole message starts the idle time anew (`hasEnded`): a rejection may come
204
+ * from a bank that has ended the dialog without saying so.
205
+ */
206
+ async sendSegments(segments, tan) {
207
+ const number = this.messageNumber;
208
+ let answer;
209
+ try {
210
+ answer = await this.protocol.post({
211
+ dialogId: this.id,
212
+ number,
213
+ segments,
214
+ signing: this.anonymous
215
+ ? undefined
216
+ : { securityFunction: this.method.securityFunction, systemId: this.systemId },
217
+ tan,
218
+ });
219
+ }
220
+ catch (error) {
221
+ if (error instanceof FinTsTransportError) {
222
+ if (this.protocol.isClosing && this.id !== unassigned)
223
+ this.messageNumber++;
224
+ else
225
+ this.discard();
226
+ }
227
+ throw error;
228
+ }
229
+ this.messageNumber++;
230
+ const response = parseBankData(() => IncomingMessage3.parse(answer));
231
+ const assigned = this.id === unassigned ? undefined : this.id;
232
+ const aborted = response.aborts(number, assigned);
233
+ if (!aborted && !response.answers(number, assigned)) {
234
+ throw new FinTsProtocolError('The answer belongs to another message than the one sent');
235
+ }
236
+ if (assigned === undefined)
128
237
  this.id = response.dialogId ?? unassigned;
238
+ if (!response.messageRejected)
239
+ this.lastAnswer = Date.now();
240
+ if (aborted || endsDialog(response.feedback) || (number === 1 && response.messageRejected))
241
+ this.discard();
242
+ return response;
129
243
  }
130
244
  }
131
245
  /** The TAN part of `response` that answers TAN `process`. */
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/v3/dialog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/v3/dialog.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { BankMessage } from '../core/bank-info.js';
2
2
  import { FinTsFeedback } from '../core/feedback.js';
3
- import type { BankResponse } from '../session/protocol.js';
4
3
  import { type Segment, SegmentSpec } from './syntax.js';
5
4
  /** Signature data of a PIN/TAN message. */
6
5
  export interface PinTanCredentials {
@@ -14,12 +13,12 @@ export interface PinTanCredentials {
14
13
  /** A message to send, and the same message with PIN and TAN masked for logging. */
15
14
  export declare class OutgoingMessage {
16
15
  readonly bytes: Uint8Array;
17
- /** The parts of the masked message, each decoded on its own as the bank's text is. */
18
- private readonly maskedParts;
19
- constructor(bytes: Uint8Array,
20
- /** The parts of the masked message, each decoded on its own as the bank's text is. */
21
- maskedParts: readonly Uint8Array[]);
22
- /** The message with PIN and TAN masked; decoded only when a logger asks for it. */
16
+ private readonly buildMasked;
17
+ constructor(bytes: Uint8Array, buildMasked: () => Uint8Array);
18
+ /**
19
+ * The message with PIN and TAN masked; built only when a logger asks for it. It is decoded as a whole, as the bank's
20
+ * text is, so a message that mixes ISO 8859-1 text with UTF-8 text (`encodeText`) shows all of it as ISO 8859-1.
21
+ */
23
22
  get masked(): string;
24
23
  }
25
24
  /**
@@ -28,7 +27,8 @@ export declare class OutgoingMessage {
28
27
  * With `security` the segments are signed with PIN and optional `tan` (HNSHK … HNSHA) and wrapped in the encryption
29
28
  * envelope (HNVSK, HNVSD) that PIN/TAN uses without actual encryption.
30
29
  *
31
- * The masked message states the sizes of its masked content, so that the log does not tell how long PIN and TAN are.
30
+ * The masked message is built as the message is, from the same time stamp and security control reference, with `***`
31
+ * for PIN and TAN, so that the log does not tell how long they are.
32
32
  */
33
33
  export declare function buildMessage(parts: {
34
34
  dialogId: string;
@@ -39,8 +39,9 @@ export declare function buildMessage(parts: {
39
39
  now?: Date;
40
40
  }): OutgoingMessage;
41
41
  /** A received message, with the segments of the encryption envelope unpacked. */
42
- export declare class IncomingMessage3 implements BankResponse {
42
+ export declare class IncomingMessage3 {
43
43
  readonly segments: readonly Segment[];
44
+ /** The memory the message holds, in bytes: its length, and what its parts take beyond that. */
44
45
  readonly size: number;
45
46
  /**
46
47
  * Return codes for the whole message (HIRMG), then for single request segments (HIRMS).
@@ -49,16 +50,36 @@ export declare class IncomingMessage3 implements BankResponse {
49
50
  * approval reports on the order of an earlier message (PIN/TAN B.4.2.1).
50
51
  */
51
52
  readonly feedback: readonly FinTsFeedback[];
53
+ /** Whether the bank rejected the message as a whole (an error in HIRMG), rather than single orders in it. */
52
54
  readonly messageRejected: boolean;
53
55
  private constructor();
54
56
  /**
55
- * Parses a message; throws `FormatError` if `data` is not a FinTS message, such as the HTML page of a proxy or a
56
- * maintenance notice.
57
+ * Parses a message; throws `FormatError` if `data` is not one complete FinTS message, such as the HTML page of a
58
+ * proxy, a maintenance notice, a message cut short, which lacks the message trailer (HNHBS) at its end, or two
59
+ * messages run together, whose second would pass for part of the first. It does as well for more than one encrypted
60
+ * part (HNVSD), each of which `parseSegments` would allow as many data elements as the whole message.
61
+ *
62
+ * Its `size` counts the memory of the data elements it keeps along with its bytes, since a message of many short
63
+ * elements takes far more memory than bytes.
57
64
  */
58
65
  static parse(data: Uint8Array): IncomingMessage3;
59
66
  static combine(first: IncomingMessage3, second: IncomingMessage3): IncomingMessage3;
67
+ /** Free-text messages the bank addresses to the user. */
60
68
  get bankMessages(): BankMessage[];
69
+ /** The dialog ID the bank assigned, as `Segment.verbatim` reads it, to send back byte for byte. */
61
70
  get dialogId(): string | undefined;
71
+ /**
72
+ * Whether the message answers message `number` of the dialog `dialogId`: header and trailer carry that number, and the
73
+ * header names that message where it names the message it refers to (Bezugsnachricht). The dialog ID counts only once
74
+ * the bank has assigned one; before, `dialogId` is `undefined`, since every first message goes out under the same.
75
+ */
76
+ answers(number: number, dialogId: string | undefined): boolean;
77
+ /**
78
+ * Whether the message is the bank's dialog abort message (Formals B.7.6) for message `number` of the dialog
79
+ * `dialogId`: unencrypted, with nothing but the header, an error for the whole message (HIRMG) and the trailer. Its
80
+ * header names the dialog ID and the message number where the bank knows them, and `unbekannt` and 9999 where not.
81
+ */
82
+ aborts(number: number, dialogId: string | undefined): boolean;
62
83
  find(type: string): Segment | undefined;
63
84
  findAll(type: string): Segment[];
64
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/v3/message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAM3D,OAAO,EAAyB,KAAK,OAAO,EAAE,WAAW,EAAqB,MAAM,aAAa,CAAC;AAElG,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AA+DD,mFAAmF;AACnF,qBAAa,eAAe;IAExB,QAAQ,CAAC,KAAK,EAAE,UAAU;IAC1B,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAFnB,KAAK,EAAE,UAAU;IAC1B,sFAAsF;IACrE,WAAW,EAAE,SAAS,UAAU,EAAE;IAGrD,mFAAmF;IACnF,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF;AASD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,eAAe,CAelB;AAgFD,iFAAiF;AACjF,qBAAa,gBAAiB,YAAW,YAAY;IAYjD,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAZvB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAE5C,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAElC,OAAO;IAaP;;;OAGG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB;IAehD,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB;IAInF,IAAI,YAAY,IAAI,WAAW,EAAE,CAEhC;IAED,IAAI,QAAQ,IAAI,MAAM,GAAG,SAAS,CAEjC;IAED,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE;CAGjC;AAeD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAQ5D;AAaD,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CAE/D"}
1
+ {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/v3/message.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMpD,OAAO,EAIL,KAAK,OAAO,EACZ,WAAW,EAGZ,MAAM,aAAa,CAAC;AAErB,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAmED,mFAAmF;AACnF,qBAAa,eAAe;IAExB,QAAQ,CAAC,KAAK,EAAE,UAAU;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADnB,KAAK,EAAE,UAAU,EACT,WAAW,EAAE,MAAM,UAAU;IAGhD;;;OAGG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF;AAQD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ,GAAG,eAAe,CAWlB;AAgED,iFAAiF;AACjF,qBAAa,gBAAgB;IAazB,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE;IACrC,+FAA+F;IAC/F,QAAQ,CAAC,IAAI,EAAE,MAAM;IAdvB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;IAE5C,6GAA6G;IAC7G,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAElC,OAAO;IAcP;;;;;;;;OAQG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB;IAgChD,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB;IAInF,yDAAyD;IACzD,IAAI,YAAY,IAAI,WAAW,EAAE,CAEhC;IAED,mGAAmG;IACnG,IAAI,QAAQ,IAAI,MAAM,GAAG,SAAS,CAEjC;IAED;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;IAe9D;;;;OAIG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;IAY7D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE;CAGjC;AAmBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAS5D;AAaD,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CAE/D"}