Add community invites api

This commit is contained in:
Aslan 2026-01-10 19:40:44 -05:00
parent e120a12eaa
commit 23128f25e1
8 changed files with 118 additions and 15 deletions

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "tether",
"version": "0.3.6",
"version": "0.3.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "tether",
"version": "0.3.6",
"version": "0.3.7",
"license": "GPL-3.0-only",
"dependencies": {
"@fastify/cookie": "^11.0.2",

View file

@ -1,6 +1,6 @@
{
"name": "tether",
"version": "0.3.6",
"version": "0.3.7",
"description": "Communication server using the Nexlink protocol",
"repository": {
"type": "git",

View file

@ -22,6 +22,9 @@ import type {
IGetRolesParams,
IGetRolesResponseError,
IGetRolesResponseSuccess,
IGetInvitesParams,
IGetInvitesResponseError,
IGetInvitesResponseSuccess,
IPostCreateInviteParams,
IPostCreateInviteRequest,
IPostCreateInviteResponseError,
@ -34,6 +37,7 @@ import {
getCommunityChannelsByIdAuth,
getCommunityMembersByIdAuth,
getCommunityRolesByIdAuth,
getCommunityInvitesByIdAuth,
createInviteAuth,
deleteCommunityByIdAuth,
} from "../../services/community/community.js";
@ -243,6 +247,36 @@ const getRoles = async (request: FastifyRequest, reply: FastifyReply) => {
} as IGetRolesResponseSuccess;
};
const getInvites = async (request: FastifyRequest, reply: FastifyReply) => {
const { id } = request.params as IGetInvitesParams;
const authHeader = request.headers["authorization"];
const community = await getCommunityById(id);
const invites = await getCommunityInvitesByIdAuth(id, authHeader);
if (!invites || !community) {
reply.status(404);
return {
id: id,
error: API_ERROR.NOT_FOUND,
} as IGetInvitesResponseError;
}
if (invites === API_ERROR.ACCESS_DENIED) {
reply.status(403);
return {
id: id,
error: API_ERROR.ACCESS_DENIED,
} as IGetInvitesResponseError;
}
return {
id: community.id,
name: community.name,
invites: invites.map((invite) => ({
id: invite.id,
})),
} as IGetInvitesResponseSuccess;
};
const postCreateInvite = async (
request: FastifyRequest,
reply: FastifyReply,
@ -292,5 +326,6 @@ export {
getMembers,
getChannels,
getRoles,
getInvites,
postCreateInvite,
};

View file

@ -9,6 +9,7 @@ const communityRoutes = async (fastify: FastifyInstance) => {
fastify.get(`/:id/members`, controller.getMembers);
fastify.get(`/:id/channels`, controller.getChannels);
fastify.get(`/:id/roles`, controller.getRoles);
fastify.get(`/:id/invites`, controller.getInvites);
fastify.post(`/:id/invite`, controller.postCreateInvite);
};

View file

@ -72,10 +72,10 @@ interface IGetMembersResponseError {
interface IGetMembersResponseSuccess {
id: string;
name: string;
members: IGetMembersResponseMembers[];
members: IGetMembersResponseMember[];
}
interface IGetMembersResponseMembers {
interface IGetMembersResponseMember {
id: string;
username: string;
}
@ -92,10 +92,10 @@ interface IGetChannelsResponseError {
interface IGetChannelsResponseSuccess {
id: string;
name: string;
channels: IGetChannelsResponseChannels[];
channels: IGetChannelsResponseChannel[];
}
interface IGetChannelsResponseChannels {
interface IGetChannelsResponseChannel {
id: string;
name: string;
}
@ -112,14 +112,33 @@ interface IGetRolesResponseError {
interface IGetRolesResponseSuccess {
id: string;
name: string;
roles: IGetRolesResponseRoles[];
roles: IGetRolesResponseRole[];
}
interface IGetRolesResponseRoles {
interface IGetRolesResponseRole {
id: string;
name: string;
}
interface IGetInvitesParams {
id: string;
}
interface IGetInvitesResponseError {
id: string;
error: API_ERROR;
}
interface IGetInvitesResponseSuccess {
id: string;
name: string;
invites: IGetInvitesResponseInvite[];
}
interface IGetInvitesResponseInvite {
id: string;
}
interface IPostCreateInviteParams {
id: string;
}
@ -157,15 +176,19 @@ export {
type IGetMembersParams,
type IGetMembersResponseError,
type IGetMembersResponseSuccess,
type IGetMembersResponseMembers,
type IGetMembersResponseMember,
type IGetChannelsParams,
type IGetChannelsResponseError,
type IGetChannelsResponseSuccess,
type IGetChannelsResponseChannels,
type IGetChannelsResponseChannel,
type IGetRolesParams,
type IGetRolesResponseError,
type IGetRolesResponseSuccess,
type IGetRolesResponseRoles,
type IGetRolesResponseRole,
type IGetInvitesParams,
type IGetInvitesResponseError,
type IGetInvitesResponseSuccess,
type IGetInvitesResponseInvite,
type IPostCreateInviteParams,
type IPostCreateInviteRequest,
type IPostCreateInviteResponseError,

View file

@ -3,12 +3,12 @@ enum PERMISSION {
CHANNELS_READ = "CHANNELS_READ",
CHANNELS_MANAGE = "CHANNELS_MANAGE",
ROLES_READ = "ROLES_READ",
INVITES_CREATE = "INVITES_CREATE",
INVITES_DELETE = "INVITES_DELETE",
ROLES_MANAGE = "ROLES_MANAGE",
MEMBERS_READ = "MEMBERS_READ",
MEMBERS_KICK = "MEMBERS_KICK",
MEMBERS_BAN = "MEMBERS_BAN",
INVITES_CREATE = "INVITES_CREATE",
INVITES_DELETE = "INVITES_DELETE",
}
export { PERMISSION };

View file

@ -9,11 +9,12 @@ import {
import { PERMISSION } from "../auth/permission.js";
import type {
ICreateCommunity,
IUpdateCommunity,
ICommunityChannel,
ICommunityMember,
ICommunityRole,
ICommunityInvite,
ICreateInvite,
IUpdateCommunity,
} from "./types.js";
const getCommunityById = async (id: string): Promise<Community | null> => {
@ -227,6 +228,42 @@ const getCommunityRolesByIdAuth = async (
return await getCommunityRolesById(id);
};
const getCommunityInvitesById = async (
id: string,
): Promise<ICommunityInvite[]> => {
return await getDB().invite.findMany({
where: {
communityId: id,
},
select: {
id: true,
},
});
};
const getCommunityInvitesByIdAuth = async (
id: string,
authHeader: string | undefined,
): Promise<ICommunityInvite[] | API_ERROR.ACCESS_DENIED> => {
const authUser = await getUserFromAuth(authHeader);
const community = await getCommunityById(id);
if (
!(await isUserAllowed(
authUser,
{
community: community,
},
community,
[PERMISSION.INVITES_CREATE],
))
) {
return API_ERROR.ACCESS_DENIED;
}
return await getCommunityInvitesById(id);
};
const createInvite = async (
id: string,
creatorId: string,
@ -280,6 +317,8 @@ export {
getCommunityChannelsByIdAuth,
getCommunityRolesById,
getCommunityRolesByIdAuth,
getCommunityInvitesById,
getCommunityInvitesByIdAuth,
createInvite,
createInviteAuth,
};

View file

@ -23,6 +23,10 @@ interface ICommunityRole {
name: string;
}
interface ICommunityInvite {
id: string;
}
interface ICreateInvite {
totalInvites?: number;
remainingInvites?: number;
@ -35,5 +39,6 @@ export {
type ICommunityMember,
type ICommunityChannel,
type ICommunityRole,
type ICommunityInvite,
type ICreateInvite,
};