1
1
// SubDomain.ts
2
2
3
3
import baseX from "base-x" ;
4
- import crypto from "crypto" ;
5
4
6
5
/**
7
6
* SubDomain Class
8
7
*
9
8
* Encapsulates the logic for encoding and decoding a combination of
10
- * chain and storeId into a DNS-friendly identifier using Base62 encoding and HMAC .
9
+ * chain and storeId into a DNS-friendly identifier using Base62 encoding.
11
10
*/
12
11
class SubDomain {
13
12
// Define the Base62 character set
@@ -18,12 +17,7 @@ class SubDomain {
18
17
private static base62 = baseX ( SubDomain . BASE62_CHARSET ) ;
19
18
20
19
// Define expected byte length for storeId
21
- private static readonly DEFAULT_STORE_ID_LENGTH = 32 ; // bytes
22
- private static readonly HMAC_LENGTH = 32 ; // bytes for HMAC-SHA256
23
-
24
- // Hardcoded compression key
25
- private static readonly COMPRESSION_KEY =
26
- "7a4e8d2f6b1c9a3f5d8e2c4b7a1f9d3e6b8c5a2f4d7e9b1c8a3f5d2e6b9c4a7" ;
20
+ private static readonly STORE_ID_LENGTH = 32 ; // bytes
27
21
28
22
// Properties
29
23
public readonly chain : string ;
@@ -44,9 +38,9 @@ class SubDomain {
44
38
}
45
39
46
40
/**
47
- * Encodes the provided chain and storeId into a DNS-friendly identifier with HMAC .
41
+ * Encodes the provided chain and storeId into a DNS-friendly identifier.
48
42
*
49
- * @returns The Base62-encoded identifier with appended HMAC .
43
+ * @returns The Base62-encoded identifier.
50
44
* @throws Will throw an error if encoding fails.
51
45
*/
52
46
private encode ( ) : string {
@@ -83,9 +77,9 @@ class SubDomain {
83
77
const storeIdBuffer = Buffer . from ( this . storeId , "hex" ) ;
84
78
85
79
// Validate storeId byte length
86
- if ( storeIdBuffer . length !== SubDomain . DEFAULT_STORE_ID_LENGTH ) {
80
+ if ( storeIdBuffer . length !== SubDomain . STORE_ID_LENGTH ) {
87
81
throw new Error (
88
- `Invalid storeId length: Expected ${ SubDomain . DEFAULT_STORE_ID_LENGTH } bytes, got ${ storeIdBuffer . length } bytes.`
82
+ `Invalid storeId length: Expected ${ SubDomain . STORE_ID_LENGTH } bytes, got ${ storeIdBuffer . length } bytes.`
89
83
) ;
90
84
}
91
85
@@ -96,16 +90,8 @@ class SubDomain {
96
90
storeIdBuffer ,
97
91
] ) ;
98
92
99
- // Create HMAC using SHA256
100
- const hmac = crypto . createHmac ( "sha256" , SubDomain . COMPRESSION_KEY ) ;
101
- hmac . update ( dataBuffer ) ;
102
- const hmacDigest = hmac . digest ( ) ; // 32 bytes
103
-
104
- // Concatenate dataBuffer and hmacDigest
105
- const finalBuffer = Buffer . concat ( [ dataBuffer , hmacDigest ] ) ;
106
-
107
- // Encode the final buffer using Base62
108
- const encodedId = SubDomain . base62 . encode ( finalBuffer ) ;
93
+ // Encode the data buffer using Base62
94
+ const encodedId = SubDomain . base62 . encode ( dataBuffer ) ;
109
95
110
96
// Ensure DNS label length does not exceed 63 characters
111
97
if ( encodedId . length > 63 ) {
@@ -118,11 +104,11 @@ class SubDomain {
118
104
}
119
105
120
106
/**
121
- * Decodes the provided identifier back into the original chain and storeId after verifying HMAC .
107
+ * Decodes the provided identifier back into the original chain and storeId.
122
108
*
123
- * @param encodedId - The Base62-encoded identifier with appended HMAC .
109
+ * @param encodedId - The Base62-encoded identifier.
124
110
* @returns An object containing the original chain and storeId.
125
- * @throws Will throw an error if decoding fails, HMAC verification fails, or data lengths mismatch.
111
+ * @throws Will throw an error if decoding fails or data lengths mismatch.
126
112
*/
127
113
public static decode ( encodedId : string ) : { chain : string ; storeId : string } {
128
114
// Validate input
@@ -139,56 +125,29 @@ class SubDomain {
139
125
throw new Error ( "Failed to decode Base62 string." ) ;
140
126
}
141
127
142
- // Ensure there's at least 1 byte for chain_length and 64 bytes for storeId and HMAC
143
- if (
144
- decodedBuffer . length <
145
- 1 + SubDomain . DEFAULT_STORE_ID_LENGTH + SubDomain . HMAC_LENGTH
146
- ) {
128
+ // Ensure there's at least 1 byte for chain_length and STORE_ID_LENGTH bytes for storeId
129
+ if ( decodedBuffer . length < 1 + SubDomain . STORE_ID_LENGTH ) {
147
130
throw new Error ( "Decoded data is too short to contain required fields." ) ;
148
131
}
149
132
150
133
// Extract chain_length (1 byte)
151
134
const chain_length = Buffer . from ( decodedBuffer ) . readUInt8 ( 0 ) ;
152
135
153
136
// Define the expected total length
154
- const expected_length =
155
- 1 +
156
- chain_length +
157
- SubDomain . DEFAULT_STORE_ID_LENGTH +
158
- SubDomain . HMAC_LENGTH ;
137
+ const expected_length = 1 + chain_length + SubDomain . STORE_ID_LENGTH ;
159
138
160
139
if ( decodedBuffer . length !== expected_length ) {
161
140
throw new Error (
162
141
`Decoded data length mismatch: expected ${ expected_length } bytes, got ${ decodedBuffer . length } bytes.`
163
142
) ;
164
143
}
165
144
166
- // Extract chain, storeId, and received HMAC from the buffer
167
- const chain = Buffer . from (
168
- decodedBuffer . slice ( 1 , 1 + chain_length )
169
- ) . toString ( "utf8" ) ;
145
+ // Extract chain and storeId from the buffer
146
+ const chain = Buffer . from ( decodedBuffer . slice ( 1 , 1 + chain_length ) ) . toString ( "utf8" ) ;
170
147
const storeIdBuffer = decodedBuffer . slice (
171
148
1 + chain_length ,
172
- 1 + chain_length + SubDomain . DEFAULT_STORE_ID_LENGTH
149
+ 1 + chain_length + SubDomain . STORE_ID_LENGTH
173
150
) ;
174
- const receivedHmac = decodedBuffer . slice (
175
- 1 + chain_length + SubDomain . DEFAULT_STORE_ID_LENGTH ,
176
- expected_length
177
- ) ;
178
-
179
- // Recompute HMAC over [chain_length][chain][storeId]
180
- const dataBuffer = decodedBuffer . slice (
181
- 0 ,
182
- 1 + chain_length + SubDomain . DEFAULT_STORE_ID_LENGTH
183
- ) ;
184
- const hmac = crypto . createHmac ( "sha256" , SubDomain . COMPRESSION_KEY ) ;
185
- hmac . update ( dataBuffer ) ;
186
- const expectedHmac = hmac . digest ( ) ; // 32 bytes
187
-
188
- // Compare HMACs securely
189
- if ( ! crypto . timingSafeEqual ( receivedHmac , expectedHmac ) ) {
190
- throw new Error ( "HMAC verification failed: Invalid identifier." ) ;
191
- }
192
151
193
152
// Convert storeId buffer to hex string
194
153
const storeId = Buffer . from ( storeIdBuffer ) . toString ( "hex" ) ;
0 commit comments