Working
This commit is contained in:
parent
64dd38f7aa
commit
b9adcb205e
14 changed files with 274 additions and 214 deletions
12
.vscode/launch.json
vendored
12
.vscode/launch.json
vendored
|
@ -15,8 +15,6 @@
|
||||||
"https://matrix.federated.nexus",
|
"https://matrix.federated.nexus",
|
||||||
"--name",
|
"--name",
|
||||||
"nexusbot",
|
"nexusbot",
|
||||||
"--inviteTo",
|
|
||||||
"#community:federated.nexus",
|
|
||||||
"--adminRoom",
|
"--adminRoom",
|
||||||
"#admins:federated.nexus",
|
"#admins:federated.nexus",
|
||||||
"--successUri",
|
"--successUri",
|
||||||
|
@ -24,7 +22,15 @@
|
||||||
"--botPasswordFile",
|
"--botPasswordFile",
|
||||||
"secrets/botPassword.txt",
|
"secrets/botPassword.txt",
|
||||||
"--smtpPasswordFile",
|
"--smtpPasswordFile",
|
||||||
"secrets/smtpPassword.txt"
|
"secrets/smtpPassword.txt",
|
||||||
|
"--adminName",
|
||||||
|
"grapevine",
|
||||||
|
"--email",
|
||||||
|
"henry@henryhiles.com",
|
||||||
|
"--mailDomain",
|
||||||
|
"mail.henryhiles.com",
|
||||||
|
"--mailName",
|
||||||
|
"Federated Nexus Registrations"
|
||||||
],
|
],
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "dart"
|
"type": "dart"
|
||||||
|
|
8
JUSTFILE
8
JUSTFILE
|
@ -1,8 +1,8 @@
|
||||||
|
test:
|
||||||
|
curl --unix-socket ./socket http:/./ -X POST -d '{"email": "foo@henryhiles.com", "username": "name"}'
|
||||||
|
|
||||||
watch:
|
watch:
|
||||||
dart run build_runner watch
|
dart run build_runner watch
|
||||||
|
|
||||||
build:
|
build:
|
||||||
dart run build_runner build
|
dart run build_runner build
|
||||||
|
|
||||||
test:
|
|
||||||
curl --unix-socket ./socket http:/root -X POST -d '{"email": "foo", "username": "bar"}'
|
|
|
@ -1,7 +1,14 @@
|
||||||
|
import "dart:convert";
|
||||||
import "dart:io";
|
import "dart:io";
|
||||||
import "package:cli_tools/config.dart";
|
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/controllers/settings_controller.dart";
|
||||||
import "package:nexusbot/helpers/api_helper.dart";
|
import "package:nexusbot/models/registration.dart";
|
||||||
import "package:riverpod/riverpod.dart";
|
import "package:riverpod/riverpod.dart";
|
||||||
import "package:shelf/shelf.dart";
|
import "package:shelf/shelf.dart";
|
||||||
import "package:shelf/shelf_io.dart";
|
import "package:shelf/shelf_io.dart";
|
||||||
|
@ -9,35 +16,145 @@ import "package:shelf_router/shelf_router.dart";
|
||||||
|
|
||||||
void main(List<String> argsRaw) async {
|
void main(List<String> argsRaw) async {
|
||||||
final parser = ConfigParser()
|
final parser = ConfigParser()
|
||||||
..addOption("socket", abbr: "s", mandatory: true)
|
..addOption("socket", mandatory: true)
|
||||||
..addOption("homeserver", abbr: "h", mandatory: true)
|
..addOption("homeserver", mandatory: true)
|
||||||
..addOption("successUri", abbr: "u", mandatory: true)
|
..addOption("successUri", mandatory: true)
|
||||||
..addOption("name", abbr: "n", mandatory: true)
|
..addOption("name", mandatory: true)
|
||||||
..addOption("adminRoom", abbr: "a", mandatory: true)
|
..addOption("adminName", mandatory: true)
|
||||||
..addOption("botPasswordFile", abbr: "b", mandatory: true)
|
..addOption("adminRoom", mandatory: true)
|
||||||
..addOption("smtpPasswordFile", abbr: "p", mandatory: true)
|
..addOption("email", mandatory: true)
|
||||||
..addOption("inviteTo", abbr: "i");
|
..addOption("mailName", mandatory: true)
|
||||||
|
..addOption("mailDomain", mandatory: true)
|
||||||
|
..addOption("smtpPasswordFile", mandatory: true)
|
||||||
|
..addOption("botPasswordFile", mandatory: true);
|
||||||
|
|
||||||
final container = ProviderContainer();
|
final container = ProviderContainer();
|
||||||
container
|
container
|
||||||
.read(SettingsController.provider.notifier)
|
.read(SettingsController.provider.notifier)
|
||||||
.set(parser.parse(argsRaw));
|
.set(parser.parse(argsRaw));
|
||||||
|
|
||||||
final apiHelper = container.read(ApiHelper.provider);
|
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<String, dynamic>)["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"@(?<username>[a-zA-Z0-9._-]+):[^\s]+.*?password:\s+(?<password>\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 handler = const Pipeline()
|
final handler = const Pipeline()
|
||||||
.addMiddleware(logRequests())
|
.addMiddleware(logRequests())
|
||||||
.addHandler((Router()..post("/", apiHelper.register)).call);
|
.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,
|
||||||
|
);
|
||||||
|
|
||||||
final settings = container.read(SettingsController.provider)!;
|
|
||||||
final server = HttpServer.listenOn(
|
final server = HttpServer.listenOn(
|
||||||
await ServerSocket.bind(
|
await ServerSocket.bind(
|
||||||
InternetAddress(settings.socket, type: InternetAddressType.unix),
|
InternetAddress(
|
||||||
|
container.read(SettingsController.provider)!.socket,
|
||||||
|
type: InternetAddressType.unix,
|
||||||
|
),
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
apiHelper.listen();
|
|
||||||
serveRequests(server, handler);
|
serveRequests(server, handler);
|
||||||
print("Bot listening at ${server.address.address}");
|
print("Bot listening at ${server.address.address}");
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
_module.args.pkgs = import inputs.nixpkgs {inherit system;};
|
_module.args.pkgs = import inputs.nixpkgs {inherit system;};
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
buildInputs = with pkgs; [just dart watchexec];
|
packages = with pkgs; [just dart watchexec];
|
||||||
|
LD_LIBRARY_PATH = "${pkgs.lib.makeLibraryPath (with pkgs; [sqlite])}:$LD_LIBRARY_PATH";
|
||||||
};
|
};
|
||||||
|
|
||||||
packages.default = pkgs.buildDartApplication {
|
packages.default = pkgs.buildDartApplication {
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
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<Client> {
|
||||||
|
@override
|
||||||
|
Future<Client> 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, Client>(
|
||||||
|
ClientController.new,
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,36 +0,0 @@
|
||||||
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<String> {
|
|
||||||
@override
|
|
||||||
Future<String> 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, String>(
|
|
||||||
LoginController.new,
|
|
||||||
);
|
|
||||||
}
|
|
27
lib/controllers/mail_client_controller.dart
Normal file
27
lib/controllers/mail_client_controller.dart
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
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<MailClient> {
|
||||||
|
@override
|
||||||
|
Future<MailClient> 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, MailClient>(
|
||||||
|
MailClientController.new,
|
||||||
|
);
|
||||||
|
}
|
15
lib/controllers/registration_controller.dart
Normal file
15
lib/controllers/registration_controller.dart
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||||
|
import "package:nexusbot/models/registration.dart";
|
||||||
|
import "package:riverpod/riverpod.dart";
|
||||||
|
|
||||||
|
class RegistrationController extends Notifier<IList<Registration>> {
|
||||||
|
@override
|
||||||
|
IList<Registration> build() => const IList.empty();
|
||||||
|
|
||||||
|
void add(Registration registration) => state = state.add(registration);
|
||||||
|
|
||||||
|
static final provider =
|
||||||
|
NotifierProvider<RegistrationController, IList<Registration>>(
|
||||||
|
RegistrationController.new,
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,130 +0,0 @@
|
||||||
import "dart:convert";
|
|
||||||
import "dart:io";
|
|
||||||
import "package:markdown/markdown.dart";
|
|
||||||
import "package:nexusbot/controllers/last_synced_controller.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";
|
|
||||||
import "package:matrix/matrix.dart";
|
|
||||||
|
|
||||||
class ApiHelper {
|
|
||||||
final Ref ref;
|
|
||||||
ApiHelper(this.ref);
|
|
||||||
|
|
||||||
String getTxn() => DateTime.now().millisecondsSinceEpoch.toString();
|
|
||||||
Future<Map<String, String>> getHeaders() async => {
|
|
||||||
HttpHeaders.contentTypeHeader: "application/json",
|
|
||||||
HttpHeaders.authorizationHeader:
|
|
||||||
"Bearer ${await ref.watch(LoginController.provider.future)}",
|
|
||||||
};
|
|
||||||
|
|
||||||
Future<String> 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<String> 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<String> 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<String> listen() async {
|
|
||||||
final settings = ref.watch(SettingsController.provider)!;
|
|
||||||
final response = await http.get(
|
|
||||||
settings.homeserver.replace(
|
|
||||||
path: "_matrix/client/v3/sync",
|
|
||||||
queryParameters: {
|
|
||||||
"timeout": "30000",
|
|
||||||
if (ref.watch(LastSyncedController.provider) != null case final since)
|
|
||||||
"since": since,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
headers: await getHeaders(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
|
||||||
throw Exception("Sync failed: ${response.body}");
|
|
||||||
}
|
|
||||||
|
|
||||||
final data = json.decode(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<Response> register(Request request) async {
|
|
||||||
final settings = ref.read(SettingsController.provider)!;
|
|
||||||
final registration = Registration.fromJson(
|
|
||||||
json.decode(await request.readAsString()),
|
|
||||||
);
|
|
||||||
|
|
||||||
Login
|
|
||||||
|
|
||||||
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>(ApiHelper.new);
|
|
||||||
}
|
|
|
@ -10,10 +10,13 @@ abstract class Settings with _$Settings {
|
||||||
required Uri homeserver,
|
required Uri homeserver,
|
||||||
required Uri successUri,
|
required Uri successUri,
|
||||||
required String name,
|
required String name,
|
||||||
|
required String adminName,
|
||||||
required String adminRoom,
|
required String adminRoom,
|
||||||
required String botPasswordFile,
|
required String email,
|
||||||
|
required String mailName,
|
||||||
|
required String mailDomain,
|
||||||
required String smtpPasswordFile,
|
required String smtpPasswordFile,
|
||||||
required String? inviteTo,
|
required String botPasswordFile,
|
||||||
}) = _Settings;
|
}) = _Settings;
|
||||||
|
|
||||||
factory Settings.fromJson(Map<String, dynamic> json) =>
|
factory Settings.fromJson(Map<String, dynamic> json) =>
|
||||||
|
|
|
@ -16,7 +16,7 @@ T _$identity<T>(T value) => value;
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$Settings {
|
mixin _$Settings {
|
||||||
|
|
||||||
String get socket; Uri get homeserver; Uri get successUri; String get name; String get adminRoom; String get botPasswordFile; String get smtpPasswordFile; String? get inviteTo;
|
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;
|
||||||
/// Create a copy of Settings
|
/// Create a copy of Settings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@ -29,16 +29,16 @@ $SettingsCopyWith<Settings> get copyWith => _$SettingsCopyWithImpl<Settings>(thi
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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.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));
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminRoom,botPasswordFile,smtpPasswordFile,inviteTo);
|
int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminName,adminRoom,email,mailName,mailDomain,smtpPasswordFile,botPasswordFile);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminRoom: $adminRoom, botPasswordFile: $botPasswordFile, smtpPasswordFile: $smtpPasswordFile, inviteTo: $inviteTo)';
|
return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminName: $adminName, adminRoom: $adminRoom, email: $email, mailName: $mailName, mailDomain: $mailDomain, smtpPasswordFile: $smtpPasswordFile, botPasswordFile: $botPasswordFile)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ abstract mixin class $SettingsCopyWith<$Res> {
|
||||||
factory $SettingsCopyWith(Settings value, $Res Function(Settings) _then) = _$SettingsCopyWithImpl;
|
factory $SettingsCopyWith(Settings value, $Res Function(Settings) _then) = _$SettingsCopyWithImpl;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String socket, Uri homeserver, Uri successUri, String name, String adminRoom, String botPasswordFile, String smtpPasswordFile, String? inviteTo
|
String socket, Uri homeserver, Uri successUri, String name, String adminName, String adminRoom, String email, String mailName, String mailDomain, String smtpPasswordFile, String botPasswordFile
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,17 +66,20 @@ class _$SettingsCopyWithImpl<$Res>
|
||||||
|
|
||||||
/// Create a copy of Settings
|
/// Create a copy of Settings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// 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? adminRoom = null,Object? botPasswordFile = null,Object? smtpPasswordFile = null,Object? inviteTo = freezed,}) {
|
@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,}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
socket: null == socket ? _self.socket : socket // ignore: cast_nullable_to_non_nullable
|
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 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,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 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,adminRoom: null == adminRoom ? _self.adminRoom : adminRoom // ignore: cast_nullable_to_non_nullable
|
||||||
as String,botPasswordFile: null == botPasswordFile ? _self.botPasswordFile : botPasswordFile // 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,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,botPasswordFile: null == botPasswordFile ? _self.botPasswordFile : botPasswordFile // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,17 +90,20 @@ as String?,
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
|
||||||
class _Settings implements Settings {
|
class _Settings implements Settings {
|
||||||
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});
|
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});
|
||||||
factory _Settings.fromJson(Map<String, dynamic> json) => _$SettingsFromJson(json);
|
factory _Settings.fromJson(Map<String, dynamic> json) => _$SettingsFromJson(json);
|
||||||
|
|
||||||
@override final String socket;
|
@override final String socket;
|
||||||
@override final Uri homeserver;
|
@override final Uri homeserver;
|
||||||
@override final Uri successUri;
|
@override final Uri successUri;
|
||||||
@override final String name;
|
@override final String name;
|
||||||
|
@override final String adminName;
|
||||||
@override final String adminRoom;
|
@override final String adminRoom;
|
||||||
@override final String botPasswordFile;
|
@override final String email;
|
||||||
|
@override final String mailName;
|
||||||
|
@override final String mailDomain;
|
||||||
@override final String smtpPasswordFile;
|
@override final String smtpPasswordFile;
|
||||||
@override final String? inviteTo;
|
@override final String botPasswordFile;
|
||||||
|
|
||||||
/// Create a copy of Settings
|
/// Create a copy of Settings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@ -112,16 +118,16 @@ Map<String, dynamic> toJson() {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
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.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));
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminRoom,botPasswordFile,smtpPasswordFile,inviteTo);
|
int get hashCode => Object.hash(runtimeType,socket,homeserver,successUri,name,adminName,adminRoom,email,mailName,mailDomain,smtpPasswordFile,botPasswordFile);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminRoom: $adminRoom, botPasswordFile: $botPasswordFile, smtpPasswordFile: $smtpPasswordFile, inviteTo: $inviteTo)';
|
return 'Settings(socket: $socket, homeserver: $homeserver, successUri: $successUri, name: $name, adminName: $adminName, adminRoom: $adminRoom, email: $email, mailName: $mailName, mailDomain: $mailDomain, smtpPasswordFile: $smtpPasswordFile, botPasswordFile: $botPasswordFile)';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,7 +138,7 @@ abstract mixin class _$SettingsCopyWith<$Res> implements $SettingsCopyWith<$Res>
|
||||||
factory _$SettingsCopyWith(_Settings value, $Res Function(_Settings) _then) = __$SettingsCopyWithImpl;
|
factory _$SettingsCopyWith(_Settings value, $Res Function(_Settings) _then) = __$SettingsCopyWithImpl;
|
||||||
@override @useResult
|
@override @useResult
|
||||||
$Res call({
|
$Res call({
|
||||||
String socket, Uri homeserver, Uri successUri, String name, String adminRoom, String botPasswordFile, String smtpPasswordFile, String? inviteTo
|
String socket, Uri homeserver, Uri successUri, String name, String adminName, String adminRoom, String email, String mailName, String mailDomain, String smtpPasswordFile, String botPasswordFile
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,17 +155,20 @@ class __$SettingsCopyWithImpl<$Res>
|
||||||
|
|
||||||
/// Create a copy of Settings
|
/// Create a copy of Settings
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// 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? adminRoom = null,Object? botPasswordFile = null,Object? smtpPasswordFile = null,Object? inviteTo = freezed,}) {
|
@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,}) {
|
||||||
return _then(_Settings(
|
return _then(_Settings(
|
||||||
socket: null == socket ? _self.socket : socket // ignore: cast_nullable_to_non_nullable
|
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 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,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 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,adminRoom: null == adminRoom ? _self.adminRoom : adminRoom // ignore: cast_nullable_to_non_nullable
|
||||||
as String,botPasswordFile: null == botPasswordFile ? _self.botPasswordFile : botPasswordFile // 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,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,botPasswordFile: null == botPasswordFile ? _self.botPasswordFile : botPasswordFile // ignore: cast_nullable_to_non_nullable
|
||||||
as String?,
|
as String,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,10 +11,13 @@ _Settings _$SettingsFromJson(Map<String, dynamic> json) => _Settings(
|
||||||
homeserver: Uri.parse(json['homeserver'] as String),
|
homeserver: Uri.parse(json['homeserver'] as String),
|
||||||
successUri: Uri.parse(json['successUri'] as String),
|
successUri: Uri.parse(json['successUri'] as String),
|
||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
|
adminName: json['adminName'] as String,
|
||||||
adminRoom: json['adminRoom'] as String,
|
adminRoom: json['adminRoom'] as String,
|
||||||
botPasswordFile: json['botPasswordFile'] as String,
|
email: json['email'] as String,
|
||||||
|
mailName: json['mailName'] as String,
|
||||||
|
mailDomain: json['mailDomain'] as String,
|
||||||
smtpPasswordFile: json['smtpPasswordFile'] as String,
|
smtpPasswordFile: json['smtpPasswordFile'] as String,
|
||||||
inviteTo: json['inviteTo'] as String?,
|
botPasswordFile: json['botPasswordFile'] as String,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$SettingsToJson(_Settings instance) => <String, dynamic>{
|
Map<String, dynamic> _$SettingsToJson(_Settings instance) => <String, dynamic>{
|
||||||
|
@ -22,8 +25,11 @@ Map<String, dynamic> _$SettingsToJson(_Settings instance) => <String, dynamic>{
|
||||||
'homeserver': instance.homeserver.toString(),
|
'homeserver': instance.homeserver.toString(),
|
||||||
'successUri': instance.successUri.toString(),
|
'successUri': instance.successUri.toString(),
|
||||||
'name': instance.name,
|
'name': instance.name,
|
||||||
|
'adminName': instance.adminName,
|
||||||
'adminRoom': instance.adminRoom,
|
'adminRoom': instance.adminRoom,
|
||||||
'botPasswordFile': instance.botPasswordFile,
|
'email': instance.email,
|
||||||
|
'mailName': instance.mailName,
|
||||||
|
'mailDomain': instance.mailDomain,
|
||||||
'smtpPasswordFile': instance.smtpPasswordFile,
|
'smtpPasswordFile': instance.smtpPasswordFile,
|
||||||
'inviteTo': instance.inviteTo,
|
'botPasswordFile': instance.botPasswordFile,
|
||||||
};
|
};
|
||||||
|
|
|
@ -729,6 +729,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.6"
|
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:
|
sqlite3:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -21,6 +21,7 @@ dependencies:
|
||||||
enough_mail: ^2.1.6
|
enough_mail: ^2.1.6
|
||||||
markdown: ^7.3.0
|
markdown: ^7.3.0
|
||||||
matrix: ^1.1.0
|
matrix: ^1.1.0
|
||||||
|
sqflite_common_ffi: ^2.3.6
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.4.6
|
build_runner: ^2.4.6
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue