diff --git a/.vscode/launch.json b/.vscode/launch.json index 2eb0341..bf9ab6a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,6 +15,8 @@ "https://matrix.federated.nexus", "--name", "nexusbot", + "--inviteTo", + "#community:federated.nexus", "--adminRoom", "#admins:federated.nexus", "--successUri", @@ -22,15 +24,7 @@ "--botPasswordFile", "secrets/botPassword.txt", "--smtpPasswordFile", - "secrets/smtpPassword.txt", - "--adminName", - "grapevine", - "--email", - "henry@henryhiles.com", - "--mailDomain", - "mail.henryhiles.com", - "--mailName", - "Federated Nexus Registrations" + "secrets/smtpPassword.txt" ], "request": "launch", "type": "dart" diff --git a/JUSTFILE b/JUSTFILE index dff0cc6..5fa18e3 100644 --- a/JUSTFILE +++ b/JUSTFILE @@ -1,8 +1,8 @@ -test: - curl --unix-socket ./socket http:/./ -X POST -d '{"email": "foo@henryhiles.com", "username": "name"}' - watch: dart run build_runner watch build: - dart run build_runner build \ No newline at end of file + dart run build_runner build + +test: + curl --unix-socket ./socket http:/root -X POST -d '{"email": "foo", "username": "bar"}' \ No newline at end of file diff --git a/bin/nexusbot.dart b/bin/nexusbot.dart index a56bc33..c4311b0 100644 --- a/bin/nexusbot.dart +++ b/bin/nexusbot.dart @@ -1,14 +1,7 @@ -import "dart:convert"; import "dart:io"; import "package:cli_tools/config.dart"; -import "package:enough_mail/enough_mail.dart" as mail; -import "package:markdown/markdown.dart"; -import "package:matrix/matrix.dart"; -import "package:nexusbot/controllers/client_controller.dart"; -import "package:nexusbot/controllers/mail_client_controller.dart"; -import "package:nexusbot/controllers/registration_controller.dart"; import "package:nexusbot/controllers/settings_controller.dart"; -import "package:nexusbot/models/registration.dart"; +import "package:nexusbot/helpers/api_helper.dart"; import "package:riverpod/riverpod.dart"; import "package:shelf/shelf.dart"; import "package:shelf/shelf_io.dart"; @@ -16,141 +9,30 @@ import "package:shelf_router/shelf_router.dart"; void main(List argsRaw) async { final parser = ConfigParser() - ..addOption("socket", mandatory: true) - ..addOption("homeserver", mandatory: true) - ..addOption("successUri", mandatory: true) - ..addOption("name", mandatory: true) - ..addOption("adminName", mandatory: true) - ..addOption("adminRoom", mandatory: true) - ..addOption("email", mandatory: true) - ..addOption("mailName", mandatory: true) - ..addOption("mailDomain", mandatory: true) - ..addOption("smtpPasswordFile", mandatory: true) - ..addOption("botPasswordFile", mandatory: true); + ..addOption("socket", abbr: "s", mandatory: true) + ..addOption("homeserver", abbr: "h", mandatory: true) + ..addOption("successUri", abbr: "u", mandatory: true) + ..addOption("name", abbr: "n", mandatory: true) + ..addOption("adminRoom", abbr: "a", mandatory: true) + ..addOption("botPasswordFile", abbr: "b", mandatory: true) + ..addOption("smtpPasswordFile", abbr: "p", mandatory: true) + ..addOption("inviteTo", abbr: "i"); final container = ProviderContainer(); container .read(SettingsController.provider.notifier) .set(parser.parse(argsRaw)); - final client = await container.read(ClientController.provider.future); - client.onTimelineEvent.stream.listen((event) async { - final settings = container.read(SettingsController.provider)!; - - if (event.room.canonicalAlias != settings.adminRoom) return; - if (event.senderId.startsWith("@${settings.name}:")) return; - switch (event.type) { - case EventTypes.Reaction: - if ((event.content["m.relates_to"] as Map)["key"] != - "✅") { - return; - } - final parentEvent = await client.getOneRoomEvent( - event.roomId!, - event.relationshipEventId!, - ); - if (!parentEvent.senderId.startsWith("@${settings.name}:")) return; - final registration = Registration.fromJson(parentEvent.content); - container - .read(RegistrationController.provider.notifier) - .add(registration); - - await event.room.sendTextEvent( - "!admin create-user ${registration.username}", - ); - break; - case EventTypes.Message: - if (!event.senderId.startsWith("@${settings.adminName}:")) break; - final results = RegExp( - r"@(?[a-zA-Z0-9._-]+):[^\s]+.*?password:\s+(?\S+)", - ).firstMatch(event.body); - if (results == null) return; - - final registration = container - .read(RegistrationController.provider) - .firstWhere( - (account) => account.username == results.namedGroup("username"), - ); - final password = results.namedGroup("password")!; - final reactionEvent = await event.room.sendReaction( - event.eventId, - "✉️ Sending...", - ); - - final from = mail.MailAddress(settings.mailName, settings.email); - final mailClient = await container.read( - MailClientController.provider.future, - ); - await mailClient.sendMessageBuilder( - mail.MessageBuilder.prepareMultipartAlternativeMessage( - plainText: - """Your registration for Federated Nexus has been accepted! Your credentials are: -Username: ${registration.username}. -Password: $password""", - htmlText: markdownToHtml( - """# Your registration for Federated Nexus has been accepted! -## Your credentials are: -- ### Username: ${registration.username}. -- ### Password: $password - -If you have any questions, check out [our documentation](https://federated.nexus/services/matrix/). - -If you have any issues, reply to this email.""", - ), - ) - ..subject = - "Your registration for Federated Nexus has been accepted!" - ..sender = from, - from: from, - recipients: [ - mail.MailAddress(registration.username, registration.email), - ], - ); - - await event.room.redactEvent(reactionEvent!); - await event.room.sendReaction(event.eventId, "✉️ Sent!"); - } - }); + final apiHelper = container.read(ApiHelper.provider); final handler = const Pipeline() .addMiddleware(logRequests()) - .addHandler( - (Router()..post("/", (Request request) async { - final settings = container.read(SettingsController.provider)!; - final registration = Registration.fromJson( - json.decode(await request.readAsString()), - ); - - final client = await container.read( - ClientController.provider.future, - ); - - final room = client.getRoomByAlias(settings.adminRoom); - final message = - """# Registration request -- Username: `${registration.username}` -- Email: `${registration.email}`"""; - final event = await room!.sendEvent({ - "body": message, - "msgtype": MessageTypes.Text, - "format": "org.matrix.custom.html", - "formatted_body": markdownToHtml(message), - ...registration.toJson(), - }); - - await room.sendReaction(event!, "✅"); - - return Response.found(settings.successUri); - })) - .call, - ); + .addHandler((Router()..post("/", apiHelper.register)).call); + final settings = container.read(SettingsController.provider)!; final server = HttpServer.listenOn( await ServerSocket.bind( - InternetAddress( - container.read(SettingsController.provider)!.socket, - type: InternetAddressType.unix, - ), + InternetAddress(settings.socket, type: InternetAddressType.unix), 0, ), ); diff --git a/flake.nix b/flake.nix index 715b303..603b68d 100644 --- a/flake.nix +++ b/flake.nix @@ -16,8 +16,7 @@ _module.args.pkgs = import inputs.nixpkgs {inherit system;}; devShells.default = pkgs.mkShell { - packages = with pkgs; [just dart watchexec]; - LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath (with pkgs; [sqlite])}:$LD_LIBRARY_PATH"; + buildInputs = with pkgs; [just dart watchexec]; }; packages.default = pkgs.buildDartApplication { diff --git a/lib/controllers/client_controller.dart b/lib/controllers/client_controller.dart deleted file mode 100644 index 066c618..0000000 --- a/lib/controllers/client_controller.dart +++ /dev/null @@ -1,33 +0,0 @@ -import "dart:io"; - -import "package:matrix/matrix.dart"; -import "package:nexusbot/controllers/settings_controller.dart"; -import "package:riverpod/riverpod.dart"; -import "package:sqflite_common_ffi/sqflite_ffi.dart"; - -class ClientController extends AsyncNotifier { - @override - Future build() async { - final settings = ref.watch(SettingsController.provider)!; - final client = Client( - "nexusbot", - database: await MatrixSdkDatabase.init( - "NexusBot", - database: await databaseFactoryFfi.openDatabase(inMemoryDatabasePath), - ), - ); - - await client.checkHomeserver(settings.homeserver); - await client.login( - LoginType.mLoginPassword, - identifier: AuthenticationUserIdentifier(user: settings.name), - password: (await File(settings.botPasswordFile).readAsString()).trim(), - ); - - return client; - } - - static final provider = AsyncNotifierProvider( - ClientController.new, - ); -} diff --git a/lib/controllers/last_synced_controller.dart b/lib/controllers/last_synced_controller.dart deleted file mode 100644 index a36d33d..0000000 --- a/lib/controllers/last_synced_controller.dart +++ /dev/null @@ -1,12 +0,0 @@ -import "package:riverpod/riverpod.dart"; - -class LastSyncedController extends Notifier { - @override - String? build() => null; - - void set(String value) => state = value; - - static final provider = NotifierProvider( - LastSyncedController.new, - ); -} diff --git a/lib/controllers/login_controller.dart b/lib/controllers/login_controller.dart new file mode 100644 index 0000000..3f30d7c --- /dev/null +++ b/lib/controllers/login_controller.dart @@ -0,0 +1,36 @@ +import "dart:io"; +import "dart:convert"; +import "package:http/http.dart"; +import "package:nexusbot/controllers/settings_controller.dart"; +import "package:riverpod/riverpod.dart"; + +class LoginController extends AsyncNotifier { + @override + Future build() async { + final settings = ref.watch(SettingsController.provider)!; + final response = await post( + settings.homeserver.replace(path: "_matrix/client/v3/login"), + headers: {HttpHeaders.contentTypeHeader: "application/json"}, + body: json.encode({ + "type": "m.login.password", + "device_id": "script", + "identifier": {"type": "m.id.user", "user": settings.name}, + "password": (await File( + settings.botPasswordFile, + ).readAsString()).trim(), + }), + ); + + if (response.statusCode != 200) { + throw Exception( + "Login failed, check your name, homeserver and botPasswordFile: ${response.body}", + ); + } + + return json.decode(response.body)["access_token"]; + } + + static final provider = AsyncNotifierProvider( + LoginController.new, + ); +} diff --git a/lib/controllers/mail_client_controller.dart b/lib/controllers/mail_client_controller.dart deleted file mode 100644 index 18c8a4f..0000000 --- a/lib/controllers/mail_client_controller.dart +++ /dev/null @@ -1,27 +0,0 @@ -import "dart:io"; -import "package:enough_mail/enough_mail.dart"; -import "package:nexusbot/controllers/settings_controller.dart"; -import "package:riverpod/riverpod.dart"; - -class MailClientController extends AsyncNotifier { - @override - Future build() async { - final settings = ref.watch(SettingsController.provider)!; - final account = MailAccount.fromManualSettings( - email: settings.email, - name: settings.mailName, - incomingHost: settings.mailDomain, - outgoingHost: settings.mailDomain, - password: (await File(settings.smtpPasswordFile).readAsString()).trim(), - ); - - final client = MailClient(account); - await client.connect(); - return client; - } - - static final provider = - AsyncNotifierProvider( - MailClientController.new, - ); -} diff --git a/lib/controllers/registration_controller.dart b/lib/controllers/registration_controller.dart deleted file mode 100644 index 6b3b2ff..0000000 --- a/lib/controllers/registration_controller.dart +++ /dev/null @@ -1,15 +0,0 @@ -import "package:fast_immutable_collections/fast_immutable_collections.dart"; -import "package:nexusbot/models/registration.dart"; -import "package:riverpod/riverpod.dart"; - -class RegistrationController extends Notifier> { - @override - IList build() => const IList.empty(); - - void add(Registration registration) => state = state.add(registration); - - static final provider = - NotifierProvider>( - RegistrationController.new, - ); -} diff --git a/lib/helpers/api_helper.dart b/lib/helpers/api_helper.dart new file mode 100644 index 0000000..b6a4f9e --- /dev/null +++ b/lib/helpers/api_helper.dart @@ -0,0 +1,105 @@ +import "dart:convert"; +import "dart:io"; +import "package:markdown/markdown.dart"; +import "package:nexusbot/controllers/login_controller.dart"; +import "package:nexusbot/controllers/settings_controller.dart"; +import "package:nexusbot/models/registration.dart"; +import "package:shelf/shelf.dart"; +import "package:http/http.dart" as http; +import "package:riverpod/riverpod.dart"; + +class ApiHelper { + final Ref ref; + ApiHelper(this.ref); + + String getTxn() => DateTime.now().millisecondsSinceEpoch.toString(); + Future> getHeaders() async => { + HttpHeaders.contentTypeHeader: "application/json", + HttpHeaders.authorizationHeader: + "Bearer ${await ref.watch(LoginController.provider.future)}", + }; + + Future getRoomId(String alias) async { + final settings = ref.watch(SettingsController.provider)!; + final response = await http.get( + settings.homeserver.replace( + path: "_matrix/client/v3/directory/room/$alias", + ), + headers: await getHeaders(), + ); + + if (response.statusCode != 200) { + throw Exception("Alias lookup failed for $alias: ${response.body}"); + } + + return json.decode(response.body)["room_id"]; + } + + Future sendMessage(message, {required String room}) async { + final settings = ref.read(SettingsController.provider)!; + final response = await http.put( + settings.homeserver.replace( + path: + "_matrix/client/v3/rooms/${await getRoomId(room)}/send/m.room.message/${getTxn()}", + ), + headers: await getHeaders(), + body: json.encode({ + "msgtype": "m.text", + "body": message, + "format": "org.matrix.custom.html", + "formatted_body": markdownToHtml(message), + }), + ); + + if (response.statusCode != 200) { + throw Exception("Message send failed for room $room: ${response.body}"); + } + + return json.decode(response.body)["event_id"]; + } + + Future react( + String reaction, { + required String eventId, + required String room, + }) async { + final settings = ref.read(SettingsController.provider)!; + final response = await http.put( + settings.homeserver.replace( + path: + "_matrix/client/v3/rooms/${await getRoomId(room)}/send/m.reaction/${getTxn()}", + ), + headers: await getHeaders(), + body: json.encode({ + "m.relates_to": { + "rel_type": "m.annotation", + "event_id": eventId, + "key": reaction, + }, + }), + ); + + if (response.statusCode != 200) { + throw Exception("Reaction failed for room $room: ${response.body}"); + } + + return json.decode(response.body)["event_id"]; + } + + Future register(Request request) async { + final settings = ref.read(SettingsController.provider)!; + final registration = Registration.fromJson( + json.decode(await request.readAsString()), + ); + + final event = await sendMessage("""# Registration request +- Username: `${registration.username}` +- Email: `${registration.email}`""", room: settings.adminRoom); + + await react("✅", eventId: event, room: settings.adminRoom); + + return Response.found(settings.successUri); + } + + static final provider = Provider(ApiHelper.new); +} diff --git a/lib/models/settings.dart b/lib/models/settings.dart index 35edbb4..481a410 100644 --- a/lib/models/settings.dart +++ b/lib/models/settings.dart @@ -10,13 +10,10 @@ abstract class Settings with _$Settings { required Uri homeserver, required Uri successUri, required String name, - required String adminName, required String adminRoom, - required String email, - required String mailName, - required String mailDomain, - required String smtpPasswordFile, required String botPasswordFile, + required String smtpPasswordFile, + required String? inviteTo, }) = _Settings; factory Settings.fromJson(Map json) => diff --git a/lib/models/settings.freezed.dart b/lib/models/settings.freezed.dart index d970287..d4d4767 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; Uri get homeserver; Uri get successUri; String get name; String get adminName; String get adminRoom; String get email; String get mailName; String get mailDomain; String get smtpPasswordFile; String get botPasswordFile; + String get socket; Uri get homeserver; Uri get successUri; String get name; String get adminRoom; String get botPasswordFile; String get smtpPasswordFile; String? get inviteTo; /// 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.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.successUri, successUri) || other.successUri == successUri)&&(identical(other.name, name) || other.name == name)&&(identical(other.adminName, adminName) || other.adminName == adminName)&&(identical(other.adminRoom, adminRoom) || other.adminRoom == adminRoom)&&(identical(other.email, email) || other.email == email)&&(identical(other.mailName, mailName) || other.mailName == mailName)&&(identical(other.mailDomain, mailDomain) || other.mailDomain == mailDomain)&&(identical(other.smtpPasswordFile, smtpPasswordFile) || other.smtpPasswordFile == smtpPasswordFile)&&(identical(other.botPasswordFile, botPasswordFile) || other.botPasswordFile == botPasswordFile)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is Settings&&(identical(other.socket, socket) || other.socket == socket)&&(identical(other.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.successUri, successUri) || other.successUri == successUri)&&(identical(other.name, name) || other.name == name)&&(identical(other.adminRoom, adminRoom) || other.adminRoom == adminRoom)&&(identical(other.botPasswordFile, botPasswordFile) || other.botPasswordFile == botPasswordFile)&&(identical(other.smtpPasswordFile, smtpPasswordFile) || other.smtpPasswordFile == smtpPasswordFile)&&(identical(other.inviteTo, inviteTo) || other.inviteTo == inviteTo)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminName,adminRoom,email,mailName,mailDomain,smtpPasswordFile,botPasswordFile); +int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminRoom,botPasswordFile,smtpPasswordFile,inviteTo); @override String toString() { - return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminName: $adminName, adminRoom: $adminRoom, email: $email, mailName: $mailName, mailDomain: $mailDomain, smtpPasswordFile: $smtpPasswordFile, botPasswordFile: $botPasswordFile)'; + return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminRoom: $adminRoom, botPasswordFile: $botPasswordFile, smtpPasswordFile: $smtpPasswordFile, inviteTo: $inviteTo)'; } @@ -49,7 +49,7 @@ abstract mixin class $SettingsCopyWith<$Res> { factory $SettingsCopyWith(Settings value, $Res Function(Settings) _then) = _$SettingsCopyWithImpl; @useResult $Res call({ - String socket, Uri homeserver, Uri successUri, String name, String adminName, String adminRoom, String email, String mailName, String mailDomain, String smtpPasswordFile, String botPasswordFile + String socket, Uri homeserver, Uri successUri, String name, String adminRoom, String botPasswordFile, String smtpPasswordFile, String? inviteTo }); @@ -66,20 +66,17 @@ 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 = null,Object? homeserver = null,Object? successUri = null,Object? name = null,Object? adminName = null,Object? adminRoom = null,Object? email = null,Object? mailName = null,Object? mailDomain = null,Object? smtpPasswordFile = null,Object? botPasswordFile = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? socket = null,Object? homeserver = null,Object? successUri = null,Object? name = null,Object? adminRoom = null,Object? botPasswordFile = null,Object? smtpPasswordFile = null,Object? inviteTo = freezed,}) { return _then(_self.copyWith( socket: null == socket ? _self.socket : socket // ignore: cast_nullable_to_non_nullable as String,homeserver: null == homeserver ? _self.homeserver : homeserver // ignore: cast_nullable_to_non_nullable as Uri,successUri: null == successUri ? _self.successUri : successUri // ignore: cast_nullable_to_non_nullable as Uri,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable -as String,adminName: null == adminName ? _self.adminName : adminName // ignore: cast_nullable_to_non_nullable as String,adminRoom: null == adminRoom ? _self.adminRoom : adminRoom // ignore: cast_nullable_to_non_nullable -as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable -as String,mailName: null == mailName ? _self.mailName : mailName // ignore: cast_nullable_to_non_nullable -as String,mailDomain: null == mailDomain ? _self.mailDomain : mailDomain // ignore: cast_nullable_to_non_nullable -as String,smtpPasswordFile: null == smtpPasswordFile ? _self.smtpPasswordFile : smtpPasswordFile // ignore: cast_nullable_to_non_nullable as String,botPasswordFile: null == botPasswordFile ? _self.botPasswordFile : botPasswordFile // ignore: cast_nullable_to_non_nullable -as String, +as String,smtpPasswordFile: null == smtpPasswordFile ? _self.smtpPasswordFile : smtpPasswordFile // ignore: cast_nullable_to_non_nullable +as String,inviteTo: freezed == inviteTo ? _self.inviteTo : inviteTo // ignore: cast_nullable_to_non_nullable +as String?, )); } @@ -90,20 +87,17 @@ as String, @JsonSerializable() class _Settings implements Settings { - const _Settings({required this.socket, required this.homeserver, required this.successUri, required this.name, required this.adminName, required this.adminRoom, required this.email, required this.mailName, required this.mailDomain, required this.smtpPasswordFile, required this.botPasswordFile}); + const _Settings({required this.socket, required this.homeserver, required this.successUri, required this.name, required this.adminRoom, required this.botPasswordFile, required this.smtpPasswordFile, required this.inviteTo}); factory _Settings.fromJson(Map json) => _$SettingsFromJson(json); @override final String socket; @override final Uri homeserver; @override final Uri successUri; @override final String name; -@override final String adminName; @override final String adminRoom; -@override final String email; -@override final String mailName; -@override final String mailDomain; -@override final String smtpPasswordFile; @override final String botPasswordFile; +@override final String smtpPasswordFile; +@override final String? inviteTo; /// Create a copy of Settings /// with the given fields replaced by the non-null parameter values. @@ -118,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.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.successUri, successUri) || other.successUri == successUri)&&(identical(other.name, name) || other.name == name)&&(identical(other.adminName, adminName) || other.adminName == adminName)&&(identical(other.adminRoom, adminRoom) || other.adminRoom == adminRoom)&&(identical(other.email, email) || other.email == email)&&(identical(other.mailName, mailName) || other.mailName == mailName)&&(identical(other.mailDomain, mailDomain) || other.mailDomain == mailDomain)&&(identical(other.smtpPasswordFile, smtpPasswordFile) || other.smtpPasswordFile == smtpPasswordFile)&&(identical(other.botPasswordFile, botPasswordFile) || other.botPasswordFile == botPasswordFile)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Settings&&(identical(other.socket, socket) || other.socket == socket)&&(identical(other.homeserver, homeserver) || other.homeserver == homeserver)&&(identical(other.successUri, successUri) || other.successUri == successUri)&&(identical(other.name, name) || other.name == name)&&(identical(other.adminRoom, adminRoom) || other.adminRoom == adminRoom)&&(identical(other.botPasswordFile, botPasswordFile) || other.botPasswordFile == botPasswordFile)&&(identical(other.smtpPasswordFile, smtpPasswordFile) || other.smtpPasswordFile == smtpPasswordFile)&&(identical(other.inviteTo, inviteTo) || other.inviteTo == inviteTo)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminName,adminRoom,email,mailName,mailDomain,smtpPasswordFile,botPasswordFile); +int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminRoom,botPasswordFile,smtpPasswordFile,inviteTo); @override String toString() { - return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminName: $adminName, adminRoom: $adminRoom, email: $email, mailName: $mailName, mailDomain: $mailDomain, smtpPasswordFile: $smtpPasswordFile, botPasswordFile: $botPasswordFile)'; + return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminRoom: $adminRoom, botPasswordFile: $botPasswordFile, smtpPasswordFile: $smtpPasswordFile, inviteTo: $inviteTo)'; } @@ -138,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, Uri homeserver, Uri successUri, String name, String adminName, String adminRoom, String email, String mailName, String mailDomain, String smtpPasswordFile, String botPasswordFile + String socket, Uri homeserver, Uri successUri, String name, String adminRoom, String botPasswordFile, String smtpPasswordFile, String? inviteTo }); @@ -155,20 +149,17 @@ 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 = null,Object? homeserver = null,Object? successUri = null,Object? name = null,Object? adminName = null,Object? adminRoom = null,Object? email = null,Object? mailName = null,Object? mailDomain = null,Object? smtpPasswordFile = null,Object? botPasswordFile = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? socket = null,Object? homeserver = null,Object? successUri = null,Object? name = null,Object? adminRoom = null,Object? botPasswordFile = null,Object? smtpPasswordFile = null,Object? inviteTo = freezed,}) { return _then(_Settings( socket: null == socket ? _self.socket : socket // ignore: cast_nullable_to_non_nullable as String,homeserver: null == homeserver ? _self.homeserver : homeserver // ignore: cast_nullable_to_non_nullable as Uri,successUri: null == successUri ? _self.successUri : successUri // ignore: cast_nullable_to_non_nullable as Uri,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable -as String,adminName: null == adminName ? _self.adminName : adminName // ignore: cast_nullable_to_non_nullable as String,adminRoom: null == adminRoom ? _self.adminRoom : adminRoom // ignore: cast_nullable_to_non_nullable -as String,email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable -as String,mailName: null == mailName ? _self.mailName : mailName // ignore: cast_nullable_to_non_nullable -as String,mailDomain: null == mailDomain ? _self.mailDomain : mailDomain // ignore: cast_nullable_to_non_nullable -as String,smtpPasswordFile: null == smtpPasswordFile ? _self.smtpPasswordFile : smtpPasswordFile // ignore: cast_nullable_to_non_nullable as String,botPasswordFile: null == botPasswordFile ? _self.botPasswordFile : botPasswordFile // ignore: cast_nullable_to_non_nullable -as String, +as String,smtpPasswordFile: null == smtpPasswordFile ? _self.smtpPasswordFile : smtpPasswordFile // ignore: cast_nullable_to_non_nullable +as String,inviteTo: freezed == inviteTo ? _self.inviteTo : inviteTo // ignore: cast_nullable_to_non_nullable +as String?, )); } diff --git a/lib/models/settings.g.dart b/lib/models/settings.g.dart index 1deff7c..60f17b5 100644 --- a/lib/models/settings.g.dart +++ b/lib/models/settings.g.dart @@ -11,13 +11,10 @@ _Settings _$SettingsFromJson(Map json) => _Settings( homeserver: Uri.parse(json['homeserver'] as String), successUri: Uri.parse(json['successUri'] as String), name: json['name'] as String, - adminName: json['adminName'] as String, adminRoom: json['adminRoom'] as String, - email: json['email'] as String, - mailName: json['mailName'] as String, - mailDomain: json['mailDomain'] as String, - smtpPasswordFile: json['smtpPasswordFile'] as String, botPasswordFile: json['botPasswordFile'] as String, + smtpPasswordFile: json['smtpPasswordFile'] as String, + inviteTo: json['inviteTo'] as String?, ); Map _$SettingsToJson(_Settings instance) => { @@ -25,11 +22,8 @@ Map _$SettingsToJson(_Settings instance) => { 'homeserver': instance.homeserver.toString(), 'successUri': instance.successUri.toString(), 'name': instance.name, - 'adminName': instance.adminName, 'adminRoom': instance.adminRoom, - 'email': instance.email, - 'mailName': instance.mailName, - 'mailDomain': instance.mailDomain, - 'smtpPasswordFile': instance.smtpPasswordFile, 'botPasswordFile': instance.botPasswordFile, + 'smtpPasswordFile': instance.smtpPasswordFile, + 'inviteTo': instance.inviteTo, }; diff --git a/pubspec.lock b/pubspec.lock index 9fb8d42..e45aaff 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -17,14 +17,6 @@ packages: url: "https://pub.dev" source: hosted version: "7.4.5" - archive: - dependency: transitive - description: - name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" - url: "https://pub.dev" - source: hosted - version: "4.0.7" args: dependency: "direct main" description: @@ -49,14 +41,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.13.0" - base58check: - dependency: transitive - description: - name: base58check - sha256: "6c300dfc33e598d2fe26319e13f6243fea81eaf8204cb4c6b69ef20a625319a5" - url: "https://pub.dev" - source: hosted - version: "2.0.0" basic_utils: dependency: transitive description: @@ -65,14 +49,6 @@ packages: url: "https://pub.dev" source: hosted version: "5.7.0" - blurhash_dart: - dependency: transitive - description: - name: blurhash_dart - sha256: "43955b6c2e30a7d440028d1af0fa185852f3534b795cc6eb81fbf397b464409f" - url: "https://pub.dev" - source: hosted - version: "1.2.1" boolean_selector: dependency: transitive description: @@ -89,14 +65,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.5.1" - build_cli_annotations: - dependency: transitive - description: - name: build_cli_annotations - sha256: b59d2769769efd6c9ff6d4c4cede0be115a566afc591705c2040b707534b1172 - url: "https://pub.dev" - source: hosted - version: "2.1.0" build_config: dependency: transitive description: @@ -153,14 +121,6 @@ packages: url: "https://pub.dev" source: hosted version: "8.10.1" - canonical_json: - dependency: transitive - description: - name: canonical_json - sha256: d6be1dd66b420c6ac9f42e3693e09edf4ff6edfee26cb4c28c1c019fdb8c0c15 - url: "https://pub.dev" - source: hosted - version: "1.1.2" checked_yaml: dependency: transitive description: @@ -177,14 +137,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.0" - cli_config: - dependency: transitive - description: - name: cli_config - sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec - url: "https://pub.dev" - source: hosted - version: "0.2.0" cli_tools: dependency: "direct main" description: @@ -225,14 +177,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" - coverage: - dependency: transitive - description: - name: coverage - sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" - url: "https://pub.dev" - source: hosted - version: "1.15.0" crypto: dependency: transitive description: @@ -241,14 +185,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.6" - csslib: - dependency: transitive - description: - name: csslib - sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.dev" - source: hosted - version: "1.0.2" dart_mappable: dependency: transitive description: @@ -273,14 +209,6 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.3" - enhanced_enum: - dependency: transitive - description: - name: enhanced_enum - sha256: "074c5a8b9664799ca91e1e8b68003b8694cb19998671cbafd9c7779c13fcdecf" - url: "https://pub.dev" - source: hosted - version: "0.2.4" enough_convert: dependency: transitive description: @@ -313,14 +241,6 @@ packages: url: "https://pub.dev" source: hosted version: "11.0.4" - ffi: - dependency: transitive - description: - name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://pub.dev" - source: hosted - version: "2.1.4" file: dependency: transitive description: @@ -337,14 +257,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" - flutter_rust_bridge: - dependency: transitive - description: - name: flutter_rust_bridge - sha256: b416ff56002789e636244fb4cc449f587656eff995e5a7169457eb0593fcaddb - url: "https://pub.dev" - source: hosted - version: "2.10.0" freezed: dependency: "direct dev" description: @@ -385,22 +297,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" - html: - dependency: transitive - description: - name: html - sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.dev" - source: hosted - version: "0.15.6" - html_unescape: - dependency: transitive - description: - name: html_unescape - sha256: "15362d7a18f19d7b742ef8dcb811f5fd2a2df98db9f80ea393c075189e0b61e3" - url: "https://pub.dev" - source: hosted - version: "2.0.0" http: dependency: "direct main" description: @@ -433,14 +329,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.1.2" - image: - dependency: transitive - description: - name: image - sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928" - url: "https://pub.dev" - source: hosted - version: "4.5.4" intl: dependency: transitive description: @@ -461,10 +349,10 @@ packages: dependency: transitive description: name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" url: "https://pub.dev" source: hosted - version: "0.6.7" + version: "0.7.2" json_annotation: dependency: "direct main" description: @@ -513,14 +401,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.12.17" - matrix: - dependency: "direct main" - description: - name: matrix - sha256: "0c033a6ebf4ed2f56ed604769984072961fefc0cb255a802ed441dcaec490196" - url: "https://pub.dev" - source: hosted - version: "1.1.0" meta: dependency: transitive description: @@ -585,14 +465,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" - posix: - dependency: transitive - description: - name: posix - sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61" - url: "https://pub.dev" - source: hosted - version: "6.0.3" pub_api_client: dependency: transitive description: @@ -617,14 +489,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" - random_string: - dependency: transitive - description: - name: random_string - sha256: "03b52435aae8cbdd1056cf91bfc5bf845e9706724dd35ae2e99fa14a1ef79d02" - url: "https://pub.dev" - source: hosted - version: "2.3.1" rfc_6901: dependency: transitive description: @@ -641,14 +505,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.6.1" - sdp_transform: - dependency: transitive - description: - name: sdp_transform - sha256: "73e412a5279a5c2de74001535208e20fff88f225c9a4571af0f7146202755e45" - url: "https://pub.dev" - source: hosted - version: "0.3.2" shelf: dependency: "direct main" description: @@ -673,14 +529,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" - slugify: - dependency: transitive - description: - name: slugify - sha256: b272501565cb28050cac2d96b7bf28a2d24c8dae359280361d124f3093d337c3 - url: "https://pub.dev" - source: hosted - version: "2.0.0" source_gen: dependency: transitive description: @@ -697,22 +545,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.5" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b - url: "https://pub.dev" - source: hosted - version: "2.1.2" - source_maps: - dependency: transitive - description: - name: source_maps - sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" - url: "https://pub.dev" - source: hosted - version: "0.10.13" source_span: dependency: transitive description: @@ -721,30 +553,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.1" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6" - url: "https://pub.dev" - source: hosted - version: "2.5.6" - sqflite_common_ffi: - dependency: "direct main" - description: - name: sqflite_common_ffi - sha256: "9faa2fedc5385ef238ce772589f7718c24cdddd27419b609bb9c6f703ea27988" - url: "https://pub.dev" - source: hosted - version: "2.3.6" - sqlite3: - dependency: transitive - description: - name: sqlite3 - sha256: dd806fff004a0aeb01e208b858dbc649bc72104670d425a81a6dd17698535f6e - url: "https://pub.dev" - source: hosted - version: "2.8.0" stack_trace: dependency: transitive description: @@ -817,14 +625,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.6" - test_core: - dependency: transitive - description: - name: test_core - sha256: "80bf5a02b60af04b09e14f6fe68b921aad119493e26e490deaca5993fef1b05a" - url: "https://pub.dev" - source: hosted - version: "0.6.11" timing: dependency: transitive description: @@ -849,30 +649,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" - unorm_dart: - dependency: transitive - description: - name: unorm_dart - sha256: "5b35bff83fce4d76467641438f9e867dc9bcfdb8c1694854f230579d68cd8f4b" - url: "https://pub.dev" - source: hosted - version: "0.2.0" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" - url: "https://pub.dev" - source: hosted - version: "15.0.2" - vodozemac: - dependency: transitive - description: - name: vodozemac - sha256: dba14017e042748fb22d270e8ab1d3e46965b89788dd3857dba938ec07571968 - url: "https://pub.dev" - source: hosted - version: "0.2.0" watcher: dependency: transitive description: @@ -905,14 +681,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" - webrtc_interface: - dependency: transitive - description: - name: webrtc_interface - sha256: "86fe3afc81a08481dfb25cf14a5a94e27062ecef25544783f352c914e0bbc1ca" - url: "https://pub.dev" - source: hosted - version: "1.2.2+hotfix.2" xml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d57ff46..f65a51f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -20,8 +20,6 @@ dependencies: args: ^2.7.0 enough_mail: ^2.1.6 markdown: ^7.3.0 - matrix: ^1.1.0 - sqflite_common_ffi: ^2.3.6 dev_dependencies: build_runner: ^2.4.6