BugVault/lib/server/packets.dart

165 lines
3.8 KiB
Dart

import 'dart:convert';
import 'package:bugvault/server/main.dart';
import 'package:bugvault/users/User.dart';
import 'package:libac_dart/nbt/Tag.dart';
import 'package:libac_dart/nbt/impl/CompoundTag.dart';
import 'package:libac_dart/nbt/impl/IntTag.dart';
import 'package:libac_dart/nbt/impl/StringTag.dart';
import 'package:libac_dart/packets/packets.dart';
class C2SPacketLogin implements IPacket {
String username = "";
@override
void decodeJson(String params) {
fromJson(json.decode(params));
}
@override
void decodeTag(Tag tag) {
CompoundTag ct = tag.asCompoundTag();
username = ct.get("user")?.asString() ?? "";
}
@override
NetworkDirection direction() {
return NetworkDirection.ClientToServer;
}
@override
String encodeJson() {
return json.encode(toJson());
}
@override
Tag encodeTag() {
CompoundTag ct = CompoundTag();
ct.put("user", StringTag.valueOf(username));
return ct;
}
@override
void fromJson(Map<String, dynamic> js) {
username = js['user'] as String;
}
@override
String getChannelID() {
return "BVPKTLOGIN";
}
@override
Future<void> handleClientPacket() async {
return;
}
@override
Future<PacketResponse> handleServerPacket() async {
S2CResponse response = S2CResponse();
S2CLoginReply loginReply = S2CLoginReply();
loginReply.username = username;
// Check if the user exists
DBUser? user = BugVaultServer.TryGetUser(username);
if (user == null && username != "") {
loginReply.g_ixLoginState |= LoginStates.NOT_FOUND;
loginReply.g_ixLoginState |= LoginStates.PROVIDE_EMAIL;
}
if (user != null) {
// Tell the user to send their TOTP Code
loginReply.g_ixLoginState |= LoginStates.FOUND;
loginReply.g_ixLoginState |= LoginStates.REQUIRE_MFA;
}
if (username == "") {
if (BugVaultServer.g_bAllowAnonymousLogin) {
loginReply.g_ixLoginState = LoginStates.LOGGED_IN;
} else {
loginReply.g_ixLoginState = LoginStates.ANONYMOUS_NOT_ALLOWED;
}
}
response.contents = loginReply.encodeTag().asCompoundTag();
return PacketResponse(replyDataTag: response.encodeTag().asCompoundTag());
}
@override
Map<String, dynamic> toJson() {
return {"user": username};
}
}
class LoginStates {
static const NOT_FOUND = 1;
static const FOUND = 2;
static const REQUIRE_MFA = 4;
static const PROVIDE_EMAIL = 8;
static const REQUIRE_EMAIL_CODE = 16;
static const LOGGED_IN = 32;
static const ANONYMOUS_NOT_ALLOWED = 64;
}
class S2CLoginReply implements IPacket {
String username = "";
int g_ixLoginState = 0;
@override
void decodeJson(String params) {
return fromJson(json.decode(params));
}
@override
void decodeTag(Tag tag) {
CompoundTag ct = tag.asCompoundTag();
username = ct.get("user")?.asString() ?? "";
g_ixLoginState = ct.get("state")?.asInt() ?? 0;
}
@override
NetworkDirection direction() {
return NetworkDirection.ServerToClient;
}
@override
String encodeJson() {
return json.encode(toJson());
}
@override
Tag encodeTag() {
CompoundTag ct = CompoundTag();
ct.put("user", StringTag.valueOf(username));
ct.put("state", IntTag.valueOf(g_ixLoginState));
return ct;
}
@override
void fromJson(Map<String, dynamic> js) {
username = js['user'] as String;
g_ixLoginState = js['state'] as int;
}
@override
String getChannelID() {
return "BVSPKTLOGINREPLY";
}
@override
Future<void> handleClientPacket() async {
// do handling stuff
}
@override
Future<PacketResponse> handleServerPacket() async {
throw UnimplementedError(); // Client side only, so this never gets invoked.
}
@override
Map<String, dynamic> toJson() {
return {"user": username, "state": g_ixLoginState};
}
}