All checks were successful
Build / build (18) (push) Successful in 42s
Build / build (22) (push) Successful in 1m12s
Build / build (20) (push) Successful in 1m13s
Build / build (18) (pull_request) Successful in 43s
Build / build (20) (pull_request) Successful in 1m12s
Build / build (22) (pull_request) Successful in 1m13s
By asking MongoDB to simply find the account by the ID and then validating the nonce ourselves, we save roughly 1ms.
103 lines
4.1 KiB
TypeScript
103 lines
4.1 KiB
TypeScript
import { Account } from "@/src/models/loginModel";
|
|
import { createInventory } from "@/src/services/inventoryService";
|
|
import { IDatabaseAccountJson, IDatabaseAccountRequiredFields } from "@/src/types/loginTypes";
|
|
import { createShip } from "./shipService";
|
|
import { Document, Types } from "mongoose";
|
|
import { Loadout } from "@/src/models/inventoryModels/loadoutModel";
|
|
import { PersonalRooms } from "@/src/models/personalRoomsModel";
|
|
import { Request } from "express";
|
|
import { config } from "@/src/services/configService";
|
|
import { createStats } from "@/src/services/statsService";
|
|
import crc32 from "crc-32";
|
|
|
|
export const isCorrectPassword = (requestPassword: string, databasePassword: string): boolean => {
|
|
return requestPassword === databasePassword;
|
|
};
|
|
|
|
export const isNameTaken = async (name: string): Promise<boolean> => {
|
|
return !!(await Account.findOne({ DisplayName: name }));
|
|
};
|
|
|
|
export const createAccount = async (accountData: IDatabaseAccountRequiredFields): Promise<IDatabaseAccountJson> => {
|
|
const account = new Account(accountData);
|
|
try {
|
|
await account.save();
|
|
const loadoutId = await createLoadout(account._id);
|
|
const shipId = await createShip(account._id);
|
|
await createInventory(account._id, { loadOutPresetId: loadoutId, ship: shipId });
|
|
await createPersonalRooms(account._id, shipId);
|
|
await createStats(account._id.toString());
|
|
return account.toJSON();
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
throw new Error(error.message);
|
|
}
|
|
throw new Error("error creating account that is not of instance Error");
|
|
}
|
|
};
|
|
|
|
export const createLoadout = async (accountId: Types.ObjectId): Promise<Types.ObjectId> => {
|
|
const loadout = new Loadout({ loadoutOwnerId: accountId });
|
|
const savedLoadout = await loadout.save();
|
|
return savedLoadout._id;
|
|
};
|
|
|
|
export const createPersonalRooms = async (accountId: Types.ObjectId, shipId: Types.ObjectId): Promise<void> => {
|
|
const personalRooms = new PersonalRooms({
|
|
personalRoomsOwnerId: accountId,
|
|
activeShipId: shipId
|
|
});
|
|
if (config.skipTutorial) {
|
|
// unlocked during Vor's Prize
|
|
const defaultFeatures = [
|
|
"/Lotus/Types/Items/ShipFeatureItems/MercuryNavigationFeatureItem",
|
|
"/Lotus/Types/Items/ShipFeatureItems/ArsenalFeatureItem",
|
|
"/Lotus/Types/Items/ShipFeatureItems/SocialMenuFeatureItem",
|
|
"/Lotus/Types/Items/ShipFeatureItems/FoundryFeatureItem",
|
|
"/Lotus/Types/Items/ShipFeatureItems/ModsFeatureItem"
|
|
];
|
|
personalRooms.Ship.Features.push(...defaultFeatures);
|
|
}
|
|
await personalRooms.save();
|
|
};
|
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
export type TAccountDocument = Document<unknown, {}, IDatabaseAccountJson> &
|
|
IDatabaseAccountJson & { _id: Types.ObjectId; __v: number };
|
|
|
|
export const getAccountForRequest = async (req: Request): Promise<TAccountDocument> => {
|
|
if (!req.query.accountId) {
|
|
throw new Error("Request is missing accountId parameter");
|
|
}
|
|
const nonce: number = parseInt(req.query.nonce as string);
|
|
if (!nonce) {
|
|
throw new Error("Request is missing nonce parameter");
|
|
}
|
|
|
|
const account = await Account.findById(req.query.accountId);
|
|
if (!account || account.Nonce != nonce) {
|
|
throw new Error("Invalid accountId-nonce pair");
|
|
}
|
|
if (account.Dropped && req.query.ct) {
|
|
account.Dropped = undefined;
|
|
await account.save();
|
|
}
|
|
return account;
|
|
};
|
|
|
|
export const getAccountIdForRequest = async (req: Request): Promise<string> => {
|
|
return (await getAccountForRequest(req))._id.toString();
|
|
};
|
|
|
|
export const isAdministrator = (account: TAccountDocument): boolean => {
|
|
return !!config.administratorNames?.find(x => x == account.DisplayName);
|
|
};
|
|
|
|
const platform_magics = [753, 639, 247, 37, 60];
|
|
export const getSuffixedName = (account: TAccountDocument): string => {
|
|
const name = account.DisplayName;
|
|
const platformId = 0;
|
|
const suffix = ((crc32.str(name.toLowerCase() + "595") >>> 0) + platform_magics[platformId]) % 1000;
|
|
return name + "#" + suffix.toString().padStart(3, "0");
|
|
};
|