mirror of
https://github.com/spacebarchat/server.git
synced 2024-11-22 18:32:29 +01:00
Merge pull request #1196 from DEVTomatoCake/feat/list-create-developer-teams
Listing & creation of Developer Portal teams
This commit is contained in:
commit
2f0dabc8e9
@ -118,10 +118,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"team_id": {
|
"team_id": {
|
||||||
"type": [
|
"type": "string"
|
||||||
"string",
|
|
||||||
"integer"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
@ -3169,6 +3166,9 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"role": {
|
||||||
|
"$ref": "#/components/schemas/TeamMemberRole"
|
||||||
|
},
|
||||||
"team_id": {
|
"team_id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -3189,6 +3189,7 @@
|
|||||||
"id",
|
"id",
|
||||||
"membership_state",
|
"membership_state",
|
||||||
"permissions",
|
"permissions",
|
||||||
|
"role",
|
||||||
"team",
|
"team",
|
||||||
"team_id",
|
"team_id",
|
||||||
"user",
|
"user",
|
||||||
@ -3202,6 +3203,14 @@
|
|||||||
],
|
],
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
|
"TeamMemberRole": {
|
||||||
|
"enum": [
|
||||||
|
"admin",
|
||||||
|
"developer",
|
||||||
|
"read_only"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"Sticker": {
|
"Sticker": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -6307,6 +6316,17 @@
|
|||||||
"protocol"
|
"protocol"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"TeamCreateSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
},
|
||||||
"TemplateCreateSchema": {
|
"TemplateCreateSchema": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -7661,6 +7681,14 @@
|
|||||||
"location"
|
"location"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"TeamListResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"patternProperties": {
|
||||||
|
"^[0-9]+$": {
|
||||||
|
"$ref": "#/components/schemas/Team"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"TenorTrendingResponse": {
|
"TenorTrendingResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -10622,8 +10650,57 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"default": {
|
"200": {
|
||||||
"description": "No description available"
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TeamListResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "include_payout_account_status",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"description": "Whether to include team payout account status in the response (default false)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"teams"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"bearer": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TeamCreateSchema"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Team"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
|
11278
assets/schemas.json
11278
assets/schemas.json
File diff suppressed because it is too large
Load Diff
@ -18,12 +18,82 @@
|
|||||||
|
|
||||||
import { Request, Response, Router } from "express";
|
import { Request, Response, Router } from "express";
|
||||||
import { route } from "@spacebar/api";
|
import { route } from "@spacebar/api";
|
||||||
|
import {
|
||||||
|
Team,
|
||||||
|
TeamCreateSchema,
|
||||||
|
TeamMember,
|
||||||
|
TeamMemberRole,
|
||||||
|
TeamMemberState,
|
||||||
|
User,
|
||||||
|
} from "@spacebar/util";
|
||||||
|
import { HTTPError } from "lambert-server";
|
||||||
|
|
||||||
const router: Router = Router();
|
const router: Router = Router();
|
||||||
|
|
||||||
router.get("/", route({}), async (req: Request, res: Response) => {
|
router.get(
|
||||||
//TODO
|
"/",
|
||||||
res.send([]);
|
route({
|
||||||
});
|
query: {
|
||||||
|
include_payout_account_status: {
|
||||||
|
type: "boolean",
|
||||||
|
description:
|
||||||
|
"Whether to include team payout account status in the response (default false)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
body: "TeamListResponse",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
const teams = await Team.find({
|
||||||
|
where: {
|
||||||
|
owner_user_id: req.user_id,
|
||||||
|
},
|
||||||
|
relations: ["members"],
|
||||||
|
});
|
||||||
|
|
||||||
|
res.send(teams);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
"/",
|
||||||
|
route({
|
||||||
|
requestBody: "TeamCreateSchema",
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
body: "Team",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
async (req: Request, res: Response) => {
|
||||||
|
const user = await User.findOneOrFail({
|
||||||
|
where: [{ id: req.user_id }],
|
||||||
|
select: ["mfa_enabled"],
|
||||||
|
});
|
||||||
|
if (!user.mfa_enabled)
|
||||||
|
throw new HTTPError("You must enable MFA to create a team");
|
||||||
|
|
||||||
|
const body = req.body as TeamCreateSchema;
|
||||||
|
|
||||||
|
const team = Team.create({
|
||||||
|
name: body.name,
|
||||||
|
owner_user_id: req.user_id,
|
||||||
|
});
|
||||||
|
await team.save();
|
||||||
|
|
||||||
|
await TeamMember.create({
|
||||||
|
user_id: req.user_id,
|
||||||
|
team_id: team.id,
|
||||||
|
membership_state: TeamMemberState.ACCEPTED,
|
||||||
|
permissions: ["*"],
|
||||||
|
role: TeamMemberRole.ADMIN,
|
||||||
|
}).save();
|
||||||
|
|
||||||
|
res.json(team);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
@ -25,6 +25,11 @@ export enum TeamMemberState {
|
|||||||
INVITED = 1,
|
INVITED = 1,
|
||||||
ACCEPTED = 2,
|
ACCEPTED = 2,
|
||||||
}
|
}
|
||||||
|
export enum TeamMemberRole {
|
||||||
|
ADMIN = "admin",
|
||||||
|
DEVELOPER = "developer",
|
||||||
|
READ_ONLY = "read_only",
|
||||||
|
}
|
||||||
|
|
||||||
@Entity({
|
@Entity({
|
||||||
name: "team_members",
|
name: "team_members",
|
||||||
@ -37,6 +42,9 @@ export class TeamMember extends BaseClass {
|
|||||||
@Column({ type: "simple-array" })
|
@Column({ type: "simple-array" })
|
||||||
permissions: string[];
|
permissions: string[];
|
||||||
|
|
||||||
|
@Column()
|
||||||
|
role: TeamMemberRole;
|
||||||
|
|
||||||
@Column({ nullable: true })
|
@Column({ nullable: true })
|
||||||
@RelationId((member: TeamMember) => member.team)
|
@RelationId((member: TeamMember) => member.team)
|
||||||
team_id: string;
|
team_id: string;
|
||||||
|
17
src/util/migration/mariadb/1724477620293-teamMemberRole.ts
Normal file
17
src/util/migration/mariadb/1724477620293-teamMemberRole.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class TeamMemberRole1724477620293 implements MigrationInterface {
|
||||||
|
name = "TeamMemberRole1724477620293";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `team_members` ADD COLUMN `role` VARCHAR(255) NOT NULL AFTER `permissions`",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `team_members` DROP COLUMN `role`",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
17
src/util/migration/mysql/1724477620293-teamMemberRole.ts
Normal file
17
src/util/migration/mysql/1724477620293-teamMemberRole.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class TeamMemberRole1724477620293 implements MigrationInterface {
|
||||||
|
name = "TeamMemberRole1724477620293";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `team_members` ADD COLUMN `role` VARCHAR(255) NOT NULL AFTER `permissions`",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE `team_members` DROP COLUMN `role`",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
15
src/util/migration/postgres/1724477620293-teamMemberRole.ts
Normal file
15
src/util/migration/postgres/1724477620293-teamMemberRole.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class TeamMemberRole1724477620293 implements MigrationInterface {
|
||||||
|
name = "TeamMemberRole1724477620293";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
"ALTER TABLE team_members ADD COLUMN role text NOT NULL",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query("ALTER TABLE team_members DROP COLUMN role");
|
||||||
|
}
|
||||||
|
}
|
@ -18,5 +18,5 @@
|
|||||||
|
|
||||||
export interface ApplicationCreateSchema {
|
export interface ApplicationCreateSchema {
|
||||||
name: string;
|
name: string;
|
||||||
team_id?: string | number;
|
team_id?: string;
|
||||||
}
|
}
|
||||||
|
21
src/util/schemas/TeamCreateSchema.ts
Normal file
21
src/util/schemas/TeamCreateSchema.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface TeamCreateSchema {
|
||||||
|
name: string;
|
||||||
|
}
|
@ -62,6 +62,7 @@ export * from "./RequestGuildMembersSchema";
|
|||||||
export * from "./RoleModifySchema";
|
export * from "./RoleModifySchema";
|
||||||
export * from "./RolePositionUpdateSchema";
|
export * from "./RolePositionUpdateSchema";
|
||||||
export * from "./SelectProtocolSchema";
|
export * from "./SelectProtocolSchema";
|
||||||
|
export * from "./TeamCreateSchema";
|
||||||
export * from "./TemplateCreateSchema";
|
export * from "./TemplateCreateSchema";
|
||||||
export * from "./TemplateModifySchema";
|
export * from "./TemplateModifySchema";
|
||||||
export * from "./TotpDisableSchema";
|
export * from "./TotpDisableSchema";
|
||||||
|
21
src/util/schemas/responses/TeamListResponse.ts
Normal file
21
src/util/schemas/responses/TeamListResponse.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||||
|
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published
|
||||||
|
by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Team } from "@spacebar/util";
|
||||||
|
|
||||||
|
export interface TeamListResponse extends Array<Team> {}
|
@ -40,6 +40,7 @@ export * from "./InstanceStatsResponse";
|
|||||||
export * from "./LocationMetadataResponse";
|
export * from "./LocationMetadataResponse";
|
||||||
export * from "./MemberJoinGuildResponse";
|
export * from "./MemberJoinGuildResponse";
|
||||||
export * from "./OAuthAuthorizeResponse";
|
export * from "./OAuthAuthorizeResponse";
|
||||||
|
export * from "./TeamListResponse";
|
||||||
export * from "./Tenor";
|
export * from "./Tenor";
|
||||||
export * from "./TokenResponse";
|
export * from "./TokenResponse";
|
||||||
export * from "./TypedResponses";
|
export * from "./TypedResponses";
|
||||||
|
Loading…
Reference in New Issue
Block a user