@@ -21,11 +21,11 @@ import '../../xdr/xdr_transaction.dart';
21
21
import '../0001/stellar_toml.dart' ;
22
22
23
23
class WebAuth {
24
- String ? _authEndpoint;
25
- String ? _serverSigningKey;
26
- Network ? _network;
27
- String ? _serverHomeDomain;
28
- http.Client httpClient = new http. Client () ;
24
+ String _authEndpoint;
25
+ String _serverSigningKey;
26
+ Network _network;
27
+ String _serverHomeDomain;
28
+ late http.Client httpClient;
29
29
int gracePeriod = 60 * 5 ;
30
30
31
31
/// Constructor
@@ -34,7 +34,13 @@ class WebAuth {
34
34
/// - Parameter serverSigningKey: The server public key, taken from stellar.toml.
35
35
/// - Parameter serverHomeDomain: The server home domain of the server where the stellar.toml was loaded from
36
36
WebAuth (this ._authEndpoint, this ._network, this ._serverSigningKey,
37
- this ._serverHomeDomain);
37
+ this ._serverHomeDomain, {http.Client ? httpClient}) {
38
+ if (httpClient != null ) {
39
+ this .httpClient = httpClient;
40
+ } else {
41
+ this .httpClient = http.Client ();
42
+ }
43
+ }
38
44
39
45
/// Creates a WebAuth instance by loading the needed data from the stellar.toml file hosted on the given domain.
40
46
/// e.g. fromDomain("soneso.com", Network.TESTNET)
@@ -51,14 +57,14 @@ class WebAuth {
51
57
);
52
58
53
59
if (toml.generalInformation.webAuthEndpoint == null ) {
54
- throw Exception ( "No WEB_AUTH_ENDPOINT found in stellar.toml" );
60
+ throw NoWebAuthEndpointFoundException (domain );
55
61
}
56
62
if (toml.generalInformation.signingKey == null ) {
57
- throw Exception ( "No auth server SIGNING_KEY found in stellar.toml" );
63
+ throw NoWebAuthServerSigningKeyFoundException (domain );
58
64
}
59
65
60
- return new WebAuth (toml.generalInformation.webAuthEndpoint, network,
61
- toml.generalInformation.signingKey, domain);
66
+ return new WebAuth (toml.generalInformation.webAuthEndpoint! , network,
67
+ toml.generalInformation.signingKey! , domain, httpClient : httpClient );
62
68
}
63
69
64
70
/// Get JWT token for wallet.
@@ -85,13 +91,12 @@ class WebAuth {
85
91
clientDomainAccountId = clientDomainAccountKeyPair.accountId;
86
92
} else if (clientDomainSigningDelegate != null ) {
87
93
if (clientDomain == null ) {
88
- throw Exception (
89
- "The clientDomain is required if clientDomainSigningDelegate is provided" );
94
+ throw MissingClientDomainException ();
90
95
}
91
96
final StellarToml clientToml =
92
97
await StellarToml .fromDomain (clientDomain, httpClient: httpClient);
93
98
if (clientToml.generalInformation.signingKey == null ) {
94
- throw Exception ( "No client domain SIGNING_KEY found in stellar.toml" );
99
+ throw NoClientDomainSigningKeyFoundException (clientDomain );
95
100
}
96
101
clientDomainAccountId = clientToml.generalInformation.signingKey;
97
102
}
@@ -128,7 +133,7 @@ class WebAuth {
128
133
129
134
String ? transaction = challengeResponse.transaction;
130
135
if (transaction == null ) {
131
- throw Exception ( "Error parsing challenge response" );
136
+ throw MissingTransactionInChallengeResponseException ( );
132
137
}
133
138
return transaction;
134
139
}
@@ -203,13 +208,13 @@ class WebAuth {
203
208
}
204
209
}
205
210
206
- if (i == 0 && dataName != _serverHomeDomain! + " auth" ) {
211
+ if (i == 0 && dataName != _serverHomeDomain + " auth" ) {
207
212
throw ChallengeValidationErrorInvalidHomeDomain (
208
213
"invalid home domain in operation $i " );
209
214
}
210
215
final dataValue = op.body.manageDataOp! .dataValue! .dataValue;
211
216
if (i > 0 && dataName == "web_auth_domain" ) {
212
- final uri = Uri .parse (_authEndpoint! );
217
+ final uri = Uri .parse (_authEndpoint);
213
218
if (uri.host != String .fromCharCodes (dataValue)) {
214
219
throw ChallengeValidationErrorInvalidWebAuthDomain (
215
220
"invalid web auth domain in operation $i " );
@@ -240,9 +245,9 @@ class WebAuth {
240
245
}
241
246
final firstSignature = envelopeXdr.v1! .signatures[0 ];
242
247
// validate signature
243
- final serverKeyPair = KeyPair .fromAccountId (_serverSigningKey! );
248
+ final serverKeyPair = KeyPair .fromAccountId (_serverSigningKey);
244
249
final transactionHash =
245
- AbstractTransaction .fromEnvelopeXdr (envelopeXdr).hash (_network! );
250
+ AbstractTransaction .fromEnvelopeXdr (envelopeXdr).hash (_network);
246
251
final valid = serverKeyPair.verify (
247
252
transactionHash, firstSignature.signature! .signature! );
248
253
if (! valid) {
@@ -260,7 +265,7 @@ class WebAuth {
260
265
}
261
266
262
267
final txHash =
263
- AbstractTransaction .fromEnvelopeXdr (envelopeXdr).hash (_network! );
268
+ AbstractTransaction .fromEnvelopeXdr (envelopeXdr).hash (_network);
264
269
265
270
List <XdrDecoratedSignature > signatures =
266
271
List <XdrDecoratedSignature >.empty (growable: true );
@@ -276,7 +281,7 @@ class WebAuth {
276
281
/// In case of success, it returns the jwt token obtained from the web auth server.
277
282
Future <String > sendSignedChallengeTransaction (
278
283
String base64EnvelopeXDR) async {
279
- Uri serverURI = Uri .parse (_authEndpoint! );
284
+ Uri serverURI = Uri .parse (_authEndpoint);
280
285
281
286
Map <String , String > headers = {...RequestBuilder .headers};
282
287
headers.putIfAbsent ("Content-Type" , () => "application/json" );
@@ -314,11 +319,10 @@ class WebAuth {
314
319
Future <ChallengeResponse > getChallengeResponse (String accountId,
315
320
[int ? memo, String ? homeDomain, String ? clientDomain]) async {
316
321
if (memo != null && accountId.startsWith ("M" )) {
317
- throw new Exception (
318
- "memo cannot be used if accountId is a muxed account" );
322
+ throw NoMemoForMuxedAccountsException ();
319
323
}
320
324
321
- Uri serverURI = Uri .parse (_authEndpoint! );
325
+ Uri serverURI = Uri .parse (_authEndpoint);
322
326
try {
323
327
_ChallengeRequestBuilder requestBuilder =
324
328
new _ChallengeRequestBuilder (httpClient, serverURI);
@@ -500,3 +504,57 @@ class SubmitCompletedChallengeErrorResponseException implements Exception {
500
504
501
505
String get error => _error;
502
506
}
507
+
508
+ class NoWebAuthEndpointFoundException implements Exception {
509
+ String domain;
510
+
511
+ NoWebAuthEndpointFoundException (this .domain);
512
+
513
+ String toString () {
514
+ return "No WEB_AUTH_ENDPOINT found in stellar.toml for domain: $domain " ;
515
+ }
516
+ }
517
+
518
+ class NoWebAuthServerSigningKeyFoundException implements Exception {
519
+ String domain;
520
+
521
+ NoWebAuthServerSigningKeyFoundException (this .domain);
522
+
523
+ String toString () {
524
+ return "No auth server SIGNING_KEY found in stellar.toml for domain: $domain " ;
525
+ }
526
+ }
527
+
528
+ class NoClientDomainSigningKeyFoundException implements Exception {
529
+ String domain;
530
+
531
+ NoClientDomainSigningKeyFoundException (this .domain);
532
+
533
+ String toString () {
534
+ return "No client domain SIGNING_KEY found in stellar.toml for domain: $domain " ;
535
+ }
536
+ }
537
+
538
+ class MissingClientDomainException implements Exception {
539
+ MissingClientDomainException ();
540
+
541
+ String toString () {
542
+ return "The clientDomain is required if clientDomainSigningDelegate is provided" ;
543
+ }
544
+ }
545
+
546
+ class MissingTransactionInChallengeResponseException implements Exception {
547
+ MissingTransactionInChallengeResponseException ();
548
+
549
+ String toString () {
550
+ return "Missing transaction in challenge response" ;
551
+ }
552
+ }
553
+
554
+ class NoMemoForMuxedAccountsException implements Exception {
555
+ NoMemoForMuxedAccountsException ();
556
+
557
+ String toString () {
558
+ return "Memo cannot be used if account is a muxed account" ;
559
+ }
560
+ }
0 commit comments