feat(webapp): extend admin workers endpoint and unify admin api auth (#3390)
Extends the admin worker groups endpoint with a GET loader and more fields on POST (type, hidden, workloadType, cloudProvider, location, staticIPs, enableFastPath), and pulls the PAT + admin check that was inlined or locally duplicated across every admin.api route into a shared helper in personalAccessToken.server.ts. The generic authenticateAdminRequest returns a discriminated result; requireAdminApiRequest is the thin Remix loader/action wrapper that throws. The neverthrow-style route (platform-notifications.ts) now composes the generic helper instead of duplicating the check. Verified locally against GET (listing) and POST (new fields, invalid enum, minimal backwards-compat).
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
area: webapp
|
||||
type: improvement
|
||||
---
|
||||
|
||||
Admin worker groups API: add GET loader and expose more fields on POST.
|
||||
+2
-21
@@ -2,7 +2,7 @@ import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import pMap from "p-map";
|
||||
import { z } from "zod";
|
||||
import { $replica, prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { determineEngineVersion } from "~/v3/engineVersion.server";
|
||||
import { engine } from "~/v3/runEngine.server";
|
||||
|
||||
@@ -16,26 +16,7 @@ const BodySchema = z.object({
|
||||
});
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const parsedParams = ParamsSchema.parse(params);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { json, LoaderFunctionArgs } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { $replica, prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { determineEngineVersion } from "~/v3/engineVersion.server";
|
||||
import { engine } from "~/v3/runEngine.server";
|
||||
|
||||
@@ -16,26 +16,7 @@ const SearchParamsSchema = z.object({
|
||||
});
|
||||
|
||||
export async function loader({ request, params }: LoaderFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const parsedParams = ParamsSchema.parse(params);
|
||||
|
||||
|
||||
+2
-21
@@ -1,7 +1,7 @@
|
||||
import { ActionFunctionArgs, json, LoaderFunctionArgs } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { scheduleEngine } from "~/v3/scheduleEngine.server";
|
||||
|
||||
const ParamsSchema = z.object({
|
||||
@@ -9,26 +9,7 @@ const ParamsSchema = z.object({
|
||||
});
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const parsedParams = ParamsSchema.parse(params);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ActionFunctionArgs, json, LoaderFunctionArgs } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { engine } from "~/v3/runEngine.server";
|
||||
import { updateEnvConcurrencyLimits } from "~/v3/runQueue.server";
|
||||
|
||||
@@ -15,26 +15,7 @@ const RequestBodySchema = z.object({
|
||||
});
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const parsedParams = ParamsSchema.parse(params);
|
||||
|
||||
@@ -71,26 +52,7 @@ const SearchParamsSchema = z.object({
|
||||
});
|
||||
|
||||
export async function loader({ request, params }: LoaderFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to get this endpoint" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const parsedParams = ParamsSchema.parse(params);
|
||||
|
||||
|
||||
@@ -1,30 +1,11 @@
|
||||
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { makeSetMultipleFlags } from "~/v3/featureFlags.server";
|
||||
import { validatePartialFeatureFlags } from "~/v3/featureFlags";
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
// Parse the request body
|
||||
|
||||
@@ -2,8 +2,7 @@ import { type DataFunctionArgs } from "@remix-run/node";
|
||||
import { PerformanceObserver } from "node:perf_hooks";
|
||||
import { runInNewContext } from "node:vm";
|
||||
import v8 from "v8";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
|
||||
async function waitTillGcFinishes() {
|
||||
let resolver: (value: PerformanceEntry) => void;
|
||||
@@ -36,21 +35,7 @@ async function waitTillGcFinishes() {
|
||||
}
|
||||
|
||||
export async function loader({ request }: DataFunctionArgs) {
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
throw new Response("You must be an admin to perform this action", { status: 403 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user?.admin) {
|
||||
throw new Response("You must be an admin to perform this action", { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const entry = await waitTillGcFinishes();
|
||||
|
||||
|
||||
@@ -1,24 +1,10 @@
|
||||
import { type ActionFunctionArgs, type LoaderFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
|
||||
async function requireAdmin(request: Request) {
|
||||
const authResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
if (!authResult) {
|
||||
throw json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: authResult.userId } });
|
||||
if (!user?.admin) {
|
||||
throw json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
|
||||
export async function loader({ request, params }: LoaderFunctionArgs) {
|
||||
await requireAdmin(request);
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const model = await prisma.llmModel.findUnique({
|
||||
where: { id: params.modelId },
|
||||
@@ -69,7 +55,7 @@ const UpdateModelSchema = z.object({
|
||||
});
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
await requireAdmin(request);
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const modelId = params.modelId!;
|
||||
|
||||
|
||||
@@ -1,24 +1,9 @@
|
||||
import { type LoaderFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { getMissingLlmModels } from "~/services/admin/missingLlmModels.server";
|
||||
|
||||
async function requireAdmin(request: Request) {
|
||||
const authResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
if (!authResult) {
|
||||
throw json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: authResult.userId } });
|
||||
if (!user?.admin) {
|
||||
throw json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
await requireAdmin(request);
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const url = new URL(request.url);
|
||||
const lookbackHours = parseInt(url.searchParams.get("lookbackHours") ?? "24", 10);
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { llmPricingRegistry } from "~/v3/llmPricingRegistry.server";
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
const authResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
if (!authResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: authResult.userId } });
|
||||
if (!user?.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
if (!llmPricingRegistry) {
|
||||
return json({ error: "LLM cost tracking is disabled" }, { status: 400 });
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { seedLlmPricing, syncLlmCatalog } from "@internal/llm-model-catalog";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { llmPricingRegistry } from "~/v3/llmPricingRegistry.server";
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
const authResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
if (!authResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: authResult.userId } });
|
||||
if (!user?.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const url = new URL(request.url);
|
||||
const action = url.searchParams.get("action") ?? "seed";
|
||||
|
||||
@@ -1,25 +1,11 @@
|
||||
import { type ActionFunctionArgs, type LoaderFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { generateFriendlyId } from "~/v3/friendlyIdentifiers";
|
||||
|
||||
async function requireAdmin(request: Request) {
|
||||
const authResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
if (!authResult) {
|
||||
throw json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({ where: { id: authResult.userId } });
|
||||
if (!user?.admin) {
|
||||
throw json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
await requireAdmin(request);
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const url = new URL(request.url);
|
||||
const page = parseInt(url.searchParams.get("page") ?? "1");
|
||||
@@ -75,7 +61,7 @@ const CreateModelSchema = z.object({
|
||||
});
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
await requireAdmin(request);
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
if (request.method !== "POST") {
|
||||
return json({ error: "Method not allowed" }, { status: 405 });
|
||||
|
||||
@@ -1,29 +1,9 @@
|
||||
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { engine } from "~/v3/runEngine.server";
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
await engine.migrateLegacyMasterQueues();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { marqs } from "~/v3/marqs/index.server";
|
||||
import { updateEnvConcurrencyLimits } from "~/v3/runQueue.server";
|
||||
|
||||
@@ -17,26 +17,7 @@ const RequestBodySchema = z.object({
|
||||
});
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const { organizationId } = ParamsSchema.parse(params);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { createEnvironment } from "~/models/organization.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { updateEnvConcurrencyLimits } from "~/v3/runQueue.server";
|
||||
|
||||
const ParamsSchema = z.object({
|
||||
@@ -19,26 +19,7 @@ const ParamsSchema = z.object({
|
||||
* It will create a staging environment for all the projects where there isn't one already
|
||||
*/
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const { organizationId } = ParamsSchema.parse(params);
|
||||
|
||||
|
||||
@@ -1,43 +1,15 @@
|
||||
import { ActionFunctionArgs, LoaderFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { validatePartialFeatureFlags } from "~/v3/featureFlags";
|
||||
|
||||
const ParamsSchema = z.object({
|
||||
organizationId: z.string(),
|
||||
});
|
||||
|
||||
async function authenticateAdmin(request: Request) {
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return { error: json({ error: "Invalid or Missing API key" }, { status: 401 }) };
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return { error: json({ error: "Invalid or Missing API key" }, { status: 401 }) };
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return { error: json({ error: "You must be an admin to perform this action" }, { status: 403 }) };
|
||||
}
|
||||
|
||||
return { user };
|
||||
}
|
||||
|
||||
export async function loader({ request, params }: LoaderFunctionArgs) {
|
||||
const authResult = await authenticateAdmin(request);
|
||||
|
||||
if ("error" in authResult) {
|
||||
return authResult.error;
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const { organizationId } = ParamsSchema.parse(params);
|
||||
|
||||
@@ -70,11 +42,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
|
||||
}
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
const authResult = await authenticateAdmin(request);
|
||||
|
||||
if ("error" in authResult) {
|
||||
return authResult.error;
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const { organizationId } = ParamsSchema.parse(params);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { createEnvironment } from "~/models/organization.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { updateEnvConcurrencyLimits } from "~/v3/runQueue.server";
|
||||
import { PauseEnvironmentService } from "~/v3/services/pauseEnvironment.server";
|
||||
|
||||
@@ -24,26 +24,7 @@ const BodySchema = z.object({
|
||||
* It will enabled/disable runs
|
||||
*/
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const { organizationId } = ParamsSchema.parse(params);
|
||||
const body = BodySchema.safeParse(await request.json());
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { err, ok, type Result } from "neverthrow";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { authenticateAdminRequest } from "~/services/personalAccessToken.server";
|
||||
import {
|
||||
createPlatformNotification,
|
||||
type CreatePlatformNotificationInput,
|
||||
@@ -11,24 +10,10 @@ type AdminUser = { id: string; admin: boolean };
|
||||
type AuthError = { status: number; message: string };
|
||||
|
||||
async function authenticateAdmin(request: Request): Promise<Result<AdminUser, AuthError>> {
|
||||
const authResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
if (!authResult) {
|
||||
return err({ status: 401, message: "Invalid or Missing API key" });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: authResult.userId },
|
||||
select: { id: true, admin: true },
|
||||
});
|
||||
|
||||
if (!user?.admin) {
|
||||
return err({
|
||||
status: user ? 403 : 401,
|
||||
message: user ? "You must be an admin to perform this action" : "Invalid or Missing API key",
|
||||
});
|
||||
}
|
||||
|
||||
return ok(user);
|
||||
const result = await authenticateAdminRequest(request);
|
||||
return result.ok
|
||||
? ok({ id: result.user.id, admin: result.user.admin })
|
||||
: err({ status: result.status, message: result.message });
|
||||
}
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { adminWorker } from "~/v3/services/adminWorker.server";
|
||||
|
||||
const Body = z.object({
|
||||
@@ -19,26 +18,7 @@ const DEFAULT_BATCH_SIZE = 500;
|
||||
const DEFAULT_DELAY_INTERVAL_MS = 1000;
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const { batchId } = Params.parse(params);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { adminWorker } from "~/v3/services/adminWorker.server";
|
||||
|
||||
const Params = z.object({
|
||||
@@ -9,26 +8,7 @@ const Params = z.object({
|
||||
});
|
||||
|
||||
export async function action({ request, params }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const { batchId } = Params.parse(params);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { type TaskRun } from "@trigger.dev/database";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { logger } from "~/services/logger.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { runsReplicationInstance } from "~/services/runsReplicationInstance.server";
|
||||
import { FINAL_RUN_STATUSES } from "~/v3/taskStatus";
|
||||
|
||||
@@ -14,26 +14,7 @@ const Body = z.object({
|
||||
const MAX_BATCH_SIZE = 50;
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
const body = await request.json();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { z } from "zod";
|
||||
import { ClickHouse } from "@internal/clickhouse";
|
||||
import { env } from "~/env.server";
|
||||
@@ -29,26 +28,7 @@ const CreateRunReplicationServiceParams = z.object({
|
||||
type CreateRunReplicationServiceParams = z.infer<typeof CreateRunReplicationServiceParams>;
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
const globalService = getRunsReplicationGlobal();
|
||||
|
||||
@@ -1,30 +1,10 @@
|
||||
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { getRunsReplicationGlobal } from "~/services/runsReplicationGlobal.server";
|
||||
import { runsReplicationInstance } from "~/services/runsReplicationInstance.server";
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
const globalService = getRunsReplicationGlobal();
|
||||
|
||||
@@ -1,30 +1,10 @@
|
||||
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { getRunsReplicationGlobal } from "~/services/runsReplicationGlobal.server";
|
||||
import { runsReplicationInstance } from "~/services/runsReplicationInstance.server";
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
const globalService = getRunsReplicationGlobal();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import {
|
||||
getRunsReplicationGlobal,
|
||||
unregisterRunsReplicationGlobal,
|
||||
@@ -8,26 +7,7 @@ import {
|
||||
import { runsReplicationInstance } from "~/services/runsReplicationInstance.server";
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
const globalService = getRunsReplicationGlobal();
|
||||
|
||||
@@ -4,8 +4,7 @@ import os from "os";
|
||||
import path from "path";
|
||||
import { PassThrough } from "stream";
|
||||
import v8 from "v8";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
|
||||
// Format date as yyyy-MM-dd HH_mm_ss_SSS
|
||||
function formatDate(date: Date) {
|
||||
@@ -25,21 +24,7 @@ function formatDate(date: Date) {
|
||||
}
|
||||
|
||||
export async function loader({ request }: DataFunctionArgs) {
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
throw new Response("You must be an admin to perform this action", { status: 403 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!user?.admin) {
|
||||
throw new Response("You must be an admin to perform this action", { status: 403 });
|
||||
}
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
const tempDir = os.tmpdir();
|
||||
const filepath = path.join(
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import { type ActionFunctionArgs, json } from "@remix-run/server-runtime";
|
||||
import {
|
||||
type ActionFunctionArgs,
|
||||
type LoaderFunctionArgs,
|
||||
json,
|
||||
} from "@remix-run/server-runtime";
|
||||
import { tryCatch } from "@trigger.dev/core";
|
||||
import { type Project } from "@trigger.dev/database";
|
||||
import { type Project, WorkerInstanceGroupType, WorkloadType } from "@trigger.dev/database";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
|
||||
import { requireAdminApiRequest } from "~/services/personalAccessToken.server";
|
||||
import { WorkerGroupService } from "~/v3/services/worker/workerGroupService.server";
|
||||
|
||||
const RequestBodySchema = z.object({
|
||||
@@ -12,34 +16,44 @@ const RequestBodySchema = z.object({
|
||||
projectId: z.string().optional(),
|
||||
makeDefaultForProject: z.boolean().default(false),
|
||||
removeDefaultFromProject: z.boolean().default(false),
|
||||
type: z.nativeEnum(WorkerInstanceGroupType).optional(),
|
||||
hidden: z.boolean().optional(),
|
||||
workloadType: z.nativeEnum(WorkloadType).optional(),
|
||||
cloudProvider: z.string().optional(),
|
||||
location: z.string().optional(),
|
||||
staticIPs: z.string().optional(),
|
||||
enableFastPath: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
// Next authenticate the request
|
||||
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
if (!authenticationResult) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: {
|
||||
id: authenticationResult.userId,
|
||||
},
|
||||
const workerGroups = await prisma.workerInstanceGroup.findMany({
|
||||
orderBy: { createdAt: "asc" },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: "Invalid or Missing API key" }, { status: 401 });
|
||||
}
|
||||
return json({ workerGroups });
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return json({ error: "You must be an admin to perform this action" }, { status: 403 });
|
||||
}
|
||||
export async function action({ request }: ActionFunctionArgs) {
|
||||
await requireAdminApiRequest(request);
|
||||
|
||||
try {
|
||||
const rawBody = await request.json();
|
||||
const { name, description, projectId, makeDefaultForProject, removeDefaultFromProject } =
|
||||
RequestBodySchema.parse(rawBody ?? {});
|
||||
const {
|
||||
name,
|
||||
description,
|
||||
projectId,
|
||||
makeDefaultForProject,
|
||||
removeDefaultFromProject,
|
||||
type,
|
||||
hidden,
|
||||
workloadType,
|
||||
cloudProvider,
|
||||
location,
|
||||
staticIPs,
|
||||
enableFastPath,
|
||||
} = RequestBodySchema.parse(rawBody ?? {});
|
||||
|
||||
if (removeDefaultFromProject) {
|
||||
if (!projectId) {
|
||||
@@ -74,7 +88,17 @@ export async function action({ request }: ActionFunctionArgs) {
|
||||
});
|
||||
|
||||
if (!existingWorkerGroup) {
|
||||
const { workerGroup, token } = await createWorkerGroup(name, description);
|
||||
const { workerGroup, token } = await createWorkerGroup({
|
||||
name,
|
||||
description,
|
||||
type,
|
||||
hidden,
|
||||
workloadType,
|
||||
cloudProvider,
|
||||
location,
|
||||
staticIPs,
|
||||
enableFastPath,
|
||||
});
|
||||
|
||||
if (!makeDefaultForProject) {
|
||||
return json({
|
||||
@@ -150,9 +174,11 @@ export async function action({ request }: ActionFunctionArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
async function createWorkerGroup(name: string | undefined, description: string | undefined) {
|
||||
async function createWorkerGroup(
|
||||
options: Parameters<WorkerGroupService["createWorkerGroup"]>[0]
|
||||
) {
|
||||
const service = new WorkerGroupService();
|
||||
return await service.createWorkerGroup({ name, description });
|
||||
return await service.createWorkerGroup(options);
|
||||
}
|
||||
|
||||
async function removeDefaultWorkerGroupFromProject(projectId: string) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type PersonalAccessToken } from "@trigger.dev/database";
|
||||
import { type PersonalAccessToken, type User } from "@trigger.dev/database";
|
||||
import { customAlphabet, nanoid } from "nanoid";
|
||||
import { z } from "zod";
|
||||
import { prisma } from "~/db.server";
|
||||
@@ -118,6 +118,59 @@ export async function authenticateApiRequestWithPersonalAccessToken(
|
||||
return authenticatePersonalAccessToken(token);
|
||||
}
|
||||
|
||||
export type AdminAuthenticationResult =
|
||||
| { ok: true; user: User }
|
||||
| { ok: false; status: 401 | 403; message: string };
|
||||
|
||||
/**
|
||||
* Authenticates a request via personal access token and checks the user is
|
||||
* an admin. Returns a discriminated result so callers can shape the failure
|
||||
* (throw a Response, wrap in neverthrow, return JSON, etc.) to fit their
|
||||
* context. See `requireAdminApiRequest` for the Remix loader/action wrapper.
|
||||
*/
|
||||
export async function authenticateAdminRequest(
|
||||
request: Request
|
||||
): Promise<AdminAuthenticationResult> {
|
||||
const authResult = await authenticateApiRequestWithPersonalAccessToken(request);
|
||||
|
||||
if (!authResult) {
|
||||
return { ok: false, status: 401, message: "Invalid or Missing API key" };
|
||||
}
|
||||
|
||||
const user = await prisma.user.findFirst({
|
||||
where: { id: authResult.userId },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return { ok: false, status: 401, message: "Invalid or Missing API key" };
|
||||
}
|
||||
|
||||
if (!user.admin) {
|
||||
return { ok: false, status: 403, message: "You must be an admin to perform this action" };
|
||||
}
|
||||
|
||||
return { ok: true, user };
|
||||
}
|
||||
|
||||
/**
|
||||
* Remix loader/action wrapper around `authenticateAdminRequest` that throws
|
||||
* a Response on failure so routes can `await` without handling the error
|
||||
* branch. Uses `new Response` directly to avoid coupling this module to
|
||||
* `@remix-run/server-runtime`.
|
||||
*/
|
||||
export async function requireAdminApiRequest(request: Request): Promise<User> {
|
||||
const result = await authenticateAdminRequest(request);
|
||||
|
||||
if (!result.ok) {
|
||||
throw new Response(JSON.stringify({ error: result.message }), {
|
||||
status: result.status,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
}
|
||||
|
||||
return result.user;
|
||||
}
|
||||
|
||||
function getPersonalAccessTokenFromRequest(request: Request) {
|
||||
const rawAuthorization = request.headers.get("Authorization");
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { WorkerInstanceGroup, WorkerInstanceGroupType } from "@trigger.dev/database";
|
||||
import { WorkerInstanceGroup, WorkerInstanceGroupType, WorkloadType } from "@trigger.dev/database";
|
||||
import { WithRunEngine } from "../baseService.server";
|
||||
import { WorkerGroupTokenService } from "./workerGroupTokenService.server";
|
||||
import { logger } from "~/services/logger.server";
|
||||
@@ -14,11 +14,25 @@ export class WorkerGroupService extends WithRunEngine {
|
||||
organizationId,
|
||||
name,
|
||||
description,
|
||||
type,
|
||||
hidden,
|
||||
workloadType,
|
||||
cloudProvider,
|
||||
location,
|
||||
staticIPs,
|
||||
enableFastPath,
|
||||
}: {
|
||||
projectId?: string;
|
||||
organizationId?: string;
|
||||
name?: string;
|
||||
description?: string;
|
||||
type?: WorkerInstanceGroupType;
|
||||
hidden?: boolean;
|
||||
workloadType?: WorkloadType;
|
||||
cloudProvider?: string;
|
||||
location?: string;
|
||||
staticIPs?: string;
|
||||
enableFastPath?: boolean;
|
||||
}) {
|
||||
if (!name) {
|
||||
name = await this.generateWorkerName({ projectId });
|
||||
@@ -30,15 +44,24 @@ export class WorkerGroupService extends WithRunEngine {
|
||||
});
|
||||
const token = await tokenService.createToken();
|
||||
|
||||
const resolvedType =
|
||||
type ?? (projectId ? WorkerInstanceGroupType.UNMANAGED : WorkerInstanceGroupType.MANAGED);
|
||||
|
||||
const workerGroup = await this._prisma.workerInstanceGroup.create({
|
||||
data: {
|
||||
projectId,
|
||||
organizationId,
|
||||
type: projectId ? WorkerInstanceGroupType.UNMANAGED : WorkerInstanceGroupType.MANAGED,
|
||||
type: resolvedType,
|
||||
masterQueue: this.generateMasterQueueName({ projectId, name }),
|
||||
tokenId: token.id,
|
||||
description,
|
||||
name,
|
||||
hidden,
|
||||
workloadType,
|
||||
cloudProvider,
|
||||
location,
|
||||
staticIPs,
|
||||
enableFastPath,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user