@coderoftime/fints 0.0.0-stage → 0.1.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 (254) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE +28 -0
  3. package/README.md +156 -2
  4. package/dist/core/account.d.ts +140 -0
  5. package/dist/core/account.d.ts.map +1 -0
  6. package/dist/core/account.js +174 -0
  7. package/dist/core/account.js.map +1 -0
  8. package/dist/core/amount.d.ts +62 -0
  9. package/dist/core/amount.d.ts.map +1 -0
  10. package/dist/core/amount.js +189 -0
  11. package/dist/core/amount.js.map +1 -0
  12. package/dist/core/balance.d.ts +54 -0
  13. package/dist/core/balance.d.ts.map +1 -0
  14. package/dist/core/balance.js +53 -0
  15. package/dist/core/balance.js.map +1 -0
  16. package/dist/core/bank-info.d.ts +49 -0
  17. package/dist/core/bank-info.d.ts.map +1 -0
  18. package/dist/core/bank-info.js +52 -0
  19. package/dist/core/bank-info.js.map +1 -0
  20. package/dist/core/client.d.ts +126 -0
  21. package/dist/core/client.d.ts.map +1 -0
  22. package/dist/core/client.js +2 -0
  23. package/dist/core/client.js.map +1 -0
  24. package/dist/core/config.d.ts +68 -0
  25. package/dist/core/config.d.ts.map +1 -0
  26. package/dist/core/config.js +113 -0
  27. package/dist/core/config.js.map +1 -0
  28. package/dist/core/errors.d.ts +91 -0
  29. package/dist/core/errors.d.ts.map +1 -0
  30. package/dist/core/errors.js +182 -0
  31. package/dist/core/errors.js.map +1 -0
  32. package/dist/core/feedback.d.ts +69 -0
  33. package/dist/core/feedback.d.ts.map +1 -0
  34. package/dist/core/feedback.js +124 -0
  35. package/dist/core/feedback.js.map +1 -0
  36. package/dist/core/transaction.d.ts +98 -0
  37. package/dist/core/transaction.d.ts.map +1 -0
  38. package/dist/core/transaction.js +91 -0
  39. package/dist/core/transaction.js.map +1 -0
  40. package/dist/core/transport.d.ts +37 -0
  41. package/dist/core/transport.d.ts.map +1 -0
  42. package/dist/core/transport.js +92 -0
  43. package/dist/core/transport.js.map +1 -0
  44. package/dist/formats/camt.d.ts +12 -0
  45. package/dist/formats/camt.d.ts.map +1 -0
  46. package/dist/formats/camt.js +159 -0
  47. package/dist/formats/camt.js.map +1 -0
  48. package/dist/formats/mt940.d.ts +42 -0
  49. package/dist/formats/mt940.d.ts.map +1 -0
  50. package/dist/formats/mt940.js +297 -0
  51. package/dist/formats/mt940.js.map +1 -0
  52. package/dist/formats/readers.d.ts +11 -0
  53. package/dist/formats/readers.d.ts.map +1 -0
  54. package/dist/formats/readers.js +47 -0
  55. package/dist/formats/readers.js.map +1 -0
  56. package/dist/formats/sepa-purpose.d.ts +22 -0
  57. package/dist/formats/sepa-purpose.d.ts.map +1 -0
  58. package/dist/formats/sepa-purpose.js +68 -0
  59. package/dist/formats/sepa-purpose.js.map +1 -0
  60. package/dist/index.d.ts +28 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +27 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/session/app-approval.d.ts +60 -0
  65. package/dist/session/app-approval.d.ts.map +1 -0
  66. package/dist/session/app-approval.js +215 -0
  67. package/dist/session/app-approval.js.map +1 -0
  68. package/dist/session/bank-connection.d.ts +28 -0
  69. package/dist/session/bank-connection.d.ts.map +1 -0
  70. package/dist/session/bank-connection.js +48 -0
  71. package/dist/session/bank-connection.js.map +1 -0
  72. package/dist/session/dialog-runner.d.ts +34 -0
  73. package/dist/session/dialog-runner.d.ts.map +1 -0
  74. package/dist/session/dialog-runner.js +112 -0
  75. package/dist/session/dialog-runner.js.map +1 -0
  76. package/dist/session/login-guard.d.ts +73 -0
  77. package/dist/session/login-guard.d.ts.map +1 -0
  78. package/dist/session/login-guard.js +109 -0
  79. package/dist/session/login-guard.js.map +1 -0
  80. package/dist/session/parameter-data.d.ts +83 -0
  81. package/dist/session/parameter-data.d.ts.map +1 -0
  82. package/dist/session/parameter-data.js +68 -0
  83. package/dist/session/parameter-data.js.map +1 -0
  84. package/dist/session/pin-tan-client.d.ts +54 -0
  85. package/dist/session/pin-tan-client.d.ts.map +1 -0
  86. package/dist/session/pin-tan-client.js +153 -0
  87. package/dist/session/pin-tan-client.js.map +1 -0
  88. package/dist/session/pin-tan-dialog.d.ts +71 -0
  89. package/dist/session/pin-tan-dialog.d.ts.map +1 -0
  90. package/dist/session/pin-tan-dialog.js +124 -0
  91. package/dist/session/pin-tan-dialog.js.map +1 -0
  92. package/dist/session/protocol.d.ts +209 -0
  93. package/dist/session/protocol.d.ts.map +1 -0
  94. package/dist/session/protocol.js +75 -0
  95. package/dist/session/protocol.js.map +1 -0
  96. package/dist/session/response-handler.d.ts +48 -0
  97. package/dist/session/response-handler.d.ts.map +1 -0
  98. package/dist/session/response-handler.js +121 -0
  99. package/dist/session/response-handler.js.map +1 -0
  100. package/dist/session/sepa-accounts.d.ts +34 -0
  101. package/dist/session/sepa-accounts.d.ts.map +1 -0
  102. package/dist/session/sepa-accounts.js +96 -0
  103. package/dist/session/sepa-accounts.js.map +1 -0
  104. package/dist/session/session-setup.d.ts +72 -0
  105. package/dist/session/session-setup.d.ts.map +1 -0
  106. package/dist/session/session-setup.js +160 -0
  107. package/dist/session/session-setup.js.map +1 -0
  108. package/dist/session/session-state.d.ts +47 -0
  109. package/dist/session/session-state.d.ts.map +1 -0
  110. package/dist/session/session-state.js +147 -0
  111. package/dist/session/session-state.js.map +1 -0
  112. package/dist/session/tan-selection.d.ts +88 -0
  113. package/dist/session/tan-selection.d.ts.map +1 -0
  114. package/dist/session/tan-selection.js +178 -0
  115. package/dist/session/tan-selection.js.map +1 -0
  116. package/dist/session/user-prompts.d.ts +61 -0
  117. package/dist/session/user-prompts.d.ts.map +1 -0
  118. package/dist/session/user-prompts.js +164 -0
  119. package/dist/session/user-prompts.js.map +1 -0
  120. package/dist/tan/challenge.d.ts +114 -0
  121. package/dist/tan/challenge.d.ts.map +1 -0
  122. package/dist/tan/challenge.js +185 -0
  123. package/dist/tan/challenge.js.map +1 -0
  124. package/dist/tan/flicker.d.ts +36 -0
  125. package/dist/tan/flicker.d.ts.map +1 -0
  126. package/dist/tan/flicker.js +262 -0
  127. package/dist/tan/flicker.js.map +1 -0
  128. package/dist/tan/tan-image.d.ts +21 -0
  129. package/dist/tan/tan-image.d.ts.map +1 -0
  130. package/dist/tan/tan-image.js +41 -0
  131. package/dist/tan/tan-image.js.map +1 -0
  132. package/dist/tan/tan-models.d.ts +145 -0
  133. package/dist/tan/tan-models.d.ts.map +1 -0
  134. package/dist/tan/tan-models.js +148 -0
  135. package/dist/tan/tan-models.js.map +1 -0
  136. package/dist/util/async.d.ts +24 -0
  137. package/dist/util/async.d.ts.map +1 -0
  138. package/dist/util/async.js +49 -0
  139. package/dist/util/async.js.map +1 -0
  140. package/dist/util/bytes.d.ts +23 -0
  141. package/dist/util/bytes.d.ts.map +1 -0
  142. package/dist/util/bytes.js +136 -0
  143. package/dist/util/bytes.js.map +1 -0
  144. package/dist/util/call-context.d.ts +12 -0
  145. package/dist/util/call-context.d.ts.map +1 -0
  146. package/dist/util/call-context.js +29 -0
  147. package/dist/util/call-context.js.map +1 -0
  148. package/dist/util/dates.d.ts +62 -0
  149. package/dist/util/dates.d.ts.map +1 -0
  150. package/dist/util/dates.js +169 -0
  151. package/dist/util/dates.js.map +1 -0
  152. package/dist/util/errors.d.ts +9 -0
  153. package/dist/util/errors.d.ts.map +1 -0
  154. package/dist/util/errors.js +15 -0
  155. package/dist/util/errors.js.map +1 -0
  156. package/dist/util/immutable-map.d.ts +16 -0
  157. package/dist/util/immutable-map.d.ts.map +1 -0
  158. package/dist/util/immutable-map.js +38 -0
  159. package/dist/util/immutable-map.js.map +1 -0
  160. package/dist/util/json.d.ts +13 -0
  161. package/dist/util/json.d.ts.map +1 -0
  162. package/dist/util/json.js +44 -0
  163. package/dist/util/json.js.map +1 -0
  164. package/dist/util/text.d.ts +20 -0
  165. package/dist/util/text.d.ts.map +1 -0
  166. package/dist/util/text.js +78 -0
  167. package/dist/util/text.js.map +1 -0
  168. package/dist/util/xml.d.ts +35 -0
  169. package/dist/util/xml.d.ts.map +1 -0
  170. package/dist/util/xml.js +183 -0
  171. package/dist/util/xml.js.map +1 -0
  172. package/dist/v3/account-extension.d.ts +25 -0
  173. package/dist/v3/account-extension.d.ts.map +1 -0
  174. package/dist/v3/account-extension.js +176 -0
  175. package/dist/v3/account-extension.js.map +1 -0
  176. package/dist/v3/client.d.ts +24 -0
  177. package/dist/v3/client.d.ts.map +1 -0
  178. package/dist/v3/client.js +16 -0
  179. package/dist/v3/client.js.map +1 -0
  180. package/dist/v3/dialog.d.ts +78 -0
  181. package/dist/v3/dialog.d.ts.map +1 -0
  182. package/dist/v3/dialog.js +138 -0
  183. package/dist/v3/dialog.js.map +1 -0
  184. package/dist/v3/message.d.ts +72 -0
  185. package/dist/v3/message.d.ts.map +1 -0
  186. package/dist/v3/message.js +259 -0
  187. package/dist/v3/message.js.map +1 -0
  188. package/dist/v3/parameters.d.ts +79 -0
  189. package/dist/v3/parameters.d.ts.map +1 -0
  190. package/dist/v3/parameters.js +396 -0
  191. package/dist/v3/parameters.js.map +1 -0
  192. package/dist/v3/protocol.d.ts +68 -0
  193. package/dist/v3/protocol.d.ts.map +1 -0
  194. package/dist/v3/protocol.js +263 -0
  195. package/dist/v3/protocol.js.map +1 -0
  196. package/dist/v3/segments.d.ts +89 -0
  197. package/dist/v3/segments.d.ts.map +1 -0
  198. package/dist/v3/segments.js +283 -0
  199. package/dist/v3/segments.js.map +1 -0
  200. package/dist/v3/syntax.d.ts +76 -0
  201. package/dist/v3/syntax.d.ts.map +1 -0
  202. package/dist/v3/syntax.js +301 -0
  203. package/dist/v3/syntax.js.map +1 -0
  204. package/package.json +63 -4
  205. package/src/core/account.ts +250 -0
  206. package/src/core/amount.ts +209 -0
  207. package/src/core/balance.ts +84 -0
  208. package/src/core/bank-info.ts +66 -0
  209. package/src/core/client.ts +149 -0
  210. package/src/core/config.ts +141 -0
  211. package/src/core/errors.ts +203 -0
  212. package/src/core/feedback.ts +137 -0
  213. package/src/core/transaction.ts +156 -0
  214. package/src/core/transport.ts +114 -0
  215. package/src/formats/camt.ts +169 -0
  216. package/src/formats/mt940.ts +333 -0
  217. package/src/formats/readers.ts +56 -0
  218. package/src/formats/sepa-purpose.ts +75 -0
  219. package/src/index.ts +68 -0
  220. package/src/session/app-approval.ts +265 -0
  221. package/src/session/bank-connection.ts +51 -0
  222. package/src/session/dialog-runner.ts +119 -0
  223. package/src/session/login-guard.ts +135 -0
  224. package/src/session/parameter-data.ts +137 -0
  225. package/src/session/pin-tan-client.ts +186 -0
  226. package/src/session/pin-tan-dialog.ts +160 -0
  227. package/src/session/protocol.ts +311 -0
  228. package/src/session/response-handler.ts +130 -0
  229. package/src/session/sepa-accounts.ts +97 -0
  230. package/src/session/session-setup.ts +165 -0
  231. package/src/session/session-state.ts +170 -0
  232. package/src/session/tan-selection.ts +192 -0
  233. package/src/session/user-prompts.ts +174 -0
  234. package/src/tan/challenge.ts +252 -0
  235. package/src/tan/flicker.ts +270 -0
  236. package/src/tan/tan-image.ts +36 -0
  237. package/src/tan/tan-models.ts +247 -0
  238. package/src/util/async.ts +53 -0
  239. package/src/util/bytes.ts +135 -0
  240. package/src/util/call-context.ts +40 -0
  241. package/src/util/dates.ts +193 -0
  242. package/src/util/errors.ts +16 -0
  243. package/src/util/immutable-map.ts +47 -0
  244. package/src/util/json.ts +51 -0
  245. package/src/util/text.ts +82 -0
  246. package/src/util/xml.ts +172 -0
  247. package/src/v3/account-extension.ts +190 -0
  248. package/src/v3/client.ts +29 -0
  249. package/src/v3/dialog.ts +199 -0
  250. package/src/v3/message.ts +321 -0
  251. package/src/v3/parameters.ts +451 -0
  252. package/src/v3/protocol.ts +331 -0
  253. package/src/v3/segments.ts +331 -0
  254. package/src/v3/syntax.ts +307 -0
@@ -0,0 +1,263 @@
1
+ // Internal to the package, and named after the FinTS specification. Documentation is where the meaning is not evident.
2
+ import { requirePin } from '../core/config.js';
3
+ import { FinTsError, FinTsTransportError, FinTsUnsupportedError } from '../core/errors.js';
4
+ import { hasErrors } from '../core/feedback.js';
5
+ import { camtTransactions, mt940Transactions } from '../formats/readers.js';
6
+ import { BankConnection, checkMessageSize } from '../session/bank-connection.js';
7
+ import { LoginGuard } from '../session/login-guard.js';
8
+ import { offeredVersion, requireBankParameters } from '../session/parameter-data.js';
9
+ import { balanceQuery, checkBeforeSigning, chooseTransactions, } from '../session/protocol.js';
10
+ import { invalidArgument } from '../util/errors.js';
11
+ import { readOptionalString } from '../util/json.js';
12
+ import { decodeBankText } from '../util/text.js';
13
+ import { FinTs3Dialog } from './dialog.js';
14
+ import { buildMessage, decodeTransport, encodeTransport, IncomingMessage3 } from './message.js';
15
+ import { Bpd3, decodeSegments, encodeSegments, Upd3 } from './parameters.js';
16
+ import { balanceAccount, parseBalance, parseSepaAccounts, parseTanMedia, Segments } from './segments.js';
17
+ import { isLatin1 } from './syntax.js';
18
+ /** Customer ID the specification reserves for anonymous dialogs. */
19
+ const anonymousCustomerId = '9999999999';
20
+ /** Longest product ID (Produktbezeichnung) and product version HKVVB takes. */
21
+ const maxProductIdLength = 25;
22
+ const maxProductVersionLength = 5;
23
+ function requireLatin1(text, name) {
24
+ // The message leaves out the value, which may be the PIN.
25
+ if (!isLatin1(text))
26
+ throw invalidArgument(`${name} contains characters FinTS 3.0 cannot send (ISO 8859-1 only)`);
27
+ return text;
28
+ }
29
+ function requireMaxLength(text, maxLength, name) {
30
+ if (text.length > maxLength)
31
+ throw invalidArgument(`At most ${maxLength} characters in FinTS 3.0`, name);
32
+ }
33
+ function requireSendable(config) {
34
+ requireLatin1(config.userId, 'userId');
35
+ requireLatin1(config.customerId, 'customerId');
36
+ requireLatin1(config.productId, 'productId');
37
+ requireLatin1(config.productVersion, 'productVersion');
38
+ // Cut short, the product would be one the bank does not know.
39
+ requireMaxLength(config.productId, maxProductIdLength, 'productId');
40
+ requireMaxLength(config.productVersion, maxProductVersionLength, 'productVersion');
41
+ return config;
42
+ }
43
+ /** The segments of `type` in all `pages`. */
44
+ function all(pages, type) {
45
+ return pages.flatMap((p) => p.findAll(type));
46
+ }
47
+ /** FinTS 3.0 messages and business transactions (HBCI segment syntax, PIN/TAN security). */
48
+ export class FinTs3Protocol {
49
+ config;
50
+ pin;
51
+ connection;
52
+ loginGuard = new LoginGuard();
53
+ /** Customer system ID the bank assigned in the synchronization. */
54
+ systemId;
55
+ bpd;
56
+ upd;
57
+ /**
58
+ * Throws `TypeError` if the PIN is empty, if the PIN or login data contain characters FinTS 3.0 cannot send (ISO
59
+ * 8859-1 only), or the product ID or version is longer than its field in HKVVB.
60
+ */
61
+ constructor(config, pin, transport, logger) {
62
+ this.config = requireSendable(config);
63
+ this.pin = requireLatin1(requirePin(pin), 'pin');
64
+ this.connection = new BankConnection(config.url, transport, logger);
65
+ }
66
+ get bankParameters() {
67
+ return this.bpd;
68
+ }
69
+ get userParameters() {
70
+ return this.upd;
71
+ }
72
+ /** Dialogs cannot start without the customer system ID. */
73
+ get synchronization() {
74
+ return this.systemId === undefined ? 'required' : 'none';
75
+ }
76
+ forgetSystemId() {
77
+ const had = this.systemId !== undefined;
78
+ this.systemId = undefined;
79
+ return had;
80
+ }
81
+ initSegments(systemId, anonymous = false) {
82
+ return [
83
+ Segments.identification({
84
+ countryCode: this.config.countryCode,
85
+ bankCode: this.config.bankCode,
86
+ customerId: anonymous ? anonymousCustomerId : this.config.customerId,
87
+ systemId,
88
+ systemIdRequired: !anonymous,
89
+ }),
90
+ Segments.processingPreparation({
91
+ bpdVersion: this.bpd?.version ?? 0,
92
+ updVersion: anonymous ? 0 : (this.upd?.version ?? 0),
93
+ language: this.bpd?.dialogLanguage ?? 0,
94
+ productId: this.config.productId,
95
+ productVersion: this.config.productVersion,
96
+ }),
97
+ ];
98
+ }
99
+ async post(message) {
100
+ const signing = message.signing;
101
+ if (signing !== undefined)
102
+ checkBeforeSigning(this.loginGuard, this.pin, this.bpd);
103
+ const outgoing = buildMessage({
104
+ dialogId: message.dialogId,
105
+ messageNumber: message.number,
106
+ segments: message.segments,
107
+ security: signing === undefined
108
+ ? undefined
109
+ : {
110
+ countryCode: this.config.countryCode,
111
+ bankCode: this.config.bankCode,
112
+ userId: this.config.userId,
113
+ systemId: signing.systemId,
114
+ pin: this.pin,
115
+ securityFunction: signing.securityFunction,
116
+ },
117
+ tan: message.tan,
118
+ });
119
+ checkMessageSize(outgoing.bytes.length, this.bpd?.bankInfo.maxMessageSize);
120
+ this.connection.log('outgoing', () => outgoing.masked);
121
+ const bytes = decodeTransport(await this.connection.post(encodeTransport(outgoing.bytes), 'text/plain'));
122
+ this.connection.log('incoming', () => decodeBankText(bytes));
123
+ return bytes;
124
+ }
125
+ keepParameterData(response) {
126
+ this.keepBankParameters(response);
127
+ this.upd = Upd3.fromSegments(response.segments, this.config.bankCode, this.config.countryCode) ?? this.upd;
128
+ this.systemId = response.find('HISYN')?.text(1) ?? this.systemId;
129
+ }
130
+ keepBankParameters(response) {
131
+ this.bpd = Bpd3.fromSegments(response.segments, this.config.bankCode) ?? this.bpd;
132
+ }
133
+ /** Keeps the bank parameter data of an anonymous dialog, and nothing that belongs to a user. */
134
+ async fetchBankParametersAnonymously() {
135
+ const response = await this.requestBankParametersAnonymously();
136
+ this.keepBankParameters(response);
137
+ return response;
138
+ }
139
+ /**
140
+ * Asks for the bank parameter data in an anonymous dialog that announces strong customer authentication; a bank that
141
+ * rejects the announcement, with a return code or by failing on it, is asked again without it.
142
+ *
143
+ * A timeout or a broken connection is not a reason to ask again: it would only double the wait.
144
+ */
145
+ async requestBankParametersAnonymously() {
146
+ let announced;
147
+ try {
148
+ announced = await this.anonymousDialog(true);
149
+ }
150
+ catch (error) {
151
+ if (error instanceof FinTsTransportError && error.statusCode === undefined)
152
+ throw error;
153
+ if (!(error instanceof FinTsError))
154
+ throw error;
155
+ return this.anonymousDialog(false);
156
+ }
157
+ if (!hasErrors(announced.feedback) || announced.find('HIBPA') !== undefined)
158
+ return announced;
159
+ return this.anonymousDialog(false);
160
+ }
161
+ async anonymousDialog(announceSca) {
162
+ const dialog = FinTs3Dialog.anonymous(this);
163
+ try {
164
+ return await dialog.requestBankParameters(announceSca);
165
+ }
166
+ finally {
167
+ await dialog.end();
168
+ }
169
+ }
170
+ newDialog(method, tanMedium) {
171
+ return FinTs3Dialog.signed(this, method, tanMedium);
172
+ }
173
+ combine(first, second) {
174
+ return IncomingMessage3.combine(first, second);
175
+ }
176
+ // --- Business transactions ---
177
+ version(transaction, implemented, options = {}) {
178
+ return offeredVersion(this.bpd, this.upd, transaction, new Set(implemented), options);
179
+ }
180
+ tanMedia() {
181
+ const version = this.version('HKTAB', [4, 5]);
182
+ if (version === undefined)
183
+ return undefined;
184
+ return {
185
+ order: () => Segments.tanMedia(version),
186
+ read: (pages) => all(pages, 'HITAB').flatMap(parseTanMedia),
187
+ };
188
+ }
189
+ sepaAccounts() {
190
+ const version = this.version('HKSPA', [1, 2, 3], { requiresEntry: true });
191
+ if (version === undefined)
192
+ return undefined;
193
+ return {
194
+ order: (continuation) => Segments.sepaAccounts(version, continuation),
195
+ read: (pages) => all(pages, 'HISPA').flatMap((s) => parseSepaAccounts(s, this.config.countryCode, this.config.bankCode)),
196
+ };
197
+ }
198
+ balance(account) {
199
+ const version = this.version('HKSAL', [6, 7, 8], { account });
200
+ if (version === undefined) {
201
+ throw new FinTsUnsupportedError('The bank reports no balance (HKSAL) for this account');
202
+ }
203
+ return balanceQuery(account, {
204
+ order: (continuation) => Segments.balance(version, account, continuation),
205
+ records: (pages) => all(pages, 'HISAL'),
206
+ accountOf: balanceAccount,
207
+ read: parseBalance,
208
+ });
209
+ }
210
+ transactions(account, format, from, to) {
211
+ const request = chooseTransactions(format, account, this.upd, {
212
+ camt: { name: 'HKCAZ', version: this.version('HKCAZ', [1], { account }) },
213
+ camtFormats: requireBankParameters(this.bpd).camtFormats,
214
+ mt940: { name: 'HKKAZ', version: this.version('HKKAZ', [6, 7], { account }) },
215
+ });
216
+ const version = request.version;
217
+ if (request.camt) {
218
+ return {
219
+ order: (continuation) => Segments.transactionsCamt(version, account, request.camtFormats, { from, to, continuation }),
220
+ // The third element group holds the booked documents, the fourth element the pending one.
221
+ read: (pages) => camtTransactions(all(pages, 'HICAZ').flatMap((s) => s
222
+ .group(3)
223
+ .filter((d) => !d.isEmpty)
224
+ .map((d) => d.bytes)), all(pages, 'HICAZ')
225
+ .map((s) => s.binary(4))
226
+ .filter((d) => d !== undefined)),
227
+ };
228
+ }
229
+ return {
230
+ order: (continuation) => Segments.transactionsMt940(version, account, { from, to, continuation }),
231
+ // The first element holds the booked transactions, the second the pending ones.
232
+ read: (pages) => mt940Transactions(all(pages, 'HIKAZ')
233
+ .map((s) => s.binary(1))
234
+ .filter((d) => d !== undefined), all(pages, 'HIKAZ')
235
+ .map((s) => s.binary(2))
236
+ .filter((d) => d !== undefined), request.currency),
237
+ };
238
+ }
239
+ // --- Saved state ---
240
+ saveState() {
241
+ return {
242
+ systemId: this.systemId ?? null,
243
+ bpd: this.bpd === undefined ? null : encodeSegments(this.bpd.segments),
244
+ upd: this.upd === undefined ? null : encodeSegments(this.upd.segments),
245
+ };
246
+ }
247
+ restoreState(saved) {
248
+ const bpd = readOptionalString(saved, 'bpd');
249
+ const upd = readOptionalString(saved, 'upd');
250
+ const restoredSystemId = readOptionalString(saved, 'systemId');
251
+ const restoredBpd = bpd === undefined ? undefined : Bpd3.fromSegments(decodeSegments(bpd), this.config.bankCode);
252
+ const restoredUpd = upd === undefined
253
+ ? undefined
254
+ : Upd3.fromSegments(decodeSegments(upd), this.config.bankCode, this.config.countryCode);
255
+ this.systemId = restoredSystemId;
256
+ this.bpd = restoredBpd;
257
+ this.upd = restoredUpd;
258
+ }
259
+ close() {
260
+ this.connection.close();
261
+ }
262
+ }
263
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/v3/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import { Account } from '../core/account.js';
2
+ import { Balance } from '../core/balance.js';
3
+ import { TanMedium } from '../tan/tan-models.js';
4
+ import { type Segment, SegmentSpec, type SegmentValue } from './syntax.js';
5
+ /** Bank identification (KIK): country code and bank code. */
6
+ export declare function bankIdentification(countryCode: string, bankCode: string): SegmentValue;
7
+ /** National account (KTV): account number, sub-account and bank identification. */
8
+ export declare function nationalAccount(a: Account): SegmentValue[];
9
+ /** International account (KTI): IBAN, BIC, then the national account. */
10
+ export declare function internationalAccount(a: Account): SegmentValue[];
11
+ /** Builders for the request segments the client sends. */
12
+ export declare const Segments: Readonly<{
13
+ /** HKIDN: who is logging in, from which customer system. */
14
+ identification(parts: {
15
+ countryCode: string;
16
+ bankCode: string;
17
+ customerId: string;
18
+ systemId: string;
19
+ systemIdRequired: boolean;
20
+ }): SegmentSpec;
21
+ /** HKVVB: the parameter data versions the client knows, the dialog language and the registered product. */
22
+ processingPreparation(parts: {
23
+ bpdVersion: number;
24
+ updVersion: number;
25
+ language: number;
26
+ productId: string;
27
+ productVersion: string;
28
+ }): SegmentSpec;
29
+ /** HKSYN: requests a new customer system ID. */
30
+ synchronization(): SegmentSpec;
31
+ dialogEnd(dialogId: string): SegmentSpec;
32
+ /** HKTAN process 4: asks for strong customer authentication of the `segmentType` sent in the same message. */
33
+ tanProcess4(version: number, segmentType: string, mediumName?: string): SegmentSpec;
34
+ /** HKTAN process 2: submits the TAN (carried in the signature) for the order with `reference`. */
35
+ tanProcess2(version: number, reference: string): SegmentSpec;
36
+ /** HKTAN process S: asks whether the order with `reference` was approved in the banking app. */
37
+ tanProcessStatus(version: number, reference: string): SegmentSpec;
38
+ /** HKSAL: the balance of one account (not of all accounts). */
39
+ balance(version: number, account: Account, continuation?: string): SegmentSpec;
40
+ /** HKKAZ: MT940 transactions of one account. */
41
+ transactionsMt940(version: number, account: Account, period: {
42
+ from?: Date | undefined;
43
+ to?: Date | undefined;
44
+ continuation?: string | undefined;
45
+ }): SegmentSpec;
46
+ /** HKCAZ: camt transactions of one account in one of `formats`. */
47
+ transactionsCamt(version: number, account: Account, formats: readonly string[], period: {
48
+ from?: Date | undefined;
49
+ to?: Date | undefined;
50
+ continuation?: string | undefined;
51
+ }): SegmentSpec;
52
+ /** HKSPA: IBAN and BIC of all accounts. */
53
+ sepaAccounts(version: number, continuation?: string): SegmentSpec;
54
+ /** HKTAB: all TAN media of all classes. */
55
+ tanMedia(version: number): SegmentSpec;
56
+ }>;
57
+ /** The TAN part of a response (HITAN). */
58
+ export declare class TanResponse {
59
+ /** The TAN process the segment answers: `4` asks for an approval, `S` answers a status request. */
60
+ readonly process: string | undefined;
61
+ readonly reference: string | undefined;
62
+ readonly challenge: string | undefined;
63
+ readonly hhdUc: Uint8Array | undefined;
64
+ readonly validUntil: Date | undefined;
65
+ readonly mediumName: string | undefined;
66
+ constructor(
67
+ /** The TAN process the segment answers: `4` asks for an approval, `S` answers a status request. */
68
+ process: string | undefined, reference: string | undefined, challenge: string | undefined, hhdUc: Uint8Array | undefined, validUntil: Date | undefined, mediumName: string | undefined);
69
+ static parse(s: Segment): TanResponse;
70
+ /** Whether the bank needs no approval although it answered with a TAN segment. */
71
+ get isDummy(): boolean;
72
+ }
73
+ /**
74
+ * Parses a balance (HISAL); throws `FormatError` if the booked balance is missing or malformed, or a balance has no
75
+ * credit/debit mark.
76
+ */
77
+ export declare function parseBalance(s: Segment, account: Account): Balance;
78
+ /**
79
+ * The account a balance (HISAL) belongs to: international (IBAN, BIC, then national) from version 7, national before.
80
+ */
81
+ export declare function balanceAccount(s: Segment): Account;
82
+ /**
83
+ * Parses the SEPA account list (HISPA), one account per data element. An account the bank marks as no payment account
84
+ * ("Kontoverwendung SEPA" N) is left out: it has no SEPA connection.
85
+ */
86
+ export declare function parseSepaAccounts(s: Segment, defaultCountry: string, defaultBank: string): Account[];
87
+ /** Parses the TAN media list (HITAB versions 4 and 5, PIN/TAN "TAN-Medium-Liste"). */
88
+ export declare function parseTanMedia(s: Segment): TanMedium[];
89
+ //# sourceMappingURL=segments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/v3/segments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,283 @@
1
+ // Internal to the package, and named after the FinTS specification. Documentation is where the meaning is not evident.
2
+ import { Account } from '../core/account.js';
3
+ import { Amount, withMark } from '../core/amount.js';
4
+ import { Balance } from '../core/balance.js';
5
+ import { noReference } from '../session/protocol.js';
6
+ import { TanMedium, tanMediumStatusOf } from '../tan/tan-models.js';
7
+ import { formatFintsDate, parseFintsDate, parseFintsDateTime } from '../util/dates.js';
8
+ import { FormatError } from '../util/errors.js';
9
+ import { SegmentSpec } from './syntax.js';
10
+ /** Bank identification (KIK): country code and bank code. */
11
+ export function bankIdentification(countryCode, bankCode) {
12
+ return [countryCode, bankCode];
13
+ }
14
+ /** National account (KTV): account number, sub-account and bank identification. */
15
+ export function nationalAccount(a) {
16
+ return [a.accountNumber, a.subAccount, a.countryCode, a.bankCode];
17
+ }
18
+ /** International account (KTI): IBAN, BIC, then the national account. */
19
+ export function internationalAccount(a) {
20
+ return [a.iban, a.bic, ...nationalAccount(a)];
21
+ }
22
+ function dateOrEmpty(date) {
23
+ return date === undefined ? undefined : formatFintsDate(date);
24
+ }
25
+ // HKTAN fields: order reference (Auftragsreferenz), "more TANs follow" and the TAN medium name.
26
+ const orderReferenceField = 5;
27
+ const moreTansField = 6;
28
+ const tanMediumField = 11;
29
+ /** Builders for the request segments the client sends. */
30
+ export const Segments = Object.freeze({
31
+ /** HKIDN: who is logging in, from which customer system. */
32
+ identification(parts) {
33
+ return new SegmentSpec('HKIDN', 2, [
34
+ bankIdentification(parts.countryCode, parts.bankCode),
35
+ parts.customerId,
36
+ parts.systemId,
37
+ parts.systemIdRequired ? 1 : 0,
38
+ ]);
39
+ },
40
+ /** HKVVB: the parameter data versions the client knows, the dialog language and the registered product. */
41
+ processingPreparation(parts) {
42
+ return new SegmentSpec('HKVVB', 3, [
43
+ parts.bpdVersion,
44
+ parts.updVersion,
45
+ parts.language,
46
+ parts.productId,
47
+ parts.productVersion,
48
+ ]);
49
+ },
50
+ /** HKSYN: requests a new customer system ID. */
51
+ synchronization() {
52
+ return new SegmentSpec('HKSYN', 3, [0]);
53
+ },
54
+ dialogEnd(dialogId) {
55
+ return new SegmentSpec('HKEND', 1, [dialogId]);
56
+ },
57
+ /** HKTAN process 4: asks for strong customer authentication of the `segmentType` sent in the same message. */
58
+ tanProcess4(version, segmentType, mediumName) {
59
+ return SegmentSpec.numbered('HKTAN', version, { 1: '4', 2: segmentType, [tanMediumField]: mediumName });
60
+ },
61
+ /** HKTAN process 2: submits the TAN (carried in the signature) for the order with `reference`. */
62
+ tanProcess2(version, reference) {
63
+ return SegmentSpec.numbered('HKTAN', version, { 1: '2', [orderReferenceField]: reference, [moreTansField]: false });
64
+ },
65
+ /** HKTAN process S: asks whether the order with `reference` was approved in the banking app. */
66
+ tanProcessStatus(version, reference) {
67
+ return SegmentSpec.numbered('HKTAN', version, { 1: 'S', [orderReferenceField]: reference, [moreTansField]: false });
68
+ },
69
+ /** HKSAL: the balance of one account (not of all accounts). */
70
+ balance(version, account, continuation) {
71
+ return new SegmentSpec('HKSAL', version, [
72
+ version >= 7 ? internationalAccount(account) : nationalAccount(account),
73
+ false,
74
+ null,
75
+ continuation,
76
+ ]);
77
+ },
78
+ /** HKKAZ: MT940 transactions of one account. */
79
+ transactionsMt940(version, account, period) {
80
+ return new SegmentSpec('HKKAZ', version, [
81
+ version >= 7 ? internationalAccount(account) : nationalAccount(account),
82
+ false,
83
+ dateOrEmpty(period.from),
84
+ dateOrEmpty(period.to),
85
+ null,
86
+ period.continuation,
87
+ ]);
88
+ },
89
+ /** HKCAZ: camt transactions of one account in one of `formats`. */
90
+ transactionsCamt(version, account, formats, period) {
91
+ return new SegmentSpec('HKCAZ', version, [
92
+ internationalAccount(account),
93
+ formats,
94
+ false,
95
+ dateOrEmpty(period.from),
96
+ dateOrEmpty(period.to),
97
+ null,
98
+ period.continuation,
99
+ ]);
100
+ },
101
+ /** HKSPA: IBAN and BIC of all accounts. */
102
+ sepaAccounts(version, continuation) {
103
+ return new SegmentSpec('HKSPA', version, [null, ...(version >= 2 ? [null, continuation] : [])]);
104
+ },
105
+ /** HKTAB: all TAN media of all classes. */
106
+ tanMedia(version) {
107
+ return new SegmentSpec('HKTAB', version, [0, 'A']);
108
+ },
109
+ });
110
+ /** Positions of the data elements in the TAN part of a response (HITAN versions 6 and 7), after the segment header. */
111
+ const Hitan = { process: 1, reference: 3, challenge: 4, hhdUc: 5, validUntil: 6, mediumName: 7 };
112
+ /** The TAN part of a response (HITAN). */
113
+ export class TanResponse {
114
+ process;
115
+ reference;
116
+ challenge;
117
+ hhdUc;
118
+ validUntil;
119
+ mediumName;
120
+ constructor(
121
+ /** The TAN process the segment answers: `4` asks for an approval, `S` answers a status request. */
122
+ process, reference, challenge, hhdUc, validUntil, mediumName) {
123
+ this.process = process;
124
+ this.reference = reference;
125
+ this.challenge = challenge;
126
+ this.hhdUc = hhdUc;
127
+ this.validUntil = validUntil;
128
+ this.mediumName = mediumName;
129
+ }
130
+ static parse(s) {
131
+ return new TanResponse(s.text(Hitan.process), s.text(Hitan.reference), s.text(Hitan.challenge), s.binary(Hitan.hhdUc), parseFintsDateTime(s.text(Hitan.validUntil, 0), s.text(Hitan.validUntil, 1)), s.text(Hitan.mediumName));
132
+ }
133
+ /** Whether the bank needs no approval although it answered with a TAN segment. */
134
+ get isDummy() {
135
+ return this.reference === undefined || this.reference === noReference;
136
+ }
137
+ }
138
+ /** Positions of the data elements in a balance (HISAL), after the segment header. */
139
+ const Hisal = {
140
+ account: 1,
141
+ productName: 2,
142
+ accountCurrency: 3,
143
+ bookedBalance: 4,
144
+ pendingBalance: 5,
145
+ creditLine: 6,
146
+ availableAmount: 7,
147
+ usedAmount: 8,
148
+ overdraft: 9,
149
+ bookingTime: 10,
150
+ };
151
+ /** Positions inside a balance (SDO): credit/debit mark, value, currency, date and time. */
152
+ const Sdo = { mark: 0, value: 1, currency: 2, date: 3, time: 4 };
153
+ /** An amount with currency (BTG) at `index`, or `undefined` if empty. */
154
+ function amountAt(s, index, fallbackCurrency) {
155
+ const value = s.text(index, 0);
156
+ if (value === undefined)
157
+ return undefined;
158
+ return Amount.parseDecimal(value, s.text(index, 1) ?? fallbackCurrency);
159
+ }
160
+ /**
161
+ * Parses a balance (HISAL); throws `FormatError` if the booked balance is missing or malformed, or a balance has no
162
+ * credit/debit mark.
163
+ */
164
+ export function parseBalance(s, account) {
165
+ const currency = s.text(Hisal.accountCurrency) ?? account.currency;
166
+ const signedBalance = (index) => {
167
+ const value = s.text(index, Sdo.value);
168
+ if (value === undefined)
169
+ return undefined;
170
+ const amountCurrency = s.text(index, Sdo.currency) ?? currency;
171
+ if (amountCurrency === undefined)
172
+ throw new FormatError('Balance without currency');
173
+ return withMark(Amount.parseDecimal(value, amountCurrency), s.text(index, Sdo.mark), 'C', 'D');
174
+ };
175
+ const booked = signedBalance(Hisal.bookedBalance);
176
+ if (booked === undefined)
177
+ throw new FormatError('Balance without booked amount');
178
+ const bookedDate = s.text(Hisal.bookedBalance, Sdo.date);
179
+ const bookedAsOf = parseFintsDate(bookedDate);
180
+ if (bookedAsOf === undefined)
181
+ throw new FormatError('Balance without date');
182
+ return new Balance({
183
+ account,
184
+ productName: s.text(Hisal.productName),
185
+ booked,
186
+ bookedAsOf,
187
+ bookedAsOfTime: parseFintsDateTime(bookedDate, s.text(Hisal.bookedBalance, Sdo.time)),
188
+ pending: signedBalance(Hisal.pendingBalance),
189
+ creditLine: amountAt(s, Hisal.creditLine, booked.currency),
190
+ available: amountAt(s, Hisal.availableAmount, booked.currency),
191
+ used: amountAt(s, Hisal.usedAmount, booked.currency),
192
+ overdraft: amountAt(s, Hisal.overdraft, booked.currency),
193
+ bookingDate: parseFintsDate(s.text(Hisal.bookingTime, 0)),
194
+ bookingTime: parseFintsDateTime(s.text(Hisal.bookingTime, 0), s.text(Hisal.bookingTime, 1)),
195
+ });
196
+ }
197
+ /**
198
+ * The account a balance (HISAL) belongs to: international (IBAN, BIC, then national) from version 7, national before.
199
+ */
200
+ export function balanceAccount(s) {
201
+ const fields = s.texts(Hisal.account);
202
+ const international = s.version >= 7;
203
+ const national = international ? 2 : 0;
204
+ return new Account({
205
+ iban: international ? fields[0] : undefined,
206
+ bic: international ? fields[1] : undefined,
207
+ accountNumber: fields[national],
208
+ subAccount: fields[national + 1],
209
+ countryCode: fields[national + 2] ?? '',
210
+ bankCode: fields[national + 3] ?? '',
211
+ });
212
+ }
213
+ /** Positions inside an account of the SEPA account list (HISPA "Kontoverbindung SEPA"). */
214
+ const Hispa = {
215
+ isSepaAccount: 0,
216
+ iban: 1,
217
+ bic: 2,
218
+ accountNumber: 3,
219
+ subAccount: 4,
220
+ countryCode: 5,
221
+ bankCode: 6,
222
+ };
223
+ /**
224
+ * Parses the SEPA account list (HISPA), one account per data element. An account the bank marks as no payment account
225
+ * ("Kontoverwendung SEPA" N) is left out: it has no SEPA connection.
226
+ */
227
+ export function parseSepaAccounts(s, defaultCountry, defaultBank) {
228
+ const accounts = [];
229
+ for (let i = 1; i < s.length; i++) {
230
+ if (s.text(i, Hispa.isSepaAccount) === 'N')
231
+ continue;
232
+ if (s.text(i, Hispa.iban) === undefined && s.text(i, Hispa.accountNumber) === undefined)
233
+ continue;
234
+ accounts.push(new Account({
235
+ iban: s.text(i, Hispa.iban),
236
+ bic: s.text(i, Hispa.bic),
237
+ accountNumber: s.text(i, Hispa.accountNumber),
238
+ subAccount: s.text(i, Hispa.subAccount),
239
+ countryCode: s.text(i, Hispa.countryCode) ?? defaultCountry,
240
+ bankCode: s.text(i, Hispa.bankCode) ?? defaultBank,
241
+ }));
242
+ }
243
+ return accounts;
244
+ }
245
+ /**
246
+ * Elements of the account a TAN medium belongs to, a national account (`ktv`: account number, sub-account, country
247
+ * code, bank code), which shifts every field behind it.
248
+ */
249
+ const accountWidth = 4;
250
+ /** Parses the TAN media list (HITAB versions 4 and 5, PIN/TAN "TAN-Medium-Liste"). */
251
+ export function parseTanMedia(s) {
252
+ // Version 5 adds the security function in front of the card number.
253
+ const version5 = s.version >= 5;
254
+ const cardNumber = version5 ? 3 : 2;
255
+ // The card number, card sequence number and card type are followed by the account. Behind it come: valid from, valid
256
+ // until, TAN list number, name, masked and full mobile number, SMS charge account (six elements), number of free TANs,
257
+ // last use, activation.
258
+ const after = cardNumber + 3 + accountWidth;
259
+ const media = [];
260
+ // The first data element is the TAN usage option; the media follow.
261
+ for (let i = 2; i < s.length; i++) {
262
+ const fields = s.texts(i);
263
+ const mediumClass = fields[0];
264
+ if (mediumClass === undefined)
265
+ continue;
266
+ media.push(new TanMedium({
267
+ mediumClass,
268
+ status: tanMediumStatusOf(fields[1]),
269
+ securityFunction: version5 ? fields[2] : undefined,
270
+ cardNumber: fields[cardNumber],
271
+ cardSequenceNumber: fields[cardNumber + 1],
272
+ validFrom: parseFintsDate(fields[after]),
273
+ validUntil: parseFintsDate(fields[after + 1]),
274
+ name: fields[after + 3],
275
+ mobileNumberMasked: fields[after + 4],
276
+ mobileNumber: fields[after + 5],
277
+ lastUsed: parseFintsDate(fields[after + 13]),
278
+ activatedOn: parseFintsDate(fields[after + 14]),
279
+ }));
280
+ }
281
+ return media;
282
+ }
283
+ //# sourceMappingURL=segments.js.map