Removed web project (galvanic authentication support in IL2CPP universal patch)

Moved instance ID to header
User instances for profile management
.. other stuff
This commit is contained in:
2025-03-22 21:57:45 -04:00
parent 73e9b72ad4
commit 6cdd0946f4
42 changed files with 663 additions and 3833 deletions

128
src/data/profiles.ts Normal file
View File

@@ -0,0 +1,128 @@
import { Redis } from "../db.ts";
import Dictionary from "./usernames.ts";
import { Config } from "../config.ts";
import { AuthType } from "./users.ts";
import * as JsonWebToken from "@gz/jwt";
const config = Config.getConfig();
interface ProfileInitOptions {
username: string
}
interface AccountExport {
accountId: number,
profileImage: string,
isJunior: boolean,
platforms: number,
username: string,
displayName: string
}
export type ProfileTokenFormat = {
iss: string;
sub: number;
nbf: number;
iat: number;
exp: number;
typ: AuthType;
}
class Profile {
static async getUniqueId() {
let id = Math.round(Math.random() * Math.pow(2, 31));
while ((await Redis.Database.exists(Redis.buildKey(Redis.KeyGroups.Profiles.Root, id.toString(), Redis.KeyGroups.Profiles.Username))) >= 1)
id = await this.getUniqueId();
return id;
}
static async byName(name: string) {
const id = await Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profile_Usernames, name));
if (id == null) return null;
else return new Profile(parseInt(id, 10));
}
static async getUniqueUsername() {
let username = `${Dictionary.Adjectives[Math.floor(Math.random() * Dictionary.Adjectives.length)]}${Dictionary.Nouns[Math.floor(Math.random() * Dictionary.Nouns.length)]}${Math.round(Math.random() * 10000)}`
while ((await Profile.byName(username)) !== null) username = await this.getUniqueUsername();
return username;
}
static async init(options?: ProfileInitOptions) {
const optionsSpecified = typeof options !== 'undefined';
const newId = await this.getUniqueId();
const newUsername = optionsSpecified ? options.username : await this.getUniqueUsername();
await Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Profile_Usernames, newUsername), newId);
await Redis.Database.set(Redis.buildKey(Redis.KeyGroups.Profiles.Root, newId.toString(), Redis.KeyGroups.Profiles.Username), newUsername);
return new Profile(newId);
}
// surely this can be written better
static getExportAccount(id: number): Promise<AccountExport | null> {
return new Promise((resolve, _reject) => {
Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, id.toString(), Redis.KeyGroups.Profiles.Username)).then(val => {
if (val == null) resolve(null);
else {
const promises = {
profileImage: Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, id.toString(), Redis.KeyGroups.Profiles.ProfileImage)),
isJunior: Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, id.toString(), Redis.KeyGroups.Profiles.Junior)),
platforms: Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, id.toString(), Redis.KeyGroups.Profiles.Platforms)),
displayName: Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, id.toString(), Redis.KeyGroups.Profiles.DisplayName)),
username: Redis.Database.get(Redis.buildKey(Redis.KeyGroups.Profiles.Root, id.toString(), Redis.KeyGroups.Profiles.Username)),
}
Promise.all(Object.values(promises)).then((values) => {
resolve({
accountId: id,
profileImage: values[0] == null ? "DefaultProfileImage" : values[0],
isJunior: values[1] == null ? false : JSON.parse(values[1]),
platforms: values[2] == null ? 1 : JSON.parse(values[2]),
displayName: values[3] == null ? (values[4] == null ? "DATABASEERROR" : values[4]) : values[3],
username: values[4] == null ? "DATABASEERROR" : values[4],
});
});
}
});
});
}
static async getExportAccountsBulk(ids: number[]) {
const accs = await Promise.all(ids.map(val => this.getExportAccount(val)));
return accs.filter(val => val !== null);
}
#id: number;
constructor(id: number) {
this.#id = id;
}
getId() {
return this.#id;
}
async export() {
return await Profile.getExportAccount(this.#id);
}
async getToken() {
const payload: ProfileTokenFormat = {
iss: config.web.publichost,
sub: this.#id,
nbf: Math.round(Date.now() / 1000) - 200,
iat: Math.round(Date.now() / 1000),
exp: Math.round(Date.now() / 1000) + (config.auth.timeout * 60 * 60),
typ: AuthType.Web
};
return await JsonWebToken.encode(payload, config.auth.secret, { algorithm: "HS512" });
}
}
export default Profile;