144 lines
4.0 KiB
TypeScript
144 lines
4.0 KiB
TypeScript
import { query, mutation, internalMutation } from "./_generated/server";
|
|
import { v } from "convex/values";
|
|
import { getRolesForUser } from "./roles";
|
|
|
|
export const get = query({
|
|
args: {},
|
|
returns: v.any(),
|
|
handler: async (ctx) => {
|
|
const settings = await ctx.db.query("serverSettings").first();
|
|
if (!settings) return null;
|
|
let iconUrl = null;
|
|
if (settings.iconStorageId) {
|
|
iconUrl = await ctx.storage.getUrl(settings.iconStorageId);
|
|
}
|
|
return { ...settings, iconUrl };
|
|
},
|
|
});
|
|
|
|
export const update = mutation({
|
|
args: {
|
|
userId: v.id("userProfiles"),
|
|
afkChannelId: v.optional(v.id("channels")),
|
|
afkTimeout: v.number(),
|
|
},
|
|
returns: v.null(),
|
|
handler: async (ctx, args) => {
|
|
// Permission check
|
|
const roles = await getRolesForUser(ctx, args.userId);
|
|
const canManage = roles.some(
|
|
(role) => (role.permissions as Record<string, boolean>)?.["manage_channels"]
|
|
);
|
|
if (!canManage) {
|
|
throw new Error("You don't have permission to manage server settings");
|
|
}
|
|
|
|
// Validate timeout range
|
|
if (args.afkTimeout < 60 || args.afkTimeout > 3600) {
|
|
throw new Error("AFK timeout must be between 60 and 3600 seconds");
|
|
}
|
|
|
|
// Validate AFK channel is a voice channel if provided
|
|
if (args.afkChannelId) {
|
|
const channel = await ctx.db.get(args.afkChannelId);
|
|
if (!channel) throw new Error("AFK channel not found");
|
|
if (channel.type !== "voice") throw new Error("AFK channel must be a voice channel");
|
|
}
|
|
|
|
const existing = await ctx.db.query("serverSettings").first();
|
|
if (existing) {
|
|
await ctx.db.patch(existing._id, {
|
|
afkChannelId: args.afkChannelId,
|
|
afkTimeout: args.afkTimeout,
|
|
});
|
|
} else {
|
|
await ctx.db.insert("serverSettings", {
|
|
afkChannelId: args.afkChannelId,
|
|
afkTimeout: args.afkTimeout,
|
|
});
|
|
}
|
|
|
|
return null;
|
|
},
|
|
});
|
|
|
|
export const updateName = mutation({
|
|
args: {
|
|
userId: v.id("userProfiles"),
|
|
serverName: v.string(),
|
|
},
|
|
returns: v.null(),
|
|
handler: async (ctx, args) => {
|
|
// Permission check
|
|
const roles = await getRolesForUser(ctx, args.userId);
|
|
const canManage = roles.some(
|
|
(role) => (role.permissions as Record<string, boolean>)?.["manage_channels"]
|
|
);
|
|
if (!canManage) {
|
|
throw new Error("You don't have permission to manage server settings");
|
|
}
|
|
|
|
// Validate name
|
|
const name = args.serverName.trim();
|
|
if (name.length === 0 || name.length > 100) {
|
|
throw new Error("Server name must be between 1 and 100 characters");
|
|
}
|
|
|
|
const existing = await ctx.db.query("serverSettings").first();
|
|
if (existing) {
|
|
await ctx.db.patch(existing._id, { serverName: name });
|
|
} else {
|
|
await ctx.db.insert("serverSettings", {
|
|
serverName: name,
|
|
afkTimeout: 300,
|
|
});
|
|
}
|
|
|
|
return null;
|
|
},
|
|
});
|
|
|
|
export const updateIcon = mutation({
|
|
args: {
|
|
userId: v.id("userProfiles"),
|
|
iconStorageId: v.optional(v.id("_storage")),
|
|
},
|
|
returns: v.null(),
|
|
handler: async (ctx, args) => {
|
|
// Permission check
|
|
const roles = await getRolesForUser(ctx, args.userId);
|
|
const canManage = roles.some(
|
|
(role) => (role.permissions as Record<string, boolean>)?.["manage_channels"]
|
|
);
|
|
if (!canManage) {
|
|
throw new Error("You don't have permission to manage server settings");
|
|
}
|
|
|
|
const existing = await ctx.db.query("serverSettings").first();
|
|
if (existing) {
|
|
await ctx.db.patch(existing._id, {
|
|
iconStorageId: args.iconStorageId,
|
|
});
|
|
} else {
|
|
await ctx.db.insert("serverSettings", {
|
|
iconStorageId: args.iconStorageId,
|
|
afkTimeout: 300,
|
|
});
|
|
}
|
|
|
|
return null;
|
|
},
|
|
});
|
|
|
|
export const clearAfkChannel = internalMutation({
|
|
args: { channelId: v.id("channels") },
|
|
returns: v.null(),
|
|
handler: async (ctx, args) => {
|
|
const settings = await ctx.db.query("serverSettings").first();
|
|
if (settings && settings.afkChannelId === args.channelId) {
|
|
await ctx.db.patch(settings._id, { afkChannelId: undefined });
|
|
}
|
|
return null;
|
|
},
|
|
});
|