diff --git a/.gitignore b/.gitignore index aa6922d..3bc06ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .dart_tool/ -.direnv \ No newline at end of file +.direnv +secret \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 6d7a358..6d69bbd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,13 +9,15 @@ "program": "bin/matrixgate.dart", "args": [ "--homeserver", - "foo", + "https://matrix.federated.nexus", "--jwtSecretFile", - "foo", + "secret", "--issuer", - "http://localhost:8080", + "http://localhost:8080/", "--authorizeEndpoint", - "https://federated.nexus/login" + "http://localhost:4321/login", + "--serviceDomain", + "federated.nexus" ], "request": "launch", "type": "dart" diff --git a/analysis_options.yaml b/analysis_options.yaml index dee8927..98042bd 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,13 +1,13 @@ # This file configures the static analysis results for your project (errors, # warnings, and lints). # -# This enables the 'recommended' set of lints from `package:lints`. +# This enables the "recommended" set of lints from `package:lints`. # This set helps identify many issues that may lead to problems when running # or consuming Dart code, and enforces writing Dart using a single, idiomatic # style and format. # # If you want a smaller set of lints you can change this to specify -# 'package:lints/core.yaml'. These are just the most critical lints +# "package:lints/core.yaml". These are just the most critical lints # (the recommended set includes the core lints). # The core lints are also what is used by pub.dev for scoring packages. diff --git a/bin/matrixgate.dart b/bin/matrixgate.dart index 469967d..3f4fbb9 100644 --- a/bin/matrixgate.dart +++ b/bin/matrixgate.dart @@ -10,8 +10,9 @@ import "package:shelf_router/shelf_router.dart"; void main(List argsRaw) async { final parser = ArgParser() ..addOption("socket", abbr: "s") - ..addOption("address", abbr: "a", defaultsTo: "127.0.0.1") + ..addOption("serviceDomain", abbr: "d") ..addOption("port", abbr: "p", defaultsTo: "8080") + ..addOption("address", abbr: "a", defaultsTo: "127.0.0.1") ..addOption("issuer", abbr: "i", mandatory: true) ..addOption("homeserver", abbr: "h", mandatory: true) ..addOption("jwtSecretFile", abbr: "j", mandatory: true) @@ -33,7 +34,7 @@ void main(List argsRaw) async { "/.well-known/openid-configuration", apiHelper.openidConfiguration, ) - ..get("/userInfo", apiHelper.userinfoHandler) + ..get("/userinfo", apiHelper.userinfoHandler) ..get("/jwks.json", apiHelper.jwks) ..post("/login", apiHelper.handleLogin) ..post("/token", apiHelper.tokenHandler)) diff --git a/lib/helpers/api_helper.dart b/lib/helpers/api_helper.dart index 591259d..62ee31b 100644 --- a/lib/helpers/api_helper.dart +++ b/lib/helpers/api_helper.dart @@ -21,9 +21,28 @@ class ApiHelper { final password = data["password"]; final redirectUri = data["redirect_uri"]; final state = data["state"] ?? ""; + final clientId = data["client_id"]; + final scope = data["scope"]; + final nonce = data["nonce"]; + + if ([ + username, + password, + redirectUri, + clientId, + nonce, + scope, + ].any((f) => f == null)) { + return Response(400, body: "Missing required field(s)"); + } + + if (!Uri.parse(redirectUri!).host.endsWith(settings.serviceDomain)) { + return Response(403, body: "Redirect URI not allowed"); + } final loginRes = await http.post( - Uri.https(settings.homeserver, "_matrix/client/v3/login"), + Uri.parse("${settings.homeserver}/_matrix/client/v3/login"), + headers: {"Content-Type": "application/json"}, body: json.encode({ "type": "m.login.password", "identifier": {"type": "m.id.user", "user": username}, @@ -40,9 +59,8 @@ class ApiHelper { final accessToken = loginData["access_token"]; final openidRes = await http.post( - Uri.https( - settings.homeserver, - "_matrix/client/v3/user/$userId/openid/request", + Uri.parse( + "${settings.homeserver}/_matrix/client/v3/user/${Uri.encodeComponent(userId)}/openid/request_token", ), headers: {"Authorization": "Bearer $accessToken"}, ); @@ -58,9 +76,13 @@ class ApiHelper { final code = base64Url.encode( List.generate(16, (_) => DateTime.now().millisecond % 256), ); + ref .read(AuthCodeController.provider.notifier) - .set(code, MatrixUser(userId: userId, matrixToken: openidToken)); + .set( + code, + MatrixUser(userId: userId, matrixToken: openidToken, nonce: nonce!), + ); return Response.found("$redirectUri?code=$code&state=$state"); } @@ -69,34 +91,38 @@ class ApiHelper { final settings = ref.read(SettingsController.provider)!; final body = Uri.splitQueryString(await request.readAsString()); final code = body["code"]; + final clientId = body["client_id"]; + + if (code == null || clientId == null) { + return Response(400, body: "Missing code or client_id"); + } final codes = ref.read(AuthCodeController.provider); - - if (code == null || !codes.containsKey(code)) { + if (!codes.containsKey(code)) { return Response(400, body: "Invalid code"); } final user = codes[code]!; ref.read(AuthCodeController.provider.notifier).remove(code); + final secret = await File.fromUri( + Uri.file(settings.jwtSecretFile), + ).readAsString(); + final jwt = JWT( { + "nonce": user.nonce, "exp": - DateTime.now().add(Duration(minutes: 10)).millisecondsSinceEpoch ~/ + DateTime.now().add(Duration(days: 7)).millisecondsSinceEpoch ~/ 1000, "iat": DateTime.now().millisecondsSinceEpoch ~/ 1000, }, subject: user.userId, - issuer: ref.read(SettingsController.provider)!.issuer, - audience: Audience([body["client_id"]!]), + issuer: settings.issuer, + audience: Audience([clientId]), ); - final token = jwt.sign( - SecretKey( - await File.fromUri(Uri.file(settings.jwtSecretFile)).readAsString(), - ), - algorithm: JWTAlgorithm.HS256, - ); + final token = jwt.sign(SecretKey(secret), algorithm: JWTAlgorithm.HS256); return Response.ok( json.encode({ @@ -119,9 +145,8 @@ class ApiHelper { final token = auth.substring(7); final matrixResp = await http.get( - Uri.https( - ref.read(SettingsController.provider)!.homeserver, - "_matrix/federation/v1/openid/userinfo", + Uri.parse( + "${ref.read(SettingsController.provider)!.homeserver}/_matrix/federation/v1/openid/userinfo", ), headers: {"Authorization": "Bearer $token"}, ); @@ -133,10 +158,16 @@ class ApiHelper { ); } - return Response.ok(matrixResp.body); + return Response.ok( + matrixResp.body, + headers: {"content-type": "application/json"}, + ); } - Response jwks(_) => Response.ok(json.encode({"keys": []})); + Response jwks(_) => Response.ok( + json.encode({"keys": []}), + headers: {"content-type": "application/json"}, + ); Response openidConfiguration(_) { final settings = ref.read(SettingsController.provider)!; @@ -145,7 +176,7 @@ class ApiHelper { "issuer": settings.issuer, "authorization_endpoint": settings.authorizeEndpoint, "token_endpoint": "${settings.issuer}/token", - "userinfo_endpoint": "${settings.issuer}/userInfo", + "userinfo_endpoint": "${settings.issuer}/userinfo", "jwks_uri": "${settings.issuer}/jwks.json", "response_types_supported": ["code"], "subject_types_supported": ["public"], diff --git a/lib/models/matrix_user.dart b/lib/models/matrix_user.dart index 805fb3f..e2d88df 100644 --- a/lib/models/matrix_user.dart +++ b/lib/models/matrix_user.dart @@ -8,6 +8,7 @@ abstract class MatrixUser with _$MatrixUser { const factory MatrixUser({ required String userId, required String matrixToken, + required String nonce, }) = _MatrixUser; factory MatrixUser.fromJson(Map json) => diff --git a/lib/models/matrix_user.freezed.dart b/lib/models/matrix_user.freezed.dart index 0dd35c7..953ea7e 100644 --- a/lib/models/matrix_user.freezed.dart +++ b/lib/models/matrix_user.freezed.dart @@ -4,7 +4,7 @@ // ignore_for_file: type=lint // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark -part of 'matrix_user.dart'; +part of "matrix_user.dart"; // ************************************************************************** // FreezedGenerator @@ -16,11 +16,11 @@ T _$identity(T value) => value; /// @nodoc mixin _$MatrixUser { - String get userId; String get matrixToken; + String get userId; String get matrixToken; String get nonce; /// Create a copy of MatrixUser /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') +@pragma("vm:prefer-inline") $MatrixUserCopyWith get copyWith => _$MatrixUserCopyWithImpl(this as MatrixUser, _$identity); /// Serializes this MatrixUser to a JSON map. @@ -29,16 +29,16 @@ $MatrixUserCopyWith get copyWith => _$MatrixUserCopyWithImpl Object.hash(runtimeType,userId,matrixToken); +int get hashCode => Object.hash(runtimeType,userId,matrixToken,nonce); @override String toString() { - return 'MatrixUser(userId: $userId, matrixToken: $matrixToken)'; + return "MatrixUser(userId: $userId, matrixToken: $matrixToken, nonce: $nonce)"; } @@ -49,7 +49,7 @@ abstract mixin class $MatrixUserCopyWith<$Res> { factory $MatrixUserCopyWith(MatrixUser value, $Res Function(MatrixUser) _then) = _$MatrixUserCopyWithImpl; @useResult $Res call({ - String userId, String matrixToken + String userId, String matrixToken, String nonce }); @@ -66,10 +66,11 @@ class _$MatrixUserCopyWithImpl<$Res> /// Create a copy of MatrixUser /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? userId = null,Object? matrixToken = null,}) { +@pragma("vm:prefer-inline") @override $Res call({Object? userId = null,Object? matrixToken = null,Object? nonce = null,}) { return _then(_self.copyWith( userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable as String,matrixToken: null == matrixToken ? _self.matrixToken : matrixToken // ignore: cast_nullable_to_non_nullable +as String,nonce: null == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable as String, )); } @@ -81,16 +82,17 @@ as String, @JsonSerializable() class _MatrixUser implements MatrixUser { - const _MatrixUser({required this.userId, required this.matrixToken}); + const _MatrixUser({required this.userId, required this.matrixToken, required this.nonce}); factory _MatrixUser.fromJson(Map json) => _$MatrixUserFromJson(json); @override final String userId; @override final String matrixToken; +@override final String nonce; /// Create a copy of MatrixUser /// with the given fields replaced by the non-null parameter values. @override @JsonKey(includeFromJson: false, includeToJson: false) -@pragma('vm:prefer-inline') +@pragma("vm:prefer-inline") _$MatrixUserCopyWith<_MatrixUser> get copyWith => __$MatrixUserCopyWithImpl<_MatrixUser>(this, _$identity); @override @@ -100,16 +102,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _MatrixUser&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.matrixToken, matrixToken) || other.matrixToken == matrixToken)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _MatrixUser&&(identical(other.userId, userId) || other.userId == userId)&&(identical(other.matrixToken, matrixToken) || other.matrixToken == matrixToken)&&(identical(other.nonce, nonce) || other.nonce == nonce)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,userId,matrixToken); +int get hashCode => Object.hash(runtimeType,userId,matrixToken,nonce); @override String toString() { - return 'MatrixUser(userId: $userId, matrixToken: $matrixToken)'; + return "MatrixUser(userId: $userId, matrixToken: $matrixToken, nonce: $nonce)"; } @@ -120,7 +122,7 @@ abstract mixin class _$MatrixUserCopyWith<$Res> implements $MatrixUserCopyWith<$ factory _$MatrixUserCopyWith(_MatrixUser value, $Res Function(_MatrixUser) _then) = __$MatrixUserCopyWithImpl; @override @useResult $Res call({ - String userId, String matrixToken + String userId, String matrixToken, String nonce }); @@ -137,10 +139,11 @@ class __$MatrixUserCopyWithImpl<$Res> /// Create a copy of MatrixUser /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? userId = null,Object? matrixToken = null,}) { +@override @pragma("vm:prefer-inline") $Res call({Object? userId = null,Object? matrixToken = null,Object? nonce = null,}) { return _then(_MatrixUser( userId: null == userId ? _self.userId : userId // ignore: cast_nullable_to_non_nullable as String,matrixToken: null == matrixToken ? _self.matrixToken : matrixToken // ignore: cast_nullable_to_non_nullable +as String,nonce: null == nonce ? _self.nonce : nonce // ignore: cast_nullable_to_non_nullable as String, )); } diff --git a/lib/models/matrix_user.g.dart b/lib/models/matrix_user.g.dart index e3aa600..5384062 100644 --- a/lib/models/matrix_user.g.dart +++ b/lib/models/matrix_user.g.dart @@ -1,18 +1,20 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'matrix_user.dart'; +part of "matrix_user.dart"; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** _MatrixUser _$MatrixUserFromJson(Map json) => _MatrixUser( - userId: json['userId'] as String, - matrixToken: json['matrixToken'] as String, + userId: json["userId"] as String, + matrixToken: json["matrixToken"] as String, + nonce: json["nonce"] as String, ); Map _$MatrixUserToJson(_MatrixUser instance) => { - 'userId': instance.userId, - 'matrixToken': instance.matrixToken, + "userId": instance.userId, + "matrixToken": instance.matrixToken, + "nonce": instance.nonce, }; diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 3fa8820..6d7a895 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -11,6 +11,7 @@ abstract class Settings with _$Settings { required String port, required String homeserver, required String issuer, + required String serviceDomain, required String jwtSecretFile, required String authorizeEndpoint, }) = _Settings; diff --git a/lib/models/settings.freezed.dart b/lib/models/settings.freezed.dart index 81dc77c..7a858e1 100644 --- a/lib/models/settings.freezed.dart +++ b/lib/models/settings.freezed.dart @@ -16,7 +16,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$Settings { - String? get socket; String get address; String get port; String get homeserver; String get issuer; String get jwtSecretFile; String get authorizeEndpoint; + String? get socket; String get address; String get port; String get homeserver; String get issuer; String get serviceDomain; String get jwtSecretFile; String get authorizeEndpoint; /// Create a copy of Settings /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -29,16 +29,16 @@ $SettingsCopyWith get copyWith => _$SettingsCopyWithImpl(thi @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is Settings&&(identical(other.socket, socket) || other.socket == socket)&&(identical(other.address, address) || other.address == address)&&(identical(other.port, port) || other.port == port)&&(identical(other.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.issuer, issuer) || other.issuer == issuer)&&(identical(other.jwtSecretFile, jwtSecretFile) || other.jwtSecretFile == jwtSecretFile)&&(identical(other.authorizeEndpoint, authorizeEndpoint) || other.authorizeEndpoint == authorizeEndpoint)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is Settings&&(identical(other.socket, socket) || other.socket == socket)&&(identical(other.address, address) || other.address == address)&&(identical(other.port, port) || other.port == port)&&(identical(other.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.issuer, issuer) || other.issuer == issuer)&&(identical(other.serviceDomain, serviceDomain) || other.serviceDomain == serviceDomain)&&(identical(other.jwtSecretFile, jwtSecretFile) || other.jwtSecretFile == jwtSecretFile)&&(identical(other.authorizeEndpoint, authorizeEndpoint) || other.authorizeEndpoint == authorizeEndpoint)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,socket,address,port,homeserver,issuer,jwtSecretFile,authorizeEndpoint); +int get hashCode => Object.hash(runtimeType,socket,address,port,homeserver,issuer,serviceDomain,jwtSecretFile,authorizeEndpoint); @override String toString() { - return 'Settings(socket: $socket, address: $address, port: $port, homeserver: $homeserver, issuer: $issuer, jwtSecretFile: $jwtSecretFile, authorizeEndpoint: $authorizeEndpoint)'; + return 'Settings(socket: $socket, address: $address, port: $port, homeserver: $homeserver, issuer: $issuer, serviceDomain: $serviceDomain, jwtSecretFile: $jwtSecretFile, authorizeEndpoint: $authorizeEndpoint)'; } @@ -49,7 +49,7 @@ abstract mixin class $SettingsCopyWith<$Res> { factory $SettingsCopyWith(Settings value, $Res Function(Settings) _then) = _$SettingsCopyWithImpl; @useResult $Res call({ - String? socket, String address, String port, String homeserver, String issuer, String jwtSecretFile, String authorizeEndpoint + String? socket, String address, String port, String homeserver, String issuer, String serviceDomain, String jwtSecretFile, String authorizeEndpoint }); @@ -66,13 +66,14 @@ class _$SettingsCopyWithImpl<$Res> /// Create a copy of Settings /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? socket = freezed,Object? address = null,Object? port = null,Object? homeserver = null,Object? issuer = null,Object? jwtSecretFile = null,Object? authorizeEndpoint = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? socket = freezed,Object? address = null,Object? port = null,Object? homeserver = null,Object? issuer = null,Object? serviceDomain = null,Object? jwtSecretFile = null,Object? authorizeEndpoint = null,}) { return _then(_self.copyWith( socket: freezed == socket ? _self.socket : socket // ignore: cast_nullable_to_non_nullable as String?,address: null == address ? _self.address : address // ignore: cast_nullable_to_non_nullable as String,port: null == port ? _self.port : port // ignore: cast_nullable_to_non_nullable as String,homeserver: null == homeserver ? _self.homeserver : homeserver // ignore: cast_nullable_to_non_nullable as String,issuer: null == issuer ? _self.issuer : issuer // ignore: cast_nullable_to_non_nullable +as String,serviceDomain: null == serviceDomain ? _self.serviceDomain : serviceDomain // ignore: cast_nullable_to_non_nullable as String,jwtSecretFile: null == jwtSecretFile ? _self.jwtSecretFile : jwtSecretFile // ignore: cast_nullable_to_non_nullable as String,authorizeEndpoint: null == authorizeEndpoint ? _self.authorizeEndpoint : authorizeEndpoint // ignore: cast_nullable_to_non_nullable as String, @@ -86,7 +87,7 @@ as String, @JsonSerializable() class _Settings implements Settings { - const _Settings({required this.socket, required this.address, required this.port, required this.homeserver, required this.issuer, required this.jwtSecretFile, required this.authorizeEndpoint}); + const _Settings({required this.socket, required this.address, required this.port, required this.homeserver, required this.issuer, required this.serviceDomain, required this.jwtSecretFile, required this.authorizeEndpoint}); factory _Settings.fromJson(Map json) => _$SettingsFromJson(json); @override final String? socket; @@ -94,6 +95,7 @@ class _Settings implements Settings { @override final String port; @override final String homeserver; @override final String issuer; +@override final String serviceDomain; @override final String jwtSecretFile; @override final String authorizeEndpoint; @@ -110,16 +112,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _Settings&&(identical(other.socket, socket) || other.socket == socket)&&(identical(other.address, address) || other.address == address)&&(identical(other.port, port) || other.port == port)&&(identical(other.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.issuer, issuer) || other.issuer == issuer)&&(identical(other.jwtSecretFile, jwtSecretFile) || other.jwtSecretFile == jwtSecretFile)&&(identical(other.authorizeEndpoint, authorizeEndpoint) || other.authorizeEndpoint == authorizeEndpoint)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Settings&&(identical(other.socket, socket) || other.socket == socket)&&(identical(other.address, address) || other.address == address)&&(identical(other.port, port) || other.port == port)&&(identical(other.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.issuer, issuer) || other.issuer == issuer)&&(identical(other.serviceDomain, serviceDomain) || other.serviceDomain == serviceDomain)&&(identical(other.jwtSecretFile, jwtSecretFile) || other.jwtSecretFile == jwtSecretFile)&&(identical(other.authorizeEndpoint, authorizeEndpoint) || other.authorizeEndpoint == authorizeEndpoint)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,socket,address,port,homeserver,issuer,jwtSecretFile,authorizeEndpoint); +int get hashCode => Object.hash(runtimeType,socket,address,port,homeserver,issuer,serviceDomain,jwtSecretFile,authorizeEndpoint); @override String toString() { - return 'Settings(socket: $socket, address: $address, port: $port, homeserver: $homeserver, issuer: $issuer, jwtSecretFile: $jwtSecretFile, authorizeEndpoint: $authorizeEndpoint)'; + return 'Settings(socket: $socket, address: $address, port: $port, homeserver: $homeserver, issuer: $issuer, serviceDomain: $serviceDomain, jwtSecretFile: $jwtSecretFile, authorizeEndpoint: $authorizeEndpoint)'; } @@ -130,7 +132,7 @@ abstract mixin class _$SettingsCopyWith<$Res> implements $SettingsCopyWith<$Res> factory _$SettingsCopyWith(_Settings value, $Res Function(_Settings) _then) = __$SettingsCopyWithImpl; @override @useResult $Res call({ - String? socket, String address, String port, String homeserver, String issuer, String jwtSecretFile, String authorizeEndpoint + String? socket, String address, String port, String homeserver, String issuer, String serviceDomain, String jwtSecretFile, String authorizeEndpoint }); @@ -147,13 +149,14 @@ class __$SettingsCopyWithImpl<$Res> /// Create a copy of Settings /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? socket = freezed,Object? address = null,Object? port = null,Object? homeserver = null,Object? issuer = null,Object? jwtSecretFile = null,Object? authorizeEndpoint = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? socket = freezed,Object? address = null,Object? port = null,Object? homeserver = null,Object? issuer = null,Object? serviceDomain = null,Object? jwtSecretFile = null,Object? authorizeEndpoint = null,}) { return _then(_Settings( socket: freezed == socket ? _self.socket : socket // ignore: cast_nullable_to_non_nullable as String?,address: null == address ? _self.address : address // ignore: cast_nullable_to_non_nullable as String,port: null == port ? _self.port : port // ignore: cast_nullable_to_non_nullable as String,homeserver: null == homeserver ? _self.homeserver : homeserver // ignore: cast_nullable_to_non_nullable as String,issuer: null == issuer ? _self.issuer : issuer // ignore: cast_nullable_to_non_nullable +as String,serviceDomain: null == serviceDomain ? _self.serviceDomain : serviceDomain // ignore: cast_nullable_to_non_nullable as String,jwtSecretFile: null == jwtSecretFile ? _self.jwtSecretFile : jwtSecretFile // ignore: cast_nullable_to_non_nullable as String,authorizeEndpoint: null == authorizeEndpoint ? _self.authorizeEndpoint : authorizeEndpoint // ignore: cast_nullable_to_non_nullable as String, diff --git a/lib/models/settings.g.dart b/lib/models/settings.g.dart index c5f7f94..2b35689 100644 --- a/lib/models/settings.g.dart +++ b/lib/models/settings.g.dart @@ -12,6 +12,7 @@ _Settings _$SettingsFromJson(Map json) => _Settings( port: json['port'] as String, homeserver: json['homeserver'] as String, issuer: json['issuer'] as String, + serviceDomain: json['serviceDomain'] as String, jwtSecretFile: json['jwtSecretFile'] as String, authorizeEndpoint: json['authorizeEndpoint'] as String, ); @@ -22,6 +23,7 @@ Map _$SettingsToJson(_Settings instance) => { 'port': instance.port, 'homeserver': instance.homeserver, 'issuer': instance.issuer, + 'serviceDomain': instance.serviceDomain, 'jwtSecretFile': instance.jwtSecretFile, 'authorizeEndpoint': instance.authorizeEndpoint, };