feat: v2 managed organizations (#19341)

* refactor: allow non unique PlatformBilling customerId

* feat: add PlatformBilling managed organizations fields

* feat: ManagedOrganization table

* refactor: bill overdue based on teamId

* refactor: restructure organizations module

* wip: organizations endpoints

* Revert "wip: organizations endpoints"

This reverts commit 0e9e66fc74f31da436f12930c1b6597c650ed621.

* refactor: unique index for managed organizations

* wip: organizations endpoints

* wip: create managed organization

* remove unecessary membership check because we have guard

* feat: create managed org

* feat: get managed org and orgs

* feat: update and delete managed orgs

* wip: api key logic

* feat: allow variable api key length

* feat: refresh managed org api key

* feat: create managed org OAuth clients using api key

* finish merge main

* chore: bump platform libraries

* tests: fix and add more tests to api-auth.strategy.e2e

* refactor: dont request managed org slug and handle metadata as object

* revert: billing service and repository update overdue based on sub and customer ids

* refactor: v2 OAuth client permissions (#19501)

* refactor: v2 permissions as string array

* refactor: frontend work with permissions as string

* tests: test '*' permissions

* fix:managed org creator have profile & test can fetch oauth client

* fix: tests

* fix: OAuthClientCard on frontend

* fix: tests
This commit is contained in:
Lauris Skraucis authored and GitHub committed 2025-02-25 18:10:46 -07:00
1 parent e4ab8d87c4
commit a44bcafcf2
192 files changed
+9103 -619

No files matched your search

@@ -0,0 +1,48 @@
import { API_VERSIONS_VALUES } from "@/lib/api-versions";
import { RefreshApiKeyInput } from "@/modules/api-keys/inputs/refresh-api-key.input";
import { RefreshApiKeyOutput } from "@/modules/api-keys/outputs/refresh-api-key.output";
import { ApiKeysService } from "@/modules/api-keys/services/api-keys.service";
import { GetUser } from "@/modules/auth/decorators/get-user/get-user.decorator";
import { ApiAuthGuard } from "@/modules/auth/guards/api-auth/api-auth.guard";
import { ApiAuthGuardRequest } from "@/modules/auth/strategies/api-auth/api-auth.strategy";
import { Body, Controller, HttpCode, HttpStatus, Post, Req, UseGuards } from "@nestjs/common";
import { ApiTags, ApiHeader, ApiOperation } from "@nestjs/swagger";
import { SUCCESS_STATUS } from "@calcom/platform-constants";
@Controller({
path: "/v2/api-keys",
version: API_VERSIONS_VALUES,
})
@UseGuards(ApiAuthGuard)
@ApiTags("Api Keys")
export class ApiKeysController {
constructor(private readonly apiKeysService: ApiKeysService) {}
@ApiOperation({
summary: "Refresh API Key",
description: `Generate a new API key and delete the current one. Provide API key to refresh as a Bearer token in the Authorization header (e.g. "Authorization: Bearer <apiKey>").`,
})
@ApiHeader({
name: "Authorization",
description: "Bearer <apiKey>",
required: true,
schema: { type: "string" },
})
@Post("/refresh")
@HttpCode(HttpStatus.OK)
async refresh(
@Body() body: RefreshApiKeyInput,
@GetUser("id") userId: number,
@Req() request: ApiAuthGuardRequest
): Promise<RefreshApiKeyOutput> {
const currentApiKey = await this.apiKeysService.getRequestApiKey(request);
const newApiKey = await this.apiKeysService.refreshApiKey(userId, currentApiKey, body);
return {
status: SUCCESS_STATUS,
data: {
apiKey: newApiKey,
},
};
}
}