Push new session handling

This commit is contained in:
zontreck 2024-05-16 15:05:54 -07:00
parent 75de51ec14
commit b99f4c3140
8 changed files with 182 additions and 7 deletions

View file

@ -1,5 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:libac_flutter/utils/Hashing.dart';
import 'package:libac_flutter/utils/uuid/UUID.dart';
import 'package:zontreck/Constants.dart'; import 'package:zontreck/Constants.dart';
import 'package:zontreck/pages/OpenSim.dart'; import 'package:zontreck/pages/OpenSim.dart';
@ -300,3 +302,55 @@ class S2CLoginResponsePacket implements IPacket {
user: User.parseJson(map['user'])); user: User.parseJson(map['user']));
} }
} }
class C2SSessionCheckPacket extends IPacket {
UUID sessionToken;
C2SSessionCheckPacket({required this.sessionToken});
@override
HTTPMethod method() {
return HTTPMethod.Post;
}
@override
String getType() {
return "C2SSessionCheck";
}
@override
String encode() {
return json.encode({
"token": Hashing.md5Hash(sessionToken.toString()),
"client": Constants.CLIENTPSK
});
}
}
class S2CSessionCheckPacket extends IPacket {
String id;
final bool valid;
S2CSessionCheckPacket({required this.id, required this.valid});
@override
HTTPMethod method() {
return HTTPMethod.Get;
}
@override
String getType() {
return "S2CSessionCheck";
}
@override
String encode() {
return json.encode({"id": id, "type": getType()});
}
static S2CSessionCheckPacket decode(String params) {
var map = json.decode(params);
var id = map['id'] as String;
return S2CSessionCheckPacket(
id: id,
valid: id == Hashing.md5Hash(Settings().currentUser!.ID.toString()));
}
}

View file

@ -1,7 +1,9 @@
import 'dart:convert'; import 'dart:convert';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:libac_flutter/nbt/NbtUtils.dart';
import 'package:libac_flutter/nbt/impl/CompoundTag.dart'; import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
import 'package:libac_flutter/nbt/impl/StringTag.dart';
import 'package:libac_flutter/utils/Hashing.dart'; import 'package:libac_flutter/utils/Hashing.dart';
import 'package:zontreck/Packets.dart'; import 'package:zontreck/Packets.dart';
import 'package:zontreck/pages/OpenSim.dart'; import 'package:zontreck/pages/OpenSim.dart';
@ -12,7 +14,8 @@ enum APIEndpoint {
Setup(script: "Setup.php", path: "/ac/home/supports/"), Setup(script: "Setup.php", path: "/ac/home/supports/"),
Register(script: "Register.php", path: "/ac/home/supports/"), Register(script: "Register.php", path: "/ac/home/supports/"),
Logout(script: "Logout.php", path: "/ac/home/supports/"), Logout(script: "Logout.php", path: "/ac/home/supports/"),
Login(script: "Login.php", path: "/ac/home/supports/"); Login(script: "Login.php", path: "/ac/home/supports/"),
ValidateSession(script: "ValidateToken.php", path: "/ac/home/supports/");
final String script; final String script;
final String path; final String path;
@ -54,6 +57,12 @@ class Settings {
static CompoundTag save() { static CompoundTag save() {
CompoundTag tag = CompoundTag(); CompoundTag tag = CompoundTag();
Settings settings = Settings();
NbtUtils.writeBoolean(tag, "loggedIn", settings.loggedIn);
tag.put("name", StringTag.valueOf(settings.userName));
tag.put("display", StringTag.valueOf(settings.displayName));
if (settings.currentUser != null)
tag.put("user", settings.currentUser!.save());
return tag; return tag;
} }
@ -146,6 +155,11 @@ class Settings {
S2CLoginResponsePacket.decode(reply); S2CLoginResponsePacket.decode(reply);
return response; return response;
} }
case "S2CSessionCheck":
{
S2CSessionCheckPacket response = S2CSessionCheckPacket.decode(reply);
return response;
}
default: default:
{ {
return NullPacket(); return NullPacket();

View file

@ -1,5 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:libac_flutter/nbt/NbtIo.dart';
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
import 'package:libac_flutter/utils/Hashing.dart'; import 'package:libac_flutter/utils/Hashing.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:zontreck/Constants.dart'; import 'package:zontreck/Constants.dart';
import 'package:zontreck/Packets.dart'; import 'package:zontreck/Packets.dart';
import 'package:zontreck/Settings.dart'; import 'package:zontreck/Settings.dart';
@ -69,6 +72,14 @@ class LoginAccountState extends State<LoginAccountPage> {
settings.loggedIn = true; settings.loggedIn = true;
settings.currentUser = response.user; settings.currentUser = response.user;
CompoundTag setting = Settings.save();
// Save to cookie
var value = await NbtIo.writeBase64String(setting);
SharedPreferences prefs =
await SharedPreferences.getInstance();
prefs.setString("settings", value);
Navigator.pop(context); Navigator.pop(context);
} else { } else {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( ScaffoldMessenger.of(context).showSnackBar(SnackBar(

View file

@ -3,7 +3,13 @@ import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:footer/footer.dart'; import 'package:footer/footer.dart';
import 'package:footer/footer_view.dart'; import 'package:footer/footer_view.dart';
import 'package:libac_flutter/nbt/NbtIo.dart';
import 'package:libac_flutter/nbt/NbtUtils.dart';
import 'package:libac_flutter/nbt/impl/CompoundTag.dart';
import 'package:libac_flutter/nbt/impl/IntTag.dart';
import 'package:libac_flutter/nbt/impl/StringTag.dart';
import 'package:libac_flutter/utils/uuid/UUID.dart'; import 'package:libac_flutter/utils/uuid/UUID.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:zontreck/Constants.dart'; import 'package:zontreck/Constants.dart';
import 'package:zontreck/Packets.dart'; import 'package:zontreck/Packets.dart';
import 'package:zontreck/Settings.dart'; import 'package:zontreck/Settings.dart';
@ -15,6 +21,7 @@ class User {
int createdAt; int createdAt;
String userTitle; String userTitle;
bool active; bool active;
UUID loginToken;
User( User(
{required this.ID, {required this.ID,
@ -22,7 +29,8 @@ class User {
required this.LastName, required this.LastName,
required this.createdAt, required this.createdAt,
required this.userTitle, required this.userTitle,
required this.active}); required this.active,
required this.loginToken});
static User parseJson(Map<String, dynamic> map) { static User parseJson(Map<String, dynamic> map) {
return User( return User(
@ -31,7 +39,8 @@ class User {
LastName: map['last'] as String, LastName: map['last'] as String,
createdAt: map['rez'] as int, createdAt: map['rez'] as int,
userTitle: map['title'] as String, userTitle: map['title'] as String,
active: map['active'] as bool); active: map['active'] as bool,
loginToken: UUID.parse(map['token'] as String));
} }
String encode() { String encode() {
@ -41,9 +50,34 @@ class User {
"last": LastName, "last": LastName,
"rez": createdAt, "rez": createdAt,
"title": userTitle, "title": userTitle,
"active": active "active": active,
"token": loginToken
}); });
} }
CompoundTag save() {
CompoundTag tag = CompoundTag();
NbtUtils.writeUUID(tag, "id", ID);
tag.put("first", StringTag.valueOf(FirstName));
tag.put("last", StringTag.valueOf(LastName));
tag.put("rez", IntTag.valueOf(createdAt));
tag.put("title", StringTag.valueOf(userTitle));
NbtUtils.writeBoolean(tag, "active", active);
NbtUtils.writeUUID(tag, "token", loginToken);
return tag;
}
static User load(CompoundTag tag) {
return User(
ID: NbtUtils.readUUID(tag, "id"),
FirstName: tag.get("first")!.asString(),
LastName: tag.get("last")!.asString(),
createdAt: tag.get("rez")!.asInt(),
userTitle: tag.get("title")!.asString(),
active: NbtUtils.readBoolean(tag, "active"),
loginToken: NbtUtils.readUUID(tag, "token"));
}
} }
class OpenSimPage extends StatefulWidget { class OpenSimPage extends StatefulWidget {
@ -77,6 +111,29 @@ class OpenSimPageState extends State<OpenSimPage> {
settings.OpenSimSetupCompleted = false; settings.OpenSimSetupCompleted = false;
} }
if (!settings.loggedIn) {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (prefs.containsKey("settings")) {
String encoded = prefs.getString("settings")!;
CompoundTag tag = NbtIo.readBase64String(encoded) as CompoundTag;
if (tag.contains("user"))
settings.currentUser = User.load(tag.get("user") as CompoundTag);
// Validate current session
var reply = await settings.sendPacketToEndpoint(
APIEndpoint.ValidateSession,
C2SSessionCheckPacket(
sessionToken: settings.currentUser!.loginToken))
as S2CSessionCheckPacket;
if (reply.valid) {
// We're good to continue loading this user
} else {
settings.currentUser = null;
prefs.clear();
}
}
}
var pong = await settings.sendPacketToEndpoint( var pong = await settings.sendPacketToEndpoint(
APIEndpoint.Ping, NullPacket()) as S2CPongPacket; APIEndpoint.Ping, NullPacket()) as S2CPongPacket;
@ -147,6 +204,11 @@ class OpenSimPageState extends State<OpenSimPage> {
APIEndpoint.Logout, APIEndpoint.Logout,
NullPacket()); NullPacket());
SharedPreferences prefs =
await SharedPreferences
.getInstance();
prefs.clear();
didChangeDependencies(); didChangeDependencies();
}, },
child: Text("LOGOUT")) child: Text("LOGOUT"))

View file

@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
set(BINARY_NAME "zontreck") set(BINARY_NAME "zontreck")
# The unique GTK application identifier for this application. See: # The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID # https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "com.example.zontreck") set(APPLICATION_ID "com.zontreck.zontreck")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake. # versions of CMake.

View file

@ -20,6 +20,7 @@ $title = "";
$login = false; $login = false;
$reason = "Unauthorized"; $reason = "Unauthorized";
$active = false; $active = false;
$token = "";
$clientKey = $js['clientKey']; $clientKey = $js['clientKey'];
if($clientKey == CLIENTPSK) { if($clientKey == CLIENTPSK) {
@ -43,6 +44,9 @@ if($clientKey == CLIENTPSK) {
$reason = "success"; $reason = "success";
$login=true; $login=true;
$token = gen_uuid();
$DB->query("UPDATE `auth` SET `webLoginKey`='$token' WHERE `UUID` = '$id';");
} else { } else {
$reason = "Invalid Password"; $reason = "Invalid Password";
} }
@ -64,7 +68,8 @@ die(json_encode(
"last" => $last, "last" => $last,
"title" => $title, "title" => $title,
"rez" => $rez, "rez" => $rez,
"active" => $active "active" => $active,
"token" => $token
) )
) )
)); ));

29
php/ValidateToken.php Normal file
View file

@ -0,0 +1,29 @@
<?php
if(!defined("COMMON"))
require("Common.php");
$js = getJsonizedInput();
$token = $js["token"];
$client = $js["client"];
$DB = get_DB();
$id = "";
$res = $DB->query("SELECT * FROM `auth`;");
if($res->num_rows != 0){
while($row = $res->fetch_assoc()){
if(md5($row['webLoginKey']) == $token) {
$id = $row["UUID"];
}
}
}
die(json_encode(
array(
"id" => md5($id),
"type" => "S2CSessionCheck"
)
));
?>

View file

@ -37,7 +37,7 @@ dependencies:
cupertino_icons: ^1.0.6 cupertino_icons: ^1.0.6
libac_flutter: libac_flutter:
hosted: https://git.zontreck.com/api/packages/AriasCreations/pub/ hosted: https://git.zontreck.com/api/packages/AriasCreations/pub/
version: 1.0.3 version: 1.0.4
dio: ^5.4.3+1 dio: ^5.4.3+1
shared_preferences: ^2.2.3 shared_preferences: ^2.2.3
footer: ^0.0.4 footer: ^0.0.4