diff --git a/apps/web/prisma/migrations/20250822125136_add_domain_access_to_api_keys/migration.sql b/apps/web/prisma/migrations/20250822125136_add_domain_access_to_api_keys/migration.sql new file mode 100644 index 0000000..318681a --- /dev/null +++ b/apps/web/prisma/migrations/20250822125136_add_domain_access_to_api_keys/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE "ApiKey" ADD COLUMN "domainId" INTEGER; + +-- AddForeignKey +ALTER TABLE "ApiKey" ADD CONSTRAINT "ApiKey_domainId_fkey" FOREIGN KEY ("domainId") REFERENCES "Domain"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/apps/web/prisma/schema.prisma b/apps/web/prisma/schema.prisma index a2ae7ed..7c4925f 100644 --- a/apps/web/prisma/schema.prisma +++ b/apps/web/prisma/schema.prisma @@ -195,6 +195,7 @@ model Domain { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) + apiKeys ApiKey[] } enum ApiPermission { @@ -209,11 +210,13 @@ model ApiKey { partialToken String name String permission ApiPermission @default(SENDING) + domainId Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt lastUsed DateTime? teamId Int team Team @relation(fields: [teamId], references: [id], onDelete: Cascade) + domain Domain? @relation(fields: [domainId], references: [id], onDelete: Cascade) } enum EmailStatus { diff --git a/apps/web/src/app/(dashboard)/dev-settings/api-keys/add-api-key.tsx b/apps/web/src/app/(dashboard)/dev-settings/api-keys/add-api-key.tsx index b6e674b..098e10d 100644 --- a/apps/web/src/app/(dashboard)/dev-settings/api-keys/add-api-key.tsx +++ b/apps/web/src/app/(dashboard)/dev-settings/api-keys/add-api-key.tsx @@ -27,11 +27,20 @@ import { FormLabel, FormMessage, } from "@usesend/ui/src/form"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@unsend/ui/src/select"; + const apiKeySchema = z.object({ name: z.string({ required_error: "Name is required" }).min(1, { message: "Name is required", }), + domainId: z.string().optional(), }); export default function AddApiKey() { @@ -40,6 +49,8 @@ export default function AddApiKey() { const createApiKeyMutation = api.apiKey.createToken.useMutation(); const [isCopied, setIsCopied] = useState(false); const [showApiKey, setShowApiKey] = useState(false); + + const domainsQuery = api.domain.domains.useQuery(); const utils = api.useUtils(); @@ -47,6 +58,7 @@ export default function AddApiKey() { resolver: zodResolver(apiKeySchema), defaultValues: { name: "", + domainId: "all", }, }); @@ -55,6 +67,7 @@ export default function AddApiKey() { { name: values.name, permission: "FULL", + domainId: values.domainId === "all" ? undefined : Number(values.domainId), }, { onSuccess: (data) => { @@ -180,6 +193,33 @@ export default function AddApiKey() { )} /> + ( + + Domain access + + + Choose which domain this API key can send emails from. + + + )} + />