mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Team membership webhook (#234)
* fixed webhook docs type * fixed docs * added team memberships webhook * changed docs sidebar width * updated tests
This commit is contained in:
parent
af53d0ca98
commit
bb7074a29e
@ -10,6 +10,7 @@ import { KnownErrors } from "@stackframe/stack-shared";
|
||||
import { ProjectsCrud } from "@stackframe/stack-shared/dist/interface/crud/projects";
|
||||
import { PrismaTransaction } from "@/lib/types";
|
||||
import { createLazyProxy } from "@stackframe/stack-shared/dist/utils/proxies";
|
||||
import { sendTeamMembershipCreatedWebhook, sendTeamMembershipDeletedWebhook } from "@/lib/webhooks";
|
||||
|
||||
|
||||
export async function addUserToTeam(tx: PrismaTransaction, options: {
|
||||
@ -91,12 +92,22 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl
|
||||
});
|
||||
});
|
||||
|
||||
return {};
|
||||
const data = {
|
||||
team_id: params.team_id,
|
||||
user_id: userId,
|
||||
};
|
||||
|
||||
await sendTeamMembershipCreatedWebhook({
|
||||
projectId: auth.project.id,
|
||||
data,
|
||||
});
|
||||
|
||||
return data;
|
||||
},
|
||||
onDelete: async ({ auth, params }) => {
|
||||
await prismaClient.$transaction(async (tx) => {
|
||||
const userId = getIdFromUserIdOrMe(params.user_id, auth.user);
|
||||
const userId = getIdFromUserIdOrMe(params.user_id, auth.user);
|
||||
|
||||
await prismaClient.$transaction(async (tx) => {
|
||||
// Users are always allowed to remove themselves from a team
|
||||
// Only users with the $remove_members permission can remove other users
|
||||
if (auth.type === 'client') {
|
||||
@ -129,5 +140,13 @@ export const teamMembershipsCrudHandlers = createLazyProxy(() => createCrudHandl
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
await sendTeamMembershipDeletedWebhook({
|
||||
projectId: auth.project.id,
|
||||
data: {
|
||||
team_id: params.team_id,
|
||||
user_id: userId,
|
||||
},
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
@ -541,7 +541,6 @@ export const usersCrudHandlers = createLazyProxy(() => createCrudHandlers(usersC
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
await sendUserCreatedWebhook({
|
||||
projectId: auth.project.id,
|
||||
data: result,
|
||||
|
||||
@ -57,7 +57,10 @@ export function parseWebhookOpenAPI(options: {
|
||||
metadata: webhook.metadata,
|
||||
method: 'POST',
|
||||
path: webhook.type,
|
||||
requestBodyDesc: undefinedIfMixed(webhook.schema.describe()) || yupObject().describe(),
|
||||
requestBodyDesc: undefinedIfMixed(yupObject({
|
||||
type: yupString().required().meta({ openapiField: { description: webhook.type, exampleValue: webhook.type }}),
|
||||
data: webhook.schema.required(),
|
||||
}).describe()) || yupObject().describe(),
|
||||
responseTypeDesc: yupString().oneOf(['json']).describe(),
|
||||
statusCodeDesc: yupNumber().oneOf([200]).describe(),
|
||||
}),
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { teamMembershipCreatedWebhookEvent, teamMembershipDeletedWebhookEvent } from "@stackframe/stack-shared/dist/interface/crud/team-memberships";
|
||||
import { teamCreatedWebhookEvent, teamDeletedWebhookEvent, teamUpdatedWebhookEvent } from "@stackframe/stack-shared/dist/interface/crud/teams";
|
||||
import { userCreatedWebhookEvent, userDeletedWebhookEvent, userUpdatedWebhookEvent } from "@stackframe/stack-shared/dist/interface/crud/users";
|
||||
import { WebhookEvent } from "@stackframe/stack-shared/dist/interface/webhooks";
|
||||
@ -51,3 +52,5 @@ export const sendUserDeletedWebhook = createWebhookSender(userDeletedWebhookEven
|
||||
export const sendTeamCreatedWebhook = createWebhookSender(teamCreatedWebhookEvent);
|
||||
export const sendTeamUpdatedWebhook = createWebhookSender(teamUpdatedWebhookEvent);
|
||||
export const sendTeamDeletedWebhook = createWebhookSender(teamDeletedWebhookEvent);
|
||||
export const sendTeamMembershipCreatedWebhook = createWebhookSender(teamMembershipCreatedWebhookEvent);
|
||||
export const sendTeamMembershipDeletedWebhook = createWebhookSender(teamMembershipDeletedWebhookEvent);
|
||||
|
||||
@ -49,7 +49,10 @@ it("creates a team and manage users on the server", async ({ expect }) => {
|
||||
expect(response).toMatchInlineSnapshot(`
|
||||
NiceResponse {
|
||||
"status": 201,
|
||||
"body": {},
|
||||
"body": {
|
||||
"team_id": "<stripped UUID>",
|
||||
"user_id": "<stripped UUID>",
|
||||
},
|
||||
"headers": Headers { <some fields may have been hidden> },
|
||||
}
|
||||
`);
|
||||
|
||||
@ -176,6 +176,7 @@ layout:
|
||||
content-width: 40rem
|
||||
disable-header: false
|
||||
header-height: 60px
|
||||
sidebar-width: 300px
|
||||
favicon: ./docs/assets/favicon.ico
|
||||
logo:
|
||||
light: ./docs/assets/logo-light-mode.svg
|
||||
|
||||
@ -11,7 +11,7 @@ In the Stack dashboard, you can create a webhook endpoint in the "Webhooks" sect
|
||||
|
||||
```json
|
||||
{
|
||||
"event": "team.created",
|
||||
"type": "team.created",
|
||||
"data": {
|
||||
"id": "2209422a-eef7-4668-967d-be79409972c5",
|
||||
"display_name": "My Team",
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
import { CrudTypeOf, createCrud } from "../../crud";
|
||||
import { yupMixed, yupObject } from "../../schema-fields";
|
||||
import { yupMixed, yupObject, yupString } from "../../schema-fields";
|
||||
import { WebhookEvent } from "../webhooks";
|
||||
|
||||
export const teamMembershipsCrudClientReadSchema = yupObject({}).required();
|
||||
export const teamMembershipsCrudClientReadSchema = yupObject({
|
||||
team_id: yupString().required(),
|
||||
user_id: yupString().required(),
|
||||
}).required();
|
||||
export const teamMembershipsCrudServerCreateSchema = yupObject({}).required();
|
||||
export const teamMembershipsCrudClientDeleteSchema = yupMixed();
|
||||
|
||||
@ -29,4 +33,24 @@ export const teamMembershipsCrud = createCrud({
|
||||
},
|
||||
},
|
||||
});
|
||||
export type TeamMembershipsCrud = CrudTypeOf<typeof teamMembershipsCrud>;
|
||||
export type TeamMembershipsCrud = CrudTypeOf<typeof teamMembershipsCrud>;
|
||||
|
||||
export const teamMembershipCreatedWebhookEvent = {
|
||||
type: "team_membership.created",
|
||||
schema: teamMembershipsCrud.server.readSchema,
|
||||
metadata: {
|
||||
summary: "Team Membership Created",
|
||||
description: "This event is triggered when a user is added to a team.",
|
||||
tags: ["Teams"],
|
||||
},
|
||||
} satisfies WebhookEvent<typeof teamMembershipsCrud.server.readSchema>;
|
||||
|
||||
export const teamMembershipDeletedWebhookEvent = {
|
||||
type: "team_membership.deleted",
|
||||
schema: teamMembershipsCrud.server.readSchema,
|
||||
metadata: {
|
||||
summary: "Team Membership Deleted",
|
||||
description: "This event is triggered when a user is removed from a team.",
|
||||
tags: ["Teams"],
|
||||
},
|
||||
} satisfies WebhookEvent<typeof teamMembershipsCrud.server.readSchema>;
|
||||
@ -1,4 +1,5 @@
|
||||
import * as yup from "yup";
|
||||
import { teamMembershipCreatedWebhookEvent, teamMembershipDeletedWebhookEvent } from "./crud/team-memberships";
|
||||
import { teamCreatedWebhookEvent, teamDeletedWebhookEvent, teamUpdatedWebhookEvent } from "./crud/teams";
|
||||
import { userCreatedWebhookEvent, userDeletedWebhookEvent, userUpdatedWebhookEvent } from "./crud/users";
|
||||
|
||||
@ -19,4 +20,6 @@ export const webhookEvents = [
|
||||
teamCreatedWebhookEvent,
|
||||
teamUpdatedWebhookEvent,
|
||||
teamDeletedWebhookEvent,
|
||||
teamMembershipCreatedWebhookEvent,
|
||||
teamMembershipDeletedWebhookEvent,
|
||||
] as const;
|
||||
Loading…
Reference in New Issue
Block a user