@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,138 @@
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';
6
+ import { TanMethod } from '../tan/tan-models.js';
7
+ import { IncomingMessage3 } from './message.js';
8
+ import { Segments, TanResponse } from './segments.js';
9
+ /** Dialog ID of a dialog the bank has not answered yet, and customer system ID before synchronization. */
10
+ const unassigned = '0';
11
+ /** The first version of HKTAN that supports strong customer authentication. */
12
+ const firstScaVersion = 6;
13
+ /** The first version of HKTAN that supports app approvals, with the status request (process S). */
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;
18
+ anonymous;
19
+ systemId;
20
+ id = unassigned;
21
+ constructor(host, method, tanMedium, anonymous) {
22
+ super(method, tanMedium);
23
+ this.host = host;
24
+ this.anonymous = anonymous;
25
+ this.systemId = anonymous ? unassigned : (host.systemId ?? unassigned);
26
+ }
27
+ static signed(host, method, tanMedium) {
28
+ return new FinTs3Dialog(host, method, tanMedium, false);
29
+ }
30
+ /** 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;
36
+ }
37
+ get isActive() {
38
+ return this.id !== unassigned && !this.hasEnded;
39
+ }
40
+ /** The version of the HKTAN segments: that of the HITANS segment the bank describes the method in. */
41
+ get tanVersion() {
42
+ return this.bankParameters?.tanVersion(this.method) ?? firstScaVersion;
43
+ }
44
+ start(synchronize = false) {
45
+ if (synchronize)
46
+ this.systemId = unassigned;
47
+ return this.sendSegments([
48
+ ...this.host.initSegments(this.systemId),
49
+ ...(this.isTwoStep ? [this.tanRequest('HKIDN')] : []),
50
+ ...(synchronize ? [Segments.synchronization()] : []),
51
+ ]);
52
+ }
53
+ /**
54
+ * Opens the dialog, asking strong authentication for `order` with a two-step method, then sends `order` in the next
55
+ * message.
56
+ */
57
+ startWith(order) {
58
+ return {
59
+ login: () => this.sendSegments([
60
+ ...this.host.initSegments(this.systemId),
61
+ ...(this.isTwoStep ? [this.tanRequest(order.type)] : []),
62
+ ]),
63
+ order: () => this.sendSegments([order]),
64
+ };
65
+ }
66
+ /**
67
+ * Opens the anonymous dialog; the answer carries the bank parameter data.
68
+ *
69
+ * With `announceSca` the message also carries HKTAN, the way a client that can do strong customer authentication
70
+ * tells the bank so, whereupon the bank may send parameter data suited to it (PIN/TAN, B.4.3.1).
71
+ */
72
+ requestBankParameters(announceSca = false) {
73
+ return this.sendSegments([
74
+ ...this.host.initSegments(unassigned, true),
75
+ ...(announceSca ? [Segments.tanProcess4(firstScaVersion, 'HKIDN')] : []),
76
+ ]);
77
+ }
78
+ send(order) {
79
+ const needsTan = this.isTwoStep && requireBankParameters(this.bankParameters).pinTan.requiresTan(order.type);
80
+ return this.sendSegments([order, ...(needsTan ? [this.tanRequest(order.type)] : [])]);
81
+ }
82
+ async sendEnd() {
83
+ await this.sendSegments([Segments.dialogEnd(this.id)]);
84
+ }
85
+ tanRequest(segmentType) {
86
+ return Segments.tanProcess4(this.tanVersion, segmentType, this.mediumName);
87
+ }
88
+ /**
89
+ * The approval a HITAN segment of process 4 asks for, answered with HKTAN process 2 (TAN) or S (status).
90
+ *
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).
93
+ */
94
+ approvalIn(response) {
95
+ const tan = tanResponseOf(response, '4');
96
+ if (tan === undefined || tan.isDummy)
97
+ return undefined;
98
+ if (hasCode(response.feedback, FeedbackCodes.decoupledPending) && this.tanVersion < firstDecoupledVersion) {
99
+ throw new FinTsProtocolError('The bank asks for an app approval, which needs HKTAN version 7');
100
+ }
101
+ 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,
108
+ submitTan: (value) => this.sendSegments([Segments.tanProcess2(this.tanVersion, reference)], value),
109
+ checkStatus: () => this.sendSegments([Segments.tanProcessStatus(this.tanVersion, reference)]),
110
+ // 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)
128
+ this.id = response.dialogId ?? unassigned;
129
+ }
130
+ }
131
+ /** The TAN part of `response` that answers TAN `process`. */
132
+ function tanResponseOf(response, process) {
133
+ return response
134
+ .findAll('HITAN')
135
+ .map((s) => TanResponse.parse(s))
136
+ .find((t) => t.process === process);
137
+ }
138
+ //# sourceMappingURL=dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/v3/dialog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { BankMessage } from '../core/bank-info.js';
2
+ import { FinTsFeedback } from '../core/feedback.js';
3
+ import type { BankResponse } from '../session/protocol.js';
4
+ import { type Segment, SegmentSpec } from './syntax.js';
5
+ /** Signature data of a PIN/TAN message. */
6
+ export interface PinTanCredentials {
7
+ readonly countryCode: string;
8
+ readonly bankCode: string;
9
+ readonly userId: string;
10
+ readonly systemId: string;
11
+ readonly pin: string;
12
+ readonly securityFunction: string;
13
+ }
14
+ /** A message to send, and the same message with PIN and TAN masked for logging. */
15
+ export declare class OutgoingMessage {
16
+ 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. */
23
+ get masked(): string;
24
+ }
25
+ /**
26
+ * Builds a message: header (HNHBK), the `segments`, trailer (HNHBS).
27
+ *
28
+ * With `security` the segments are signed with PIN and optional `tan` (HNSHK … HNSHA) and wrapped in the encryption
29
+ * envelope (HNVSK, HNVSD) that PIN/TAN uses without actual encryption.
30
+ *
31
+ * The masked message states the sizes of its masked content, so that the log does not tell how long PIN and TAN are.
32
+ */
33
+ export declare function buildMessage(parts: {
34
+ dialogId: string;
35
+ messageNumber: number;
36
+ segments: readonly SegmentSpec[];
37
+ security?: PinTanCredentials | undefined;
38
+ tan?: string | undefined;
39
+ now?: Date;
40
+ }): OutgoingMessage;
41
+ /** A received message, with the segments of the encryption envelope unpacked. */
42
+ export declare class IncomingMessage3 implements BankResponse {
43
+ readonly segments: readonly Segment[];
44
+ readonly size: number;
45
+ /**
46
+ * Return codes for the whole message (HIRMG), then for single request segments (HIRMS).
47
+ *
48
+ * The segment a HIRMS refers to is not kept: each message carries one order, and the answer that completes an
49
+ * approval reports on the order of an earlier message (PIN/TAN B.4.2.1).
50
+ */
51
+ readonly feedback: readonly FinTsFeedback[];
52
+ readonly messageRejected: boolean;
53
+ private constructor();
54
+ /**
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
+ */
58
+ static parse(data: Uint8Array): IncomingMessage3;
59
+ static combine(first: IncomingMessage3, second: IncomingMessage3): IncomingMessage3;
60
+ get bankMessages(): BankMessage[];
61
+ get dialogId(): string | undefined;
62
+ find(type: string): Segment | undefined;
63
+ findAll(type: string): Segment[];
64
+ }
65
+ /**
66
+ * Unpacks the transport encoding: PIN/TAN servers answer in base64, a few with the raw message.
67
+ *
68
+ * Returns anything else unchanged, for `IncomingMessage3.parse` to reject.
69
+ */
70
+ export declare function decodeTransport(body: Uint8Array): Uint8Array;
71
+ export declare function encodeTransport(message: Uint8Array): Uint8Array;
72
+ //# sourceMappingURL=message.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,259 @@
1
+ // Internal to the package, and named after the FinTS specification. Documentation is where the meaning is not evident.
2
+ import { BankMessage } from '../core/bank-info.js';
3
+ import { FinTsFeedback } from '../core/feedback.js';
4
+ import { TanMethod } from '../tan/tan-models.js';
5
+ import { base64Encode, BytesBuilder, latin1Decode, latin1Encode } from '../util/bytes.js';
6
+ import { formatFintsDate, formatFintsTime } from '../util/dates.js';
7
+ import { FormatError } from '../util/errors.js';
8
+ import { decodeBankText, decodeBase64Lines } from '../util/text.js';
9
+ import { Binary, parseSegments, SegmentSpec } from './syntax.js';
10
+ function isTwoStep(c) {
11
+ return c.securityFunction !== TanMethod.oneStep.securityFunction;
12
+ }
13
+ // Codes of the PIN/TAN security envelope, from the FinTS security specification. PIN/TAN neither hashes, signs nor
14
+ // encrypts, but the envelope must name the algorithms of the chip card procedures all the same.
15
+ /** Area the signature covers: signature head and data (SHM). */
16
+ const signedArea = 1;
17
+ /** Role of the security supplier: issuer (ISS). */
18
+ const issuer = 1;
19
+ /** Security identification: message sender (MS), empty CID, then the customer system ID. */
20
+ function sender(systemId) {
21
+ return [1, null, systemId];
22
+ }
23
+ /** Security reference number, the same in every message. */
24
+ const securityReference = 1;
25
+ /** Security time stamp (STS). */
26
+ function timestamp(time) {
27
+ return [1, formatFintsDate(time), formatFintsTime(time)];
28
+ }
29
+ /** Hash algorithm: owner hashing (OHA), mutually agreed algorithm (ZZZ), initialisation value in clear (IVC). */
30
+ const hashAlgorithm = [1, 999, 1];
31
+ /** Signature algorithm: owner signing (OSG), RSA, ISO 9796-1. */
32
+ const signatureAlgorithm = [6, 10, 16];
33
+ /** Security function of the encryption head: plain text, since PIN/TAN does not encrypt. */
34
+ const plainText = 998;
35
+ /**
36
+ * Encryption algorithm: owner symmetric (OSY), CBC, 2-key triple DES, a key of zeros, symmetric key (KYE),
37
+ * initialisation value in clear (IVC).
38
+ */
39
+ const encryptionAlgorithm = [2, 2, 13, new Binary(new Uint8Array(8)), 5, 1];
40
+ /** Compression function: none. */
41
+ const noCompression = 0;
42
+ /** Key name: bank, user, key type `S` (signature) or `V` (encryption), key number and version 0. */
43
+ function keyName(c, keyType) {
44
+ return [c.countryCode, c.bankCode, c.userId, keyType, 0, 0];
45
+ }
46
+ /** A random integer from 0 below `bound`, from a cryptographically secure source. */
47
+ function secureRandom(bound) {
48
+ const values = new Uint32Array(1);
49
+ crypto.getRandomValues(values);
50
+ return values[0] % bound;
51
+ }
52
+ /** A random 14-digit reference that ties the signature head (HNSHK) to the signature end (HNSHA). */
53
+ function securityControlReference() {
54
+ return `${secureRandom(900000000) + 100000000}${secureRandom(100000).toString().padStart(5, '0')}`;
55
+ }
56
+ /** A message to send, and the same message with PIN and TAN masked for logging. */
57
+ export class OutgoingMessage {
58
+ bytes;
59
+ maskedParts;
60
+ constructor(bytes,
61
+ /** The parts of the masked message, each decoded on its own as the bank's text is. */
62
+ maskedParts) {
63
+ this.bytes = bytes;
64
+ this.maskedParts = maskedParts;
65
+ }
66
+ /** The message with PIN and TAN masked; decoded only when a logger asks for it. */
67
+ get masked() {
68
+ return this.maskedParts.map(decodeBankText).join('');
69
+ }
70
+ }
71
+ /**
72
+ * Builds a message: header (HNHBK), the `segments`, trailer (HNHBS).
73
+ *
74
+ * With `security` the segments are signed with PIN and optional `tan` (HNSHK … HNSHA) and wrapped in the encryption
75
+ * envelope (HNVSK, HNVSD) that PIN/TAN uses without actual encryption.
76
+ *
77
+ * The masked message states the sizes of its masked content, so that the log does not tell how long PIN and TAN are.
78
+ */
79
+ export function buildMessage(parts) {
80
+ const body = parts.security === undefined
81
+ ? plainBody(parts.segments)
82
+ : signedBody(parts.segments, parts.security, parts.tan, parts.now ?? new Date());
83
+ const trailer = new SegmentSpec('HNHBS', 1, [parts.messageNumber]).build(body.nextNumber);
84
+ // The header states the size of the whole message, itself included; its own size does not depend on it.
85
+ const header = (size) => new SegmentSpec('HNHBK', 3, [size.toString().padStart(12, '0'), 300, parts.dialogId, parts.messageNumber]).build(1);
86
+ const sizeOf = (sections) => header(0).length + lengthOf(sections) + trailer.length;
87
+ const result = new BytesBuilder();
88
+ result.add(header(sizeOf([body.bytes])));
89
+ result.add(body.bytes);
90
+ result.add(trailer);
91
+ return new OutgoingMessage(result.takeBytes(), [header(sizeOf(body.masked)), ...body.masked, trailer]);
92
+ }
93
+ /** The number of bytes in `parts` together. */
94
+ function lengthOf(parts) {
95
+ return parts.reduce((sum, part) => sum + part.length, 0);
96
+ }
97
+ /** The segments of a message without security, as the anonymous dialog sends them. */
98
+ function plainBody(segments) {
99
+ const built = segments.map((segment, i) => segment.build(i + 2));
100
+ const bytes = new BytesBuilder();
101
+ built.forEach((b) => {
102
+ bytes.add(b);
103
+ });
104
+ return { bytes: bytes.takeBytes(), masked: built, nextNumber: built.length + 2 };
105
+ }
106
+ /** The segments signed with PIN and optional `tan`, inside the encryption envelope. */
107
+ function signedBody(segments, security, tan, time) {
108
+ const profile = ['PIN', isTwoStep(security) ? 2 : 1];
109
+ const controlReference = securityControlReference();
110
+ const inner = new BytesBuilder();
111
+ const maskedInner = [];
112
+ const addInner = (built, masked) => {
113
+ inner.add(built);
114
+ maskedInner.push(masked ?? built);
115
+ };
116
+ addInner(new SegmentSpec('HNSHK', 4, [
117
+ profile,
118
+ security.securityFunction,
119
+ controlReference,
120
+ signedArea,
121
+ issuer,
122
+ sender(security.systemId),
123
+ securityReference,
124
+ timestamp(time),
125
+ hashAlgorithm,
126
+ signatureAlgorithm,
127
+ keyName(security, 'S'),
128
+ ]).build(2));
129
+ let number = 3;
130
+ for (const segment of segments)
131
+ addInner(segment.build(number++));
132
+ const signatureEnd = (pin, tanValue) => new SegmentSpec('HNSHA', 2, [controlReference, null, [pin, tanValue]]);
133
+ addInner(signatureEnd(security.pin, tan).build(number), signatureEnd('***', tan === undefined ? undefined : '***').build(number));
134
+ const innerBytes = inner.takeBytes();
135
+ const encryptionHead = new SegmentSpec('HNVSK', 3, [
136
+ profile,
137
+ plainText,
138
+ issuer,
139
+ sender(security.systemId),
140
+ timestamp(time),
141
+ encryptionAlgorithm,
142
+ keyName(security, 'V'),
143
+ noCompression,
144
+ ]).build(998);
145
+ const bytes = new BytesBuilder();
146
+ bytes.add(encryptionHead);
147
+ bytes.add(new SegmentSpec('HNVSD', 1, [new Binary(innerBytes)]).build(999));
148
+ const masked = [
149
+ encryptionHead,
150
+ latin1Encode(`HNVSD:999:1+@${lengthOf(maskedInner)}@`),
151
+ ...maskedInner,
152
+ latin1Encode("'"),
153
+ ];
154
+ return { bytes: bytes.takeBytes(), masked, nextNumber: number + 1 };
155
+ }
156
+ /** A received message, with the segments of the encryption envelope unpacked. */
157
+ export class IncomingMessage3 {
158
+ segments;
159
+ size;
160
+ /**
161
+ * Return codes for the whole message (HIRMG), then for single request segments (HIRMS).
162
+ *
163
+ * The segment a HIRMS refers to is not kept: each message carries one order, and the answer that completes an
164
+ * approval reports on the order of an earlier message (PIN/TAN B.4.2.1).
165
+ */
166
+ feedback;
167
+ messageRejected;
168
+ constructor(segments, size) {
169
+ this.segments = segments;
170
+ this.size = size;
171
+ this.feedback = Object.freeze(['HIRMG', 'HIRMS'].flatMap((type) => segments.filter((s) => s.type === type).flatMap(feedbackOf)));
172
+ this.messageRejected = segments
173
+ .filter((s) => s.type === 'HIRMG')
174
+ .flatMap(feedbackOf)
175
+ .some((f) => f.isError);
176
+ }
177
+ /**
178
+ * Parses a message; throws `FormatError` if `data` is not a FinTS message, such as the HTML page of a proxy or a
179
+ * maintenance notice.
180
+ */
181
+ static parse(data) {
182
+ const outer = parseSegments(data);
183
+ if (outer[0]?.type !== 'HNHBK')
184
+ throw new FormatError('Not a FinTS message: no message header');
185
+ const segments = [];
186
+ for (const s of outer) {
187
+ if (s.type === 'HNVSD') {
188
+ const payload = s.binary(1);
189
+ if (payload !== undefined)
190
+ segments.push(...parseSegments(payload));
191
+ }
192
+ else {
193
+ segments.push(s);
194
+ }
195
+ }
196
+ return new IncomingMessage3(segments, data.length);
197
+ }
198
+ static combine(first, second) {
199
+ return new IncomingMessage3([...first.segments, ...second.segments], first.size + second.size);
200
+ }
201
+ get bankMessages() {
202
+ return this.findAll('HIKIM').map((m) => new BankMessage(m.text(1) ?? '', m.text(2) ?? ''));
203
+ }
204
+ get dialogId() {
205
+ return this.find('HNHBK')?.text(3);
206
+ }
207
+ find(type) {
208
+ return this.segments.find((s) => s.type === type);
209
+ }
210
+ findAll(type) {
211
+ return this.segments.filter((s) => s.type === type);
212
+ }
213
+ }
214
+ function feedbackOf(s) {
215
+ const feedback = [];
216
+ for (let i = 1; i < s.length; i++) {
217
+ const code = s.text(i);
218
+ if (code === undefined)
219
+ continue;
220
+ const parameters = [];
221
+ // Empty parameters stay, as empty text, so that each keeps its position.
222
+ for (let j = 3; j < s.group(i).length; j++)
223
+ parameters.push(s.text(i, j) ?? '');
224
+ feedback.push(new FinTsFeedback({ code, reference: s.text(i, 1), text: s.text(i, 2) ?? '', parameters }));
225
+ }
226
+ return feedback;
227
+ }
228
+ /**
229
+ * Unpacks the transport encoding: PIN/TAN servers answer in base64, a few with the raw message.
230
+ *
231
+ * Returns anything else unchanged, for `IncomingMessage3.parse` to reject.
232
+ */
233
+ export function decodeTransport(body) {
234
+ if (startsWithMessageHeader(body))
235
+ return body;
236
+ try {
237
+ return decodeBase64Lines(latin1Decode(body));
238
+ }
239
+ catch (error) {
240
+ if (error instanceof FormatError)
241
+ return body;
242
+ throw error;
243
+ }
244
+ }
245
+ const messageHeader = latin1Encode('HNHBK');
246
+ const whitespaceBytes = new Set([0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x20]);
247
+ /** Whether `body` is a raw message: its header segment comes first, after any white space. */
248
+ function startsWithMessageHeader(body) {
249
+ let start = 0;
250
+ while (start < body.length && whitespaceBytes.has(body[start]))
251
+ start++;
252
+ if (body.length - start < messageHeader.length)
253
+ return false;
254
+ return messageHeader.every((byte, i) => body[start + i] === byte);
255
+ }
256
+ export function encodeTransport(message) {
257
+ return latin1Encode(base64Encode(message));
258
+ }
259
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/v3/message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import { Account } from '../core/account.js';
2
+ import type { Balance } from '../core/balance.js';
3
+ import { BankInfo } from '../core/bank-info.js';
4
+ import { type BankParameters, type UserParameters } from '../session/parameter-data.js';
5
+ import { TanMethod } from '../tan/tan-models.js';
6
+ import { type Segment } from './syntax.js';
7
+ /** FinTS 3.0 bank parameter data (BPD): HIBPA and the parameter segments (`HI…S`), parsed once. */
8
+ export declare class Bpd3 implements BankParameters {
9
+ readonly segments: readonly Segment[];
10
+ readonly bankInfo: BankInfo;
11
+ /** The two-step TAN methods of HITANS versions 6 and 7, by security function. */
12
+ private readonly offeredMethods;
13
+ readonly tanMethods: readonly TanMethod[];
14
+ readonly unsupportedTanMethods: readonly string[];
15
+ readonly pinTan: PinTanParameters;
16
+ /** camt formats the bank offers for HKCAZ. */
17
+ readonly camtFormats: readonly string[];
18
+ /** Versions of each parameter segment, by segment type. */
19
+ private readonly versions;
20
+ /**
21
+ * The dialog language HKVVB names: the bank's standard language (HIKOM), else the first it supports (HIBPA). Only
22
+ * these may be sent once the parameter data are known; `0`, the default, only before (Formals C.3.1.3).
23
+ */
24
+ readonly dialogLanguage: number;
25
+ private constructor();
26
+ get version(): number;
27
+ get pinLength(): {
28
+ min: number | undefined;
29
+ max: number | undefined;
30
+ };
31
+ allowsWithPinTan(transaction: string): boolean;
32
+ /** The BPD in `all`, or `undefined` if they contain no HIBPA segment. */
33
+ static fromSegments(all: readonly Segment[], fallbackBankCode: string): Bpd3 | undefined;
34
+ /** The parameter segment type of a business transaction: `HKSAL` → `HISALS`. */
35
+ static parameterName(transaction: string): string;
36
+ bestVersion(transaction: string, implemented: ReadonlySet<number>): number | undefined;
37
+ /** The version of the HKTAN segments that go with `method`; `undefined` for a method the bank does not offer. */
38
+ tanVersion(method: TanMethod): number | undefined;
39
+ }
40
+ /**
41
+ * PIN/TAN parameters (HIPINS): the PIN length, which business transactions PIN/TAN allows, and which of them need a
42
+ * TAN.
43
+ */
44
+ export declare class PinTanParameters {
45
+ private readonly tanRequired;
46
+ /** The shortest and longest PIN the bank takes. */
47
+ readonly pinLength: {
48
+ min: number | undefined;
49
+ max: number | undefined;
50
+ };
51
+ private constructor();
52
+ /** Reads the HIPINS segment of the highest version. */
53
+ static parse(segments: readonly Segment[]): PinTanParameters;
54
+ /** Whether the bank wants a TAN for the business transaction of `segmentType`, such as `HKKAZ`. */
55
+ requiresTan(segmentType: string): boolean;
56
+ /** Whether PIN/TAN allows `segmentType` at all: HIPINS lists it, or lists no business transactions (PIN/TAN B.8.1). */
57
+ allowsWithPinTan(segmentType: string): boolean;
58
+ }
59
+ /** FinTS 3.0 user parameter data (UPD): HIUPA and the accounts (HIUPD), parsed once. */
60
+ export declare class Upd3 implements UserParameters {
61
+ readonly segments: readonly Segment[];
62
+ readonly version: number;
63
+ readonly listsAllTransactions: boolean;
64
+ readonly listedTransactions: ReadonlySet<string>;
65
+ /** The accounts with the extension each carries, where it does. */
66
+ private readonly entries;
67
+ readonly accounts: readonly Account[];
68
+ /** `listsAll` tells whether HIUPA declares the lists of permitted transactions complete ("UPD-Verwendung" 0). */
69
+ private constructor();
70
+ /** FinTS 3.0 UPD do not list the allowed TAN methods; the bank reports them with return code 3920. */
71
+ get allowedTanMethods(): readonly string[];
72
+ completeBalance(account: Account): Balance | undefined;
73
+ /** The UPD in `all`, or `undefined` if they contain no HIUPA segment. */
74
+ static fromSegments(all: readonly Segment[], defaultBankCode: string, defaultCountry: string): Upd3 | undefined;
75
+ }
76
+ /** Serializes parameter segments for the saved state. */
77
+ export declare function encodeSegments(segments: readonly Segment[]): string;
78
+ export declare function decodeSegments(data: string): Segment[];
79
+ //# sourceMappingURL=parameters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameters.d.ts","sourceRoot":"","sources":["../../src/v3/parameters.ts"],"names":[],"mappings":"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"}