cyberchef 11.1.0 → 11.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 (148) hide show
  1. package/AGENTS.md +75 -0
  2. package/CHANGELOG.md +173 -2
  3. package/Dockerfile +2 -2
  4. package/Gruntfile.js +1 -0
  5. package/README.md +7 -6
  6. package/SECURITY.md +3 -1
  7. package/package.json +22 -21
  8. package/src/core/Chef.mjs +2 -0
  9. package/src/core/Dish.mjs +1 -5
  10. package/src/core/Ingredient.mjs +92 -0
  11. package/src/core/Operation.mjs +19 -0
  12. package/src/core/Recipe.mjs +4 -0
  13. package/src/core/Utils.mjs +48 -0
  14. package/src/core/config/Categories.json +22 -6
  15. package/src/core/config/OperationConfig.json +4774 -1228
  16. package/src/core/config/modules/Ciphers.mjs +20 -0
  17. package/src/core/config/modules/Crypto.mjs +10 -0
  18. package/src/core/config/modules/Default.mjs +8 -0
  19. package/src/core/config/modules/File.mjs +16 -0
  20. package/src/core/config/modules/OpModules.mjs +2 -0
  21. package/src/core/config/scripts/generateHTMLEntities.mjs +139 -0
  22. package/src/core/config/scripts/htmlEntityOverrides.mjs +86 -0
  23. package/src/core/dishTypes/DishType.mjs +1 -1
  24. package/src/core/errors/ExcludedOperationError.mjs +1 -1
  25. package/src/core/lib/Arithmetic.mjs +21 -5
  26. package/src/core/lib/BigIntUtils.mjs +0 -1
  27. package/src/core/lib/COBS.mjs +86 -0
  28. package/src/core/lib/Charts.mjs +3 -3
  29. package/src/core/lib/Decimal.mjs +5 -5
  30. package/src/core/lib/HTMLEntities.mjs +2068 -0
  31. package/src/core/lib/Present.mjs +422 -0
  32. package/src/core/lib/Protocol.mjs +8 -6
  33. package/src/core/lib/TEA.mjs +494 -0
  34. package/src/core/lib/TLVParser.mjs +16 -7
  35. package/src/core/lib/Twofish.mjs +608 -0
  36. package/src/core/operations/AsconDecrypt.mjs +112 -0
  37. package/src/core/operations/AsconEncrypt.mjs +108 -0
  38. package/src/core/operations/AsconHash.mjs +49 -0
  39. package/src/core/operations/AsconMAC.mjs +68 -0
  40. package/src/core/operations/AutomatedValidationTestOp.mjs +84 -0
  41. package/src/core/operations/AvroToJSON.mjs +1 -1
  42. package/src/core/operations/BLAKE3.mjs +5 -1
  43. package/src/core/operations/BcryptCompare.mjs +11 -5
  44. package/src/core/operations/BitShiftLeft.mjs +4 -1
  45. package/src/core/operations/Bzip2Compress.mjs +1 -1
  46. package/src/core/operations/DechunkHTTPResponse.mjs +4 -1
  47. package/src/core/operations/ExtendedGCD.mjs +101 -0
  48. package/src/core/operations/FromBase.mjs +2 -1
  49. package/src/core/operations/FromCOBS.mjs +38 -0
  50. package/src/core/operations/FromDecimal.mjs +6 -1
  51. package/src/core/operations/FromHTMLEntity.mjs +2 -1458
  52. package/src/core/operations/GenerateDeBruijnSequence.mjs +8 -0
  53. package/src/core/operations/GenerateHOTP.mjs +21 -6
  54. package/src/core/operations/GenerateImage.mjs +22 -10
  55. package/src/core/operations/GeneratePrime.mjs +154 -0
  56. package/src/core/operations/GenerateTOTP.mjs +24 -7
  57. package/src/core/operations/Gzip.mjs +1 -3
  58. package/src/core/operations/Jsonata.mjs +12 -0
  59. package/src/core/operations/MIMEDecoding.mjs +1 -1
  60. package/src/core/operations/MOD.mjs +62 -0
  61. package/src/core/operations/ModularInverse.mjs +107 -0
  62. package/src/core/operations/PRESENTDecrypt.mjs +94 -0
  63. package/src/core/operations/PRESENTEncrypt.mjs +94 -0
  64. package/src/core/operations/ParityBit.mjs +1 -1
  65. package/src/core/operations/ParseIPv4Header.mjs +1 -1
  66. package/src/core/operations/ParseURI.mjs +18 -5
  67. package/src/core/operations/PseudoRandomNumberGenerator.mjs +2 -1
  68. package/src/core/operations/RandomPrime.mjs +154 -0
  69. package/src/core/operations/RenderPDF.mjs +100 -0
  70. package/src/core/operations/SHA2.mjs +1 -1
  71. package/src/core/operations/SM4Encrypt.mjs +1 -1
  72. package/src/core/operations/SetDifference.mjs +8 -1
  73. package/src/core/operations/SetIntersection.mjs +8 -1
  74. package/src/core/operations/ShowOnMap.mjs +14 -2
  75. package/src/core/operations/TEADecrypt.mjs +98 -0
  76. package/src/core/operations/TEAEncrypt.mjs +98 -0
  77. package/src/core/operations/ToBase.mjs +4 -4
  78. package/src/core/operations/ToBase32.mjs +20 -4
  79. package/src/core/operations/ToBinary.mjs +4 -1
  80. package/src/core/operations/ToCOBS.mjs +38 -0
  81. package/src/core/operations/ToHTMLEntity.mjs +7 -1430
  82. package/src/core/operations/ToHexdump.mjs +7 -1
  83. package/src/core/operations/TwofishDecrypt.mjs +94 -0
  84. package/src/core/operations/TwofishEncrypt.mjs +94 -0
  85. package/src/core/operations/URLEncode.mjs +22 -18
  86. package/src/core/operations/UnescapeUnicodeCharacters.mjs +2 -1
  87. package/src/core/operations/ViewBitPlane.mjs +9 -3
  88. package/src/core/operations/Wrap.mjs +5 -0
  89. package/src/core/operations/XORBruteForce.mjs +4 -1
  90. package/src/core/operations/XORChecksum.mjs +10 -3
  91. package/src/core/operations/XTEADecrypt.mjs +110 -0
  92. package/src/core/operations/XTEAEncrypt.mjs +110 -0
  93. package/src/core/operations/index.mjs +42 -0
  94. package/src/core/vendor/ascon.mjs +162 -0
  95. package/src/core/vendor/htmlEntities/entity.json +2233 -0
  96. package/src/core/vendor/htmlEntities/entity.txt +14 -0
  97. package/src/node/api.mjs +4 -1
  98. package/src/node/index.mjs +105 -0
  99. package/src/web/HTMLOperation.mjs +2 -1
  100. package/src/web/stylesheets/layout/_io.css +8 -0
  101. package/tests/browser/00_nightwatch.js +26 -0
  102. package/tests/browser/02_ops.js +20 -4
  103. package/tests/node/index.mjs +2 -0
  104. package/tests/node/tests/Dish.mjs +19 -0
  105. package/tests/node/tests/NodeDish.mjs +36 -0
  106. package/tests/node/tests/ToHTMLEntity.mjs +82 -0
  107. package/tests/node/tests/Utils.mjs +77 -0
  108. package/tests/node/tests/lib/ChartsProtocolPrototypePollution.mjs +90 -0
  109. package/tests/node/tests/nodeApi.mjs +33 -1
  110. package/tests/node/tests/operations.mjs +26 -1
  111. package/tests/operations/index.mjs +17 -0
  112. package/tests/operations/tests/Arithmetic.mjs +33 -0
  113. package/tests/operations/tests/Ascon.mjs +501 -0
  114. package/tests/operations/tests/AutomatedValidation.mjs +154 -0
  115. package/tests/operations/tests/BLAKE3.mjs +39 -1
  116. package/tests/operations/tests/Base32.mjs +22 -0
  117. package/tests/operations/tests/COBS.mjs +476 -0
  118. package/tests/operations/tests/CharEnc.mjs +2 -2
  119. package/tests/operations/tests/DechunkHTTPResponse.mjs +66 -0
  120. package/tests/operations/tests/ExtendedGCD.mjs +78 -0
  121. package/tests/operations/tests/FromBase.mjs +66 -0
  122. package/tests/operations/tests/FromDecimal.mjs +55 -0
  123. package/tests/operations/tests/GenerateLoremIpsum.mjs +2 -2
  124. package/tests/operations/tests/Gzip.mjs +60 -0
  125. package/tests/operations/tests/HTMLEntity.mjs +126 -0
  126. package/tests/operations/tests/Hash.mjs +44 -0
  127. package/tests/operations/tests/Hexdump.mjs +11 -0
  128. package/tests/operations/tests/Image.mjs +26 -0
  129. package/tests/operations/tests/Jsonata.mjs +23 -0
  130. package/tests/operations/tests/MIMEDecoding.mjs +33 -0
  131. package/tests/operations/tests/MOD.mjs +208 -0
  132. package/tests/operations/tests/Median.mjs +33 -0
  133. package/tests/operations/tests/ModularInverse.mjs +78 -0
  134. package/tests/operations/tests/OTP.mjs +167 -2
  135. package/tests/operations/tests/PRESENT.mjs +465 -0
  136. package/tests/operations/tests/ParseIPv4Header.mjs +11 -0
  137. package/tests/operations/tests/ParseTLV.mjs +41 -0
  138. package/tests/operations/tests/RenderPDF.mjs +55 -0
  139. package/tests/operations/tests/SM2.mjs +1 -1
  140. package/tests/operations/tests/SetDifference.mjs +22 -0
  141. package/tests/operations/tests/SetIntersection.mjs +23 -1
  142. package/tests/operations/tests/ShowOnMap.mjs +61 -0
  143. package/tests/operations/tests/TEA.mjs +566 -0
  144. package/tests/operations/tests/Twofish.mjs +486 -0
  145. package/tests/operations/tests/URLEncodeDecode.mjs +26 -0
  146. package/tests/operations/tests/UnescapeUnicodeCharacters.mjs +88 -0
  147. package/tests/operations/tests/Wrap.mjs +44 -0
  148. package/webpack.config.js +3 -3
@@ -0,0 +1,208 @@
1
+ /**
2
+ * MOD tests
3
+ *
4
+ * @license Apache-2.0
5
+ */
6
+ import TestRegister from "../../lib/TestRegister.mjs";
7
+
8
+ TestRegister.addTests([
9
+ {
10
+ name: "MOD: Basic modulo operation",
11
+ input: "15 4 7",
12
+ expectedOutput: "0 1 1",
13
+ recipeConfig: [
14
+ {
15
+ "op": "MOD",
16
+ "args": [3, "Space"]
17
+ }
18
+ ],
19
+ },
20
+ {
21
+ name: "MOD: Single number",
22
+ input: "10",
23
+ expectedOutput: "1",
24
+ recipeConfig: [
25
+ {
26
+ "op": "MOD",
27
+ "args": [3, "Space"]
28
+ }
29
+ ],
30
+ },
31
+ {
32
+ name: "MOD: Comma-separated numbers",
33
+ input: "15,8,23,16,5",
34
+ expectedOutput: "1 1 2 2 5",
35
+ recipeConfig: [
36
+ {
37
+ "op": "MOD",
38
+ "args": [7, "Comma"]
39
+ }
40
+ ],
41
+ },
42
+ {
43
+ name: "MOD: Line feed separated numbers",
44
+ input: "25\n13\n44\n7",
45
+ expectedOutput: "0 3 4 2",
46
+ recipeConfig: [
47
+ {
48
+ "op": "MOD",
49
+ "args": [5, "Line feed"]
50
+ }
51
+ ],
52
+ },
53
+ {
54
+ name: "MOD: Large numbers",
55
+ input: "123456789012345 987654321098765",
56
+ expectedOutput: "123456789012345 987654321098765",
57
+ recipeConfig: [
58
+ {
59
+ "op": "MOD",
60
+ "args": [1234567890123456, "Space"]
61
+ }
62
+ ],
63
+ },
64
+ {
65
+ name: "MOD: Mixed with non-numeric values",
66
+ input: "15 abc 4 def 7 xyz 23",
67
+ expectedOutput: "0 1 1 2",
68
+ recipeConfig: [
69
+ {
70
+ "op": "MOD",
71
+ "args": [3, "Space"]
72
+ }
73
+ ],
74
+ },
75
+ {
76
+ name: "MOD: Decimal numbers",
77
+ input: "10.5 15.7 8.2",
78
+ expectedOutput: "1.5 0.7 2.2",
79
+ recipeConfig: [
80
+ {
81
+ "op": "MOD",
82
+ "args": [3, "Space"]
83
+ }
84
+ ],
85
+ },
86
+ {
87
+ name: "MOD: Negative numbers",
88
+ input: "-15 -8 25 -10",
89
+ expectedOutput: "0 -2 1 -1",
90
+ recipeConfig: [
91
+ {
92
+ "op": "MOD",
93
+ "args": [3, "Space"]
94
+ }
95
+ ],
96
+ },
97
+ {
98
+ name: "MOD: Zero in input",
99
+ input: "0 5 10 15 20",
100
+ expectedOutput: "0 2 1 0 2",
101
+ recipeConfig: [
102
+ {
103
+ "op": "MOD",
104
+ "args": [3, "Space"]
105
+ }
106
+ ],
107
+ },
108
+ {
109
+ name: "MOD: Modulus of 2 (even/odd check)",
110
+ input: "1 2 3 4 5 6 7 8 9 10",
111
+ expectedOutput: "1 0 1 0 1 0 1 0 1 0",
112
+ recipeConfig: [
113
+ {
114
+ "op": "MOD",
115
+ "args": [2, "Space"]
116
+ }
117
+ ],
118
+ },
119
+ {
120
+ name: "MOD: Numbers with extra whitespace",
121
+ input: " 15 4 7 ",
122
+ expectedOutput: "0 1 1",
123
+ recipeConfig: [
124
+ {
125
+ "op": "MOD",
126
+ "args": [3, "Space"]
127
+ }
128
+ ],
129
+ },
130
+ {
131
+ name: "MOD: Empty input",
132
+ input: "",
133
+ expectedOutput: "",
134
+ recipeConfig: [
135
+ {
136
+ "op": "MOD",
137
+ "args": [3, "Space"]
138
+ }
139
+ ],
140
+ },
141
+ {
142
+ name: "MOD: Scientific notation",
143
+ input: "1e3 2e2 5e1",
144
+ expectedOutput: "1 2 2",
145
+ recipeConfig: [
146
+ {
147
+ "op": "MOD",
148
+ "args": [3, "Space"]
149
+ }
150
+ ],
151
+ },
152
+ {
153
+ name: "MOD: Floating point precision",
154
+ input: "10.123456789 20.987654321",
155
+ expectedOutput: "1.123456789 2.987654321",
156
+ recipeConfig: [
157
+ {
158
+ "op": "MOD",
159
+ "args": [3, "Space"]
160
+ }
161
+ ],
162
+ },
163
+ {
164
+ name: "MOD: Zero modulus error",
165
+ input: "15 4 7",
166
+ expectedError: true,
167
+ expectedOutput: "MOD - Modulus cannot be zero",
168
+ recipeConfig: [
169
+ {
170
+ "op": "MOD",
171
+ "args": [0, "Space"]
172
+ }
173
+ ],
174
+ },
175
+ {
176
+ name: "MOD: Semi-colon separated numbers",
177
+ input: "17;5;8;13",
178
+ expectedOutput: "2 0 3 3",
179
+ recipeConfig: [
180
+ {
181
+ "op": "MOD",
182
+ "args": [5, "Semi-colon"]
183
+ }
184
+ ],
185
+ },
186
+ {
187
+ name: "MOD: Colon separated numbers",
188
+ input: "25:9:14:7",
189
+ expectedOutput: "1 1 2 3",
190
+ recipeConfig: [
191
+ {
192
+ "op": "MOD",
193
+ "args": [4, "Colon"]
194
+ }
195
+ ],
196
+ },
197
+ {
198
+ name: "MOD: CRLF separated numbers",
199
+ input: "30\r\n18\r\n22\r\n11",
200
+ expectedOutput: "0 0 4 5",
201
+ recipeConfig: [
202
+ {
203
+ "op": "MOD",
204
+ "args": [6, "CRLF"]
205
+ }
206
+ ],
207
+ },
208
+ ]);
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Median operation tests.
3
+ *
4
+ * @author copilot-swe-agent[bot]
5
+ * @copyright Crown Copyright 2018
6
+ * @license Apache-2.0
7
+ */
8
+ import TestRegister from "../../lib/TestRegister.mjs";
9
+
10
+ TestRegister.addTests([
11
+ {
12
+ name: "Median: odd-length input",
13
+ input: "10 1 2",
14
+ expectedOutput: "2",
15
+ recipeConfig: [
16
+ {
17
+ op: "Median",
18
+ args: ["Space"],
19
+ },
20
+ ],
21
+ },
22
+ {
23
+ name: "Median: even-length input",
24
+ input: "10 1 2 5",
25
+ expectedOutput: "3.5",
26
+ recipeConfig: [
27
+ {
28
+ op: "Median",
29
+ args: ["Space"],
30
+ },
31
+ ],
32
+ },
33
+ ]);
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Modular Inverse tests.
3
+ *
4
+ * @author p-leriche [philip.leriche@cantab.net]
5
+ *
6
+ * @copyright Crown Copyright 2025
7
+ * @license Apache-2.0
8
+ */
9
+ import TestRegister from "../../lib/TestRegister.mjs";
10
+
11
+ TestRegister.addTests([
12
+ {
13
+ name: "Modular Inverse: basic example (3 mod 11)",
14
+ input: "",
15
+ expectedOutput: "4",
16
+ recipeConfig: [
17
+ {
18
+ op: "Modular Inverse",
19
+ args: ["3", "11"],
20
+ },
21
+ ],
22
+ },
23
+ {
24
+ name: "Modular Inverse: another coprime pair (7 mod 26)",
25
+ input: "",
26
+ expectedOutput: "15",
27
+ recipeConfig: [
28
+ {
29
+ op: "Modular Inverse",
30
+ args: ["7", "26"],
31
+ },
32
+ ],
33
+ },
34
+ {
35
+ name: "Modular Inverse: hexadecimal input (0x10 mod 0x11)",
36
+ input: "",
37
+ expectedOutput: "16",
38
+ recipeConfig: [
39
+ {
40
+ op: "Modular Inverse",
41
+ args: ["0x10", "0x11"],
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ name: "Modular Inverse: using input field for value",
47
+ input: "5",
48
+ expectedOutput: "21",
49
+ recipeConfig: [
50
+ {
51
+ op: "Modular Inverse",
52
+ args: ["", "26"],
53
+ },
54
+ ],
55
+ },
56
+ {
57
+ name: "Modular Inverse: using input field for modulus",
58
+ input: "17",
59
+ expectedOutput: "7",
60
+ recipeConfig: [
61
+ {
62
+ op: "Modular Inverse",
63
+ args: ["5", ""],
64
+ },
65
+ ],
66
+ },
67
+ {
68
+ name: "Modular Inverse: large number (RSA-like)",
69
+ input: "",
70
+ expectedOutput: "934281398294",
71
+ recipeConfig: [
72
+ {
73
+ op: "Modular Inverse",
74
+ args: ["65537", "9999999999999"],
75
+ },
76
+ ],
77
+ },
78
+ ]);
@@ -12,11 +12,176 @@ TestRegister.addTests([
12
12
  {
13
13
  name: "Generate HOTP",
14
14
  input: "JBSWY3DPEHPK3PXP",
15
- expectedOutput: `URI: otpauth://hotp/?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0\n\nPassword: 282760`,
15
+ expectedOutput: `URI: otpauth://hotp/Account?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0\n\nPassword: 282760`,
16
16
  recipeConfig: [
17
17
  {
18
18
  op: "Generate HOTP",
19
- args: ["", 6, 0], // [Name, Code length, Counter]
19
+ args: ["Account", 6, 0], // [Name, Code length, Counter]
20
+ },
21
+ ],
22
+ },
23
+ {
24
+ name: "Generate HOTP - empty name rejected",
25
+ input: "JBSWY3DPEHPK3PXP",
26
+ expectedOutput: "Name cannot be empty.",
27
+ recipeConfig: [
28
+ {
29
+ op: "Generate HOTP",
30
+ args: ["", 6, 0],
31
+ },
32
+ ],
33
+ },
34
+ {
35
+ name: "Generate HOTP - code length below minimum rejected",
36
+ input: "JBSWY3DPEHPK3PXP",
37
+ expectedOutput: "Code length must be greater than or equal to 6.",
38
+ recipeConfig: [
39
+ {
40
+ op: "Generate HOTP",
41
+ args: ["Account", -6, 0],
42
+ },
43
+ ],
44
+ },
45
+ {
46
+ name: "Generate HOTP - code length above maximum rejected",
47
+ input: "JBSWY3DPEHPK3PXP",
48
+ expectedOutput: "Code length must be less than or equal to 8.",
49
+ recipeConfig: [
50
+ {
51
+ op: "Generate HOTP",
52
+ args: ["Account", 9, 0],
53
+ },
54
+ ],
55
+ },
56
+ {
57
+ name: "Generate HOTP - non-integer code length rejected",
58
+ input: "JBSWY3DPEHPK3PXP",
59
+ expectedOutput: "Code length must be an integer.",
60
+ recipeConfig: [
61
+ {
62
+ op: "Generate HOTP",
63
+ args: ["Account", 6.5, 0],
64
+ },
65
+ ],
66
+ },
67
+ {
68
+ name: "Generate HOTP - negative counter rejected",
69
+ input: "JBSWY3DPEHPK3PXP",
70
+ expectedOutput: "Counter must be greater than or equal to 0.",
71
+ recipeConfig: [
72
+ {
73
+ op: "Generate HOTP",
74
+ args: ["Account", 6, -1],
75
+ },
76
+ ],
77
+ },
78
+ {
79
+ name: "Generate HOTP - special characters in name are URI-encoded",
80
+ input: "JBSWY3DPEHPK3PXP",
81
+ expectedOutput: `URI: otpauth://hotp/user%40example.com?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&counter=0\n\nPassword: 282760`,
82
+ recipeConfig: [
83
+ {
84
+ op: "Generate HOTP",
85
+ args: ["user@example.com", 6, 0],
86
+ },
87
+ ],
88
+ },
89
+ {
90
+ name: "Generate TOTP",
91
+ input: "JBSWY3DPEHPK3PXP",
92
+ expectedMatch: /^URI: otpauth:\/\/totp\/Account\?secret=JBSWY3DPEHPK3PXP&algorithm=SHA1&digits=6&period=30\n\nPassword: \d{6}$/,
93
+ recipeConfig: [
94
+ {
95
+ op: "Generate TOTP",
96
+ args: ["Account", 6, 0, 30], // [Name, Code length, Epoch offset (T0), Interval (T1)]
97
+ },
98
+ ],
99
+ },
100
+ {
101
+ name: "Generate TOTP - empty name rejected",
102
+ input: "JBSWY3DPEHPK3PXP",
103
+ expectedOutput: "Name cannot be empty.",
104
+ recipeConfig: [
105
+ {
106
+ op: "Generate TOTP",
107
+ args: ["", 6, 0, 30],
108
+ },
109
+ ],
110
+ },
111
+ {
112
+ name: "Generate TOTP - code length below minimum rejected",
113
+ input: "JBSWY3DPEHPK3PXP",
114
+ expectedOutput: "Code length must be greater than or equal to 6.",
115
+ recipeConfig: [
116
+ {
117
+ op: "Generate TOTP",
118
+ args: ["Account", -6, 0, 30],
119
+ },
120
+ ],
121
+ },
122
+ {
123
+ name: "Generate TOTP - code length above maximum rejected",
124
+ input: "JBSWY3DPEHPK3PXP",
125
+ expectedOutput: "Code length must be less than or equal to 8.",
126
+ recipeConfig: [
127
+ {
128
+ op: "Generate TOTP",
129
+ args: ["Account", 9, 0, 30],
130
+ },
131
+ ],
132
+ },
133
+ {
134
+ name: "Generate TOTP - non-integer code length rejected",
135
+ input: "JBSWY3DPEHPK3PXP",
136
+ expectedOutput: "Code length must be an integer.",
137
+ recipeConfig: [
138
+ {
139
+ op: "Generate TOTP",
140
+ args: ["Account", 6.5, 0, 30],
141
+ },
142
+ ],
143
+ },
144
+ {
145
+ name: "Generate TOTP - negative interval rejected",
146
+ input: "JBSWY3DPEHPK3PXP",
147
+ expectedOutput: "Interval (T1) must be greater than or equal to 1.",
148
+ recipeConfig: [
149
+ {
150
+ op: "Generate TOTP",
151
+ args: ["Account", 6, 0, -1],
152
+ },
153
+ ],
154
+ },
155
+ {
156
+ name: "Generate TOTP - negative epoch offset rejected",
157
+ input: "JBSWY3DPEHPK3PXP",
158
+ expectedOutput: "Epoch offset (T0) must be greater than or equal to 0.",
159
+ recipeConfig: [
160
+ {
161
+ op: "Generate TOTP",
162
+ args: ["Account", 6, -1, 30],
163
+ },
164
+ ],
165
+ },
166
+ {
167
+ name: "Generate HOTP - invalid base32 secret rejected",
168
+ input: "not,valid|base32;input",
169
+ expectedOutput: "Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).",
170
+ recipeConfig: [
171
+ {
172
+ op: "Generate HOTP",
173
+ args: ["Account", 6, 0],
174
+ },
175
+ ],
176
+ },
177
+ {
178
+ name: "Generate TOTP - invalid base32 secret rejected",
179
+ input: "not,valid|base32;input",
180
+ expectedOutput: "Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).",
181
+ recipeConfig: [
182
+ {
183
+ op: "Generate TOTP",
184
+ args: ["Account", 6, 0, 30],
20
185
  },
21
186
  ],
22
187
  },