@@ -25,6 +25,13 @@ interface SiwxMessage {
25
25
uri : string ;
26
26
}
27
27
28
+ interface ParsedUri {
29
+ scheme : string | null ;
30
+ domain ?: string ;
31
+ path ?: string ;
32
+ queryString ?: string ;
33
+ }
34
+
28
35
/**
29
36
* Parses a given message string and extracts various components into a SiwxMessage object.
30
37
*
@@ -126,42 +133,61 @@ function expect(test: boolean, errorMessage: string) {
126
133
*
127
134
* @throws Will throw an error if the schemes, paths, or domains do not match.
128
135
*/
129
- function validateDomainAndUri ( msgUri : string , expectedUri : string ) {
130
- const parseUri = ( uri : string ) => {
136
+ function validateDomainAndUri ( msgUri : string , expectedUri : string | string [ ] ) {
137
+ const parseUri = ( uri : string ) : ParsedUri => {
131
138
const [ scheme , domainWithPath ] = uri . includes ( '://' ) ? uri . split ( '://' , 2 ) : [ null , uri ] ;
132
139
const [ domainAndPath , queryString ] = domainWithPath . split ( '?' , 2 ) ?? [ domainWithPath , '' ] ;
133
140
const [ domain , path ] = domainAndPath ?. split ( '/' , 2 ) ?? [ domainAndPath , '' ] ;
134
141
return { scheme, domain, path, queryString } ;
135
142
} ;
136
143
137
144
const msgParsed = parseUri ( msgUri ) ;
138
- const expectedParsed = parseUri ( expectedUri ) ;
139
145
140
- // If the expected URI has a scheme, the scheme must match
141
- if ( expectedParsed . scheme ) {
142
- expect (
143
- msgParsed . scheme === expectedParsed . scheme ,
144
- `Message does not match expected domain. Domain scheme mismatch. Scheme: ${ msgParsed . scheme } Expected: ${ expectedParsed . scheme } `
145
- ) ;
146
+ const errors : string [ ] = [ ] ;
147
+ const uri = Array . isArray ( expectedUri ) ? expectedUri : [ expectedUri ] ;
148
+ for ( const expected of uri ) {
149
+ const expectedParsed = parseUri ( expected ) ;
150
+ const error = validateParsedDomainAndUri ( msgParsed , expectedParsed ) ;
151
+ if ( ! error ) return ;
152
+ errors . push ( error ) ;
146
153
}
147
154
148
- // If the expected URI has a path, the path must match
149
- if ( expectedParsed . path ) {
155
+ expect ( errors . length === 0 , 'Message does not match any expected domain. ' + errors . join ( '\n' ) ) ;
156
+ }
157
+
158
+ function validateParsedDomainAndUri ( msgParsed : ParsedUri , expectedParsed : ParsedUri ) : string | null {
159
+ try {
160
+ // If the expected URI has a scheme, the scheme must match
161
+ if ( expectedParsed . scheme ) {
162
+ expect (
163
+ msgParsed . scheme === expectedParsed . scheme ,
164
+ `Message does not match expected domain. Domain scheme mismatch. Scheme: ${ msgParsed . scheme } Expected: ${ expectedParsed . scheme } `
165
+ ) ;
166
+ }
167
+
168
+ // If the expected URI has a path, the path must match
169
+ if ( expectedParsed . path ) {
170
+ expect (
171
+ msgParsed . path === expectedParsed . path ,
172
+ `Message does not match expected domain. Domain path mismatch. Path: ${ msgParsed . path } Expected: ${ expectedParsed . path } `
173
+ ) ;
174
+ }
175
+
176
+ // Ignore ports in validation
177
+ const msgParsedDomain = msgParsed . domain ?. split ( ':' ) [ 0 ] ;
178
+ const expectedParsedDomain = expectedParsed . domain ?. split ( ':' ) [ 0 ] ;
179
+
180
+ // If the domain in the message does not match the domain in the URI, throw an error
150
181
expect (
151
- msgParsed . path === expectedParsed . path ,
152
- `Message does not match expected domain. Domain path mismatch. Path : ${ msgParsed . path } Expected: ${ expectedParsed . path } `
182
+ msgParsedDomain === expectedParsedDomain ,
183
+ `Message does not match expected domain. Domain: ${ msgParsedDomain } Expected: ${ expectedParsedDomain } `
153
184
) ;
185
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
186
+ } catch ( error : any ) {
187
+ return error . message ;
154
188
}
155
189
156
- // Ignore ports in validation
157
- const msgParsedDomain = msgParsed . domain ?. split ( ':' ) [ 0 ] ;
158
- const expectedParsedDomain = expectedParsed . domain ?. split ( ':' ) [ 0 ] ;
159
-
160
- // If the domain in the message does not match the domain in the URI, throw an error
161
- expect (
162
- msgParsedDomain === expectedParsedDomain ,
163
- `Message does not match expected domain. Domain: ${ msgParsedDomain } Expected: ${ expectedParsedDomain } `
164
- ) ;
190
+ return null ;
165
191
}
166
192
167
193
/**
@@ -179,7 +205,7 @@ function validateDomainAndUri(msgUri: string, expectedUri: string) {
179
205
function validateLoginPayload (
180
206
payload : SiwfResponsePayloadLogin ,
181
207
userPublicKey : SiwfPublicKey ,
182
- loginMsgUri : string
208
+ loginMsgUri : string | string [ ]
183
209
) : void {
184
210
// Check that the userPublicKey signed the message
185
211
expect (
@@ -219,7 +245,7 @@ function validateExtrinsicPayloadSignature(key: string, signature: string, messa
219
245
expect ( verifySignatureMaybeWrapped ( key , signature , hexToU8a ( message ) ) , 'Payload signature failed' ) ;
220
246
}
221
247
222
- export async function validatePayloads ( response : SiwfResponse , loginMsgUri : string ) : Promise < void > {
248
+ export async function validatePayloads ( response : SiwfResponse , loginMsgUri : string | string [ ] ) : Promise < void > {
223
249
// Wait for the WASM to load
224
250
await cryptoWaitReady ( ) ;
225
251
response . payloads . every ( ( payload ) => {
0 commit comments