diff --git a/src/controllers/api/abortDojoComponentController.ts b/src/controllers/api/abortDojoComponentController.ts index fbeb3670..f17179cd 100644 --- a/src/controllers/api/abortDojoComponentController.ts +++ b/src/controllers/api/abortDojoComponentController.ts @@ -1,14 +1,34 @@ -import { getDojoClient, getGuildForRequestEx, removeDojoDeco, removeDojoRoom } from "@/src/services/guildService"; +import { + getDojoClient, + getGuildForRequestEx, + hasAccessToDojo, + hasGuildPermission, + removeDojoDeco, + removeDojoRoom +} from "@/src/services/guildService"; import { getInventory } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const abortDojoComponentController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); - const inventory = await getInventory(accountId); + const inventory = await getInventory(accountId, "LevelKeys"); const guild = await getGuildForRequestEx(req, inventory); const request = JSON.parse(String(req.body)) as IAbortDojoComponentRequest; + if ( + !hasAccessToDojo(inventory) || + !(await hasGuildPermission( + guild, + accountId, + request.DecoId ? GuildPermission.Decorator : GuildPermission.Architect + )) + ) { + res.json({ DojoRequestStatus: -1 }); + return; + } + if (request.DecoId) { removeDojoDeco(guild, request.ComponentId, request.DecoId); } else { diff --git a/src/controllers/api/abortDojoComponentDestructionController.ts b/src/controllers/api/abortDojoComponentDestructionController.ts index 1df71495..0d4c89ff 100644 --- a/src/controllers/api/abortDojoComponentDestructionController.ts +++ b/src/controllers/api/abortDojoComponentDestructionController.ts @@ -1,8 +1,17 @@ -import { getDojoClient, getGuildForRequest } from "@/src/services/guildService"; +import { getDojoClient, getGuildForRequest, hasAccessToDojo, hasGuildPermission } from "@/src/services/guildService"; +import { getInventory } from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const abortDojoComponentDestructionController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "LevelKeys"); const guild = await getGuildForRequest(req); + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Architect))) { + res.json({ DojoRequestStatus: -1 }); + return; + } const componentId = req.query.componentId as string; guild.DojoComponents.id(componentId)!.DestructionTime = undefined; diff --git a/src/controllers/api/addToGuildController.ts b/src/controllers/api/addToGuildController.ts index a7a3f250..0d24cd00 100644 --- a/src/controllers/api/addToGuildController.ts +++ b/src/controllers/api/addToGuildController.ts @@ -1,11 +1,11 @@ import { Guild, GuildMember } from "@/src/models/guildModel"; import { Account } from "@/src/models/loginModel"; -import { fillInInventoryDataForGuildMember } from "@/src/services/guildService"; +import { fillInInventoryDataForGuildMember, hasGuildPermission } from "@/src/services/guildService"; import { createMessage } from "@/src/services/inboxService"; import { getInventory } from "@/src/services/inventoryService"; import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService"; import { IOid } from "@/src/types/commonTypes"; -import { IGuildMemberClient } from "@/src/types/guildTypes"; +import { GuildPermission, IGuildMemberClient } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; import { ExportFlavour } from "warframe-public-export-plus"; @@ -19,7 +19,10 @@ export const addToGuildController: RequestHandler = async (req, res) => { } const guild = (await Guild.findOne({ _id: payload.GuildId.$oid }, "Name"))!; - // TODO: Check sender is allowed to send invites for this guild. + const senderAccount = await getAccountForRequest(req); + if (!(await hasGuildPermission(guild, senderAccount._id.toString(), GuildPermission.Recruiter))) { + res.status(400).json("Invalid permission"); + } if ( await GuildMember.exists({ @@ -37,7 +40,6 @@ export const addToGuildController: RequestHandler = async (req, res) => { status: 2 // outgoing invite }); - const senderAccount = await getAccountForRequest(req); const senderInventory = await getInventory(senderAccount._id.toString(), "ActiveAvatarImageType"); await createMessage(account._id.toString(), [ { diff --git a/src/controllers/api/changeDojoRootController.ts b/src/controllers/api/changeDojoRootController.ts index d596aae3..2f0722c7 100644 --- a/src/controllers/api/changeDojoRootController.ts +++ b/src/controllers/api/changeDojoRootController.ts @@ -1,12 +1,19 @@ import { RequestHandler } from "express"; -import { getDojoClient, getGuildForRequest } from "@/src/services/guildService"; +import { getDojoClient, getGuildForRequest, hasAccessToDojo, hasGuildPermission } from "@/src/services/guildService"; import { logger } from "@/src/utils/logger"; -import { IDojoComponentDatabase } from "@/src/types/guildTypes"; +import { GuildPermission, IDojoComponentDatabase } from "@/src/types/guildTypes"; import { Types } from "mongoose"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getInventory } from "@/src/services/inventoryService"; export const changeDojoRootController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "LevelKeys"); const guild = await getGuildForRequest(req); - // At this point, we know that a member of the guild is making this request. Assuming they are allowed to change the root. + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Architect))) { + res.json({ DojoRequestStatus: -1 }); + return; + } const idToNode: Record = {}; guild.DojoComponents.forEach(x => { diff --git a/src/controllers/api/changeGuildRankController.ts b/src/controllers/api/changeGuildRankController.ts index 3293d251..28a8113e 100644 --- a/src/controllers/api/changeGuildRankController.ts +++ b/src/controllers/api/changeGuildRankController.ts @@ -1,28 +1,38 @@ import { GuildMember } from "@/src/models/guildModel"; +import { getGuildForRequest, hasGuildPermissionEx } from "@/src/services/guildService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const changeGuildRankController: RequestHandler = async (req, res) => { - // TODO: Verify permissions - const guildMember = (await GuildMember.findOne({ + const accountId = await getAccountIdForRequest(req); + const member = (await GuildMember.findOne({ + accountId: accountId, + guildId: req.query.guildId as string + }))!; + const newRank: number = parseInt(req.query.rankChange as string); + + const guild = await getGuildForRequest(req); + if (newRank < member.rank || !hasGuildPermissionEx(guild, member, GuildPermission.Promoter)) { + res.status(400).json("Invalid permission"); + return; + } + + const target = (await GuildMember.findOne({ guildId: req.query.guildId as string, accountId: req.query.targetId as string }))!; - guildMember.rank = parseInt(req.query.rankChange as string); - await guildMember.save(); + target.rank = parseInt(req.query.rankChange as string); + await target.save(); - if (guildMember.rank == 0) { + if (newRank == 0) { // If we just promoted someone else to Founding Warlord, we need to demote ourselves to Warlord. - await GuildMember.findOneAndUpdate( - { - guildId: req.query.guildId as string, - accountId: req.query.accountId as string - }, - { rank: 1 } - ); + member.rank = 1; + await member.save(); } res.json({ _id: req.query.targetId as string, - Rank: guildMember.rank + Rank: newRank }); }; diff --git a/src/controllers/api/contributeToDojoComponentController.ts b/src/controllers/api/contributeToDojoComponentController.ts index 6f13ab54..9261627e 100644 --- a/src/controllers/api/contributeToDojoComponentController.ts +++ b/src/controllers/api/contributeToDojoComponentController.ts @@ -3,6 +3,7 @@ import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/invento import { getDojoClient, getGuildForRequestEx, + hasAccessToDojo, processDojoBuildMaterialsGathered, scaleRequiredCount, setDojoRoomLogFunded @@ -28,8 +29,12 @@ interface IContributeToDojoComponentRequest { export const contributeToDojoComponentController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); - const guild = await getGuildForRequestEx(req, inventory); // Any clan member should have permission to contribute although notably permission is denied if they have not crafted the dojo key and were simply invited in. + if (!hasAccessToDojo(inventory)) { + res.json({ DojoRequestStatus: -1 }); + return; + } + const guild = await getGuildForRequestEx(req, inventory); const request = JSON.parse(String(req.body)) as IContributeToDojoComponentRequest; const component = guild.DojoComponents.id(request.ComponentId)!; diff --git a/src/controllers/api/customizeGuildRanksController.ts b/src/controllers/api/customizeGuildRanksController.ts index 3e237a81..5ddca7b6 100644 --- a/src/controllers/api/customizeGuildRanksController.ts +++ b/src/controllers/api/customizeGuildRanksController.ts @@ -1,11 +1,16 @@ -import { getGuildForRequest } from "@/src/services/guildService"; -import { IGuildRank } from "@/src/types/guildTypes"; +import { getGuildForRequest, hasGuildPermission } from "@/src/services/guildService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission, IGuildRank } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const customizeGuildRanksController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); const guild = await getGuildForRequest(req); const payload = JSON.parse(String(req.body)) as ICustomizeGuildRanksRequest; - // TODO: Verify permissions + if (!(await hasGuildPermission(guild, accountId, GuildPermission.Ruler))) { + res.status(400).json("Invalid permission"); + return; + } guild.Ranks = payload.GuildRanks; await guild.save(); res.end(); diff --git a/src/controllers/api/destroyDojoDecoController.ts b/src/controllers/api/destroyDojoDecoController.ts index 1b7ec1dd..1b2517c3 100644 --- a/src/controllers/api/destroyDojoDecoController.ts +++ b/src/controllers/api/destroyDojoDecoController.ts @@ -1,8 +1,23 @@ -import { getDojoClient, getGuildForRequest, removeDojoDeco } from "@/src/services/guildService"; +import { + getDojoClient, + getGuildForRequest, + hasAccessToDojo, + hasGuildPermission, + removeDojoDeco +} from "@/src/services/guildService"; +import { getInventory } from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const destroyDojoDecoController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "LevelKeys"); const guild = await getGuildForRequest(req); + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Decorator))) { + res.json({ DojoRequestStatus: -1 }); + return; + } const request = JSON.parse(String(req.body)) as IDestroyDojoDecoRequest; removeDojoDeco(guild, request.ComponentId, request.DecoId); diff --git a/src/controllers/api/dojoComponentRushController.ts b/src/controllers/api/dojoComponentRushController.ts index 934b8d98..633b38e1 100644 --- a/src/controllers/api/dojoComponentRushController.ts +++ b/src/controllers/api/dojoComponentRushController.ts @@ -1,4 +1,4 @@ -import { getDojoClient, getGuildForRequestEx, scaleRequiredCount } from "@/src/services/guildService"; +import { getDojoClient, getGuildForRequestEx, hasAccessToDojo, scaleRequiredCount } from "@/src/services/guildService"; import { getInventory, updateCurrency } from "@/src/services/inventoryService"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { IDojoContributable } from "@/src/types/guildTypes"; @@ -17,6 +17,10 @@ interface IDojoComponentRushRequest { export const dojoComponentRushController: RequestHandler = async (req, res) => { const accountId = await getAccountIdForRequest(req); const inventory = await getInventory(accountId); + if (!hasAccessToDojo(inventory)) { + res.json({ DojoRequestStatus: -1 }); + return; + } const guild = await getGuildForRequestEx(req, inventory); const request = JSON.parse(String(req.body)) as IDojoComponentRushRequest; const component = guild.DojoComponents.id(request.ComponentId)!; diff --git a/src/controllers/api/guildTechController.ts b/src/controllers/api/guildTechController.ts index ff92244f..c51628af 100644 --- a/src/controllers/api/guildTechController.ts +++ b/src/controllers/api/guildTechController.ts @@ -1,5 +1,11 @@ import { RequestHandler } from "express"; -import { getGuildForRequestEx, getGuildVault, scaleRequiredCount } from "@/src/services/guildService"; +import { + getGuildForRequestEx, + getGuildVault, + hasAccessToDojo, + hasGuildPermission, + scaleRequiredCount +} from "@/src/services/guildService"; import { ExportDojoRecipes, IDojoResearch } from "warframe-public-export-plus"; import { getAccountIdForRequest } from "@/src/services/loginService"; import { @@ -13,7 +19,7 @@ import { import { IMiscItem } from "@/src/types/inventoryTypes/inventoryTypes"; import { IInventoryChanges } from "@/src/types/purchaseTypes"; import { config } from "@/src/services/configService"; -import { ITechProjectClient, ITechProjectDatabase } from "@/src/types/guildTypes"; +import { GuildPermission, ITechProjectClient, ITechProjectDatabase } from "@/src/types/guildTypes"; import { TGuildDatabaseDocument } from "@/src/models/guildModel"; import { toMongoDate } from "@/src/helpers/inventoryHelpers"; @@ -48,6 +54,10 @@ export const guildTechController: RequestHandler = async (req, res) => { } res.json({ TechProjects: techProjects }); } else if (action == "Start") { + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Fabricator))) { + res.status(400).send("-1").end(); + return; + } const recipe = ExportDojoRecipes.research[data.RecipeType!]; guild.TechProjects ??= []; if (!guild.TechProjects.find(x => x.ItemType == data.RecipeType)) { @@ -71,6 +81,10 @@ export const guildTechController: RequestHandler = async (req, res) => { await guild.save(); res.end(); } else if (action == "Contribute") { + if (!hasAccessToDojo(inventory)) { + res.status(400).send("-1").end(); + return; + } const contributions = data as IGuildTechContributeFields; const techProject = guild.TechProjects!.find(x => x.ItemType == contributions.RecipeType)!; @@ -133,9 +147,12 @@ export const guildTechController: RequestHandler = async (req, res) => { Vault: getGuildVault(guild) }); } else if (action == "Buy") { + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Fabricator))) { + res.status(400).send("-1").end(); + return; + } const purchase = data as IGuildTechBuyFields; const quantity = parseInt(data.Action.split(",")[1]); - const inventory = await getInventory(accountId); const recipeChanges = [ { ItemType: purchase.RecipeType, @@ -157,9 +174,12 @@ export const guildTechController: RequestHandler = async (req, res) => { } }); } else if (action == "Fabricate") { + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Fabricator))) { + res.status(400).send("-1").end(); + return; + } const payload = data as IGuildTechFabricateRequest; const recipe = ExportDojoRecipes.fabrications[payload.RecipeType]; - const inventory = await getInventory(accountId); const inventoryChanges: IInventoryChanges = updateCurrency(inventory, recipe.price, false); inventoryChanges.MiscItems = recipe.ingredients.map(x => ({ ItemType: x.ItemType, diff --git a/src/controllers/api/placeDecoInComponentController.ts b/src/controllers/api/placeDecoInComponentController.ts index b08a1700..2768be9e 100644 --- a/src/controllers/api/placeDecoInComponentController.ts +++ b/src/controllers/api/placeDecoInComponentController.ts @@ -1,12 +1,20 @@ -import { getDojoClient, getGuildForRequest } from "@/src/services/guildService"; +import { getDojoClient, getGuildForRequest, hasAccessToDojo, hasGuildPermission } from "@/src/services/guildService"; +import { getInventory } from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; import { Types } from "mongoose"; import { ExportDojoRecipes } from "warframe-public-export-plus"; export const placeDecoInComponentController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "LevelKeys"); const guild = await getGuildForRequest(req); + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Decorator))) { + res.json({ DojoRequestStatus: -1 }); + return; + } const request = JSON.parse(String(req.body)) as IPlaceDecoInComponentRequest; - // At this point, we know that a member of the guild is making this request. Assuming they are allowed to place decorations. const component = guild.DojoComponents.id(request.ComponentId)!; if (component.DecoCapacity === undefined) { diff --git a/src/controllers/api/queueDojoComponentDestructionController.ts b/src/controllers/api/queueDojoComponentDestructionController.ts index a4459cdd..3f8782cb 100644 --- a/src/controllers/api/queueDojoComponentDestructionController.ts +++ b/src/controllers/api/queueDojoComponentDestructionController.ts @@ -1,9 +1,18 @@ import { config } from "@/src/services/configService"; -import { getDojoClient, getGuildForRequest } from "@/src/services/guildService"; +import { getDojoClient, getGuildForRequest, hasAccessToDojo, hasGuildPermission } from "@/src/services/guildService"; +import { getInventory } from "@/src/services/inventoryService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const queueDojoComponentDestructionController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "LevelKeys"); const guild = await getGuildForRequest(req); + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Architect))) { + res.json({ DojoRequestStatus: -1 }); + return; + } const componentId = req.query.componentId as string; guild.DojoComponents.id(componentId)!.DestructionTime = new Date( diff --git a/src/controllers/api/removeFromGuildController.ts b/src/controllers/api/removeFromGuildController.ts index 2ae0be1c..3a794634 100644 --- a/src/controllers/api/removeFromGuildController.ts +++ b/src/controllers/api/removeFromGuildController.ts @@ -1,15 +1,20 @@ import { GuildMember } from "@/src/models/guildModel"; import { Account } from "@/src/models/loginModel"; -import { getGuildForRequest } from "@/src/services/guildService"; +import { getGuildForRequest, hasGuildPermission } from "@/src/services/guildService"; import { getInventory } from "@/src/services/inventoryService"; import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const removeFromGuildController: RequestHandler = async (req, res) => { const account = await getAccountForRequest(req); const guild = await getGuildForRequest(req); - // TODO: Check permissions const payload = JSON.parse(String(req.body)) as IRemoveFromGuildRequest; + const isKick = !account._id.equals(payload.userId); + if (isKick && !(await hasGuildPermission(guild, account._id, GuildPermission.Regulator))) { + res.status(400).json("Invalid permission"); + return; + } const guildMember = (await GuildMember.findOne({ accountId: payload.userId, guildId: guild._id }))!; if (guildMember.status == 0) { @@ -36,21 +41,19 @@ export const removeFromGuildController: RequestHandler = async (req, res) => { await GuildMember.deleteOne({ _id: guildMember._id }); guild.RosterActivity ??= []; - if (account._id.equals(payload.userId)) { - // Leave - guild.RosterActivity.push({ - dateTime: new Date(), - entryType: 7, - details: getSuffixedName(account) - }); - } else { - // Kick + if (isKick) { const kickee = (await Account.findOne({ _id: payload.userId }))!; guild.RosterActivity.push({ dateTime: new Date(), entryType: 12, details: getSuffixedName(kickee) + "," + getSuffixedName(account) }); + } else { + guild.RosterActivity.push({ + dateTime: new Date(), + entryType: 7, + details: getSuffixedName(account) + }); } await guild.save(); diff --git a/src/controllers/api/setGuildMotdController.ts b/src/controllers/api/setGuildMotdController.ts index 32f6f3ec..e0eb2aac 100644 --- a/src/controllers/api/setGuildMotdController.ts +++ b/src/controllers/api/setGuildMotdController.ts @@ -1,13 +1,18 @@ import { Guild } from "@/src/models/guildModel"; +import { hasGuildPermission } from "@/src/services/guildService"; import { getInventory } from "@/src/services/inventoryService"; import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService"; +import { GuildPermission } from "@/src/types/guildTypes"; import { RequestHandler } from "express"; export const setGuildMotdController: RequestHandler = async (req, res) => { const account = await getAccountForRequest(req); - const inventory = await getInventory(account._id.toString()); + const inventory = await getInventory(account._id.toString(), "GuildId"); const guild = (await Guild.findOne({ _id: inventory.GuildId! }))!; - // TODO: Check permissions + if (!(await hasGuildPermission(guild, account._id, GuildPermission.Herald))) { + res.status(400).json("Invalid permission"); + return; + } const IsLongMOTD = "longMOTD" in req.query; const MOTD = req.body ? String(req.body) : undefined; diff --git a/src/controllers/api/startDojoRecipeController.ts b/src/controllers/api/startDojoRecipeController.ts index d492c09a..ed2b9ab4 100644 --- a/src/controllers/api/startDojoRecipeController.ts +++ b/src/controllers/api/startDojoRecipeController.ts @@ -1,14 +1,18 @@ import { RequestHandler } from "express"; -import { IDojoComponentClient } from "@/src/types/guildTypes"; +import { GuildPermission, IDojoComponentClient } from "@/src/types/guildTypes"; import { getDojoClient, getGuildForRequest, + hasAccessToDojo, + hasGuildPermission, processDojoBuildMaterialsGathered, setDojoRoomLogFunded } from "@/src/services/guildService"; import { Types } from "mongoose"; import { ExportDojoRecipes } from "warframe-public-export-plus"; import { config } from "@/src/services/configService"; +import { getAccountIdForRequest } from "@/src/services/loginService"; +import { getInventory } from "@/src/services/inventoryService"; interface IStartDojoRecipeRequest { PlacedComponent: IDojoComponentClient; @@ -16,8 +20,13 @@ interface IStartDojoRecipeRequest { } export const startDojoRecipeController: RequestHandler = async (req, res) => { + const accountId = await getAccountIdForRequest(req); + const inventory = await getInventory(accountId, "LevelKeys"); const guild = await getGuildForRequest(req); - // At this point, we know that a member of the guild is making this request. Assuming they are allowed to start a build. + if (!hasAccessToDojo(inventory) || !(await hasGuildPermission(guild, accountId, GuildPermission.Architect))) { + res.json({ DojoRequestStatus: -1 }); + return; + } const request = JSON.parse(String(req.body)) as IStartDojoRecipeRequest; const room = Object.values(ExportDojoRecipes.rooms).find(x => x.resultType == request.PlacedComponent.pf); diff --git a/src/services/guildService.ts b/src/services/guildService.ts index bb580383..8a7e0220 100644 --- a/src/services/guildService.ts +++ b/src/services/guildService.ts @@ -4,6 +4,7 @@ import { addRecipes, getInventory } from "@/src/services/inventoryService"; import { Guild, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel"; import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel"; import { + GuildPermission, IDojoClient, IDojoComponentClient, IDojoComponentDatabase, @@ -11,6 +12,7 @@ import { IDojoDecoClient, IGuildClient, IGuildMemberClient, + IGuildMemberDatabase, IGuildVault } from "@/src/types/guildTypes"; import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers"; @@ -322,3 +324,28 @@ export const createUniqueClanName = async (name: string): Promise => { } while (discriminator != initialDiscriminator); throw new Error(`clan name is so unoriginal it's already been done 1000 times: ${name}`); }; + +export const hasAccessToDojo = (inventory: TInventoryDatabaseDocument): boolean => { + return inventory.LevelKeys.find(x => x.ItemType == "/Lotus/Types/Keys/DojoKey") !== undefined; +}; + +export const hasGuildPermission = async ( + guild: TGuildDatabaseDocument, + accountId: string | Types.ObjectId, + perm: GuildPermission +): Promise => { + const member = await GuildMember.findOne({ accountId: accountId, guildId: guild._id }); + if (member) { + return hasGuildPermissionEx(guild, member, perm); + } + return false; +}; + +export const hasGuildPermissionEx = ( + guild: TGuildDatabaseDocument, + member: IGuildMemberDatabase, + perm: GuildPermission +): boolean => { + const rank = guild.Ranks[member.rank]; + return (rank.Permissions & perm) != 0; +};