Skip to content

Commit b0d12cc

Browse files
committed
Adding docs and support for using both API keys and PATs when interacting with the env var endpoints
1 parent b738d06 commit b0d12cc

19 files changed

+1451
-1232
lines changed

apps/webapp/app/presenters/v3/EnvironmentVariablesPresenter.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class EnvironmentVariablesPresenter {
8787
);
8888

8989
const repository = new EnvironmentVariablesRepository(this.#prismaClient);
90-
const variables = await repository.getProject(project.id, userId);
90+
const variables = await repository.getProject(project.id);
9191

9292
return {
9393
environmentVariables: environmentVariables.map((environmentVariable) => {

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.environment-variables.new/route.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
115115
const project = await prisma.project.findUnique({
116116
where: {
117117
slug: params.projectParam,
118+
organization: {
119+
members: {
120+
some: {
121+
userId,
122+
},
123+
},
124+
},
118125
},
119126
select: {
120127
id: true,
@@ -126,7 +133,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
126133
}
127134

128135
const repository = new EnvironmentVariablesRepository(prisma);
129-
const result = await repository.create(project.id, userId, submission.value);
136+
const result = await repository.create(project.id, submission.value);
130137

131138
if (!result.success) {
132139
if (result.variableErrors) {

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.v3.$projectParam.environment-variables/route.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
106106
const project = await prisma.project.findUnique({
107107
where: {
108108
slug: params.projectParam,
109+
organization: {
110+
members: {
111+
some: {
112+
userId,
113+
},
114+
},
115+
},
109116
},
110117
select: {
111118
id: true,
@@ -119,7 +126,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
119126
switch (submission.value.action) {
120127
case "edit": {
121128
const repository = new EnvironmentVariablesRepository(prisma);
122-
const result = await repository.edit(project.id, userId, submission.value);
129+
const result = await repository.edit(project.id, submission.value);
123130

124131
if (!result.success) {
125132
submission.error.key = result.error;
@@ -138,7 +145,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
138145
}
139146
case "delete": {
140147
const repository = new EnvironmentVariablesRepository(prisma);
141-
const result = await repository.delete(project.id, userId, submission.value);
148+
const result = await repository.delete(project.id, submission.value);
142149

143150
if (!result.success) {
144151
submission.error.key = result.error;

apps/webapp/app/routes/api.v1.projects.$projectRef.envvars.$slug.$name.ts

Lines changed: 21 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import { ActionFunctionArgs, LoaderFunctionArgs, json } from "@remix-run/server-
22
import { UpdateEnvironmentVariableRequestBody } from "@trigger.dev/core/v3";
33
import { z } from "zod";
44
import { prisma } from "~/db.server";
5-
import { findProjectByRef } from "~/models/project.server";
6-
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
5+
import {
6+
authenticateProjectApiKeyOrPersonalAccessToken,
7+
authenticatedEnvironmentForAuthentication,
8+
} from "~/services/apiAuth.server";
79
import { EnvironmentVariablesRepository } from "~/v3/environmentVariables/environmentVariablesRepository.server";
810

911
const ParamsSchema = z.object({
@@ -19,44 +21,23 @@ export async function action({ params, request }: ActionFunctionArgs) {
1921
return json({ error: "Invalid params" }, { status: 400 });
2022
}
2123

22-
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
24+
const authenticationResult = await authenticateProjectApiKeyOrPersonalAccessToken(request);
2325

2426
if (!authenticationResult) {
2527
return json({ error: "Invalid or Missing API key" }, { status: 401 });
2628
}
2729

28-
const user = await prisma.user.findUnique({
29-
where: {
30-
id: authenticationResult.userId,
31-
},
32-
});
33-
34-
if (!user) {
35-
return json({ error: "Invalid or Missing API key" }, { status: 401 });
36-
}
37-
38-
const project = await findProjectByRef(parsedParams.data.projectRef, user.id);
39-
40-
if (!project) {
41-
return json({ error: "Project not found" }, { status: 404 });
42-
}
43-
44-
const environment = await prisma.runtimeEnvironment.findFirst({
45-
where: {
46-
projectId: project.id,
47-
slug: parsedParams.data.slug,
48-
},
49-
});
50-
51-
if (!environment) {
52-
return json({ error: "Environment not found" }, { status: 404 });
53-
}
30+
const environment = await authenticatedEnvironmentForAuthentication(
31+
authenticationResult,
32+
parsedParams.data.projectRef,
33+
parsedParams.data.slug
34+
);
5435

5536
// Find the environment variable
5637
const variable = await prisma.environmentVariable.findFirst({
5738
where: {
5839
key: parsedParams.data.name,
59-
projectId: project.id,
40+
projectId: environment.project.id,
6041
},
6142
});
6243

@@ -68,7 +49,7 @@ export async function action({ params, request }: ActionFunctionArgs) {
6849

6950
switch (request.method.toUpperCase()) {
7051
case "DELETE": {
71-
const result = await repository.deleteValue(project.id, user.id, {
52+
const result = await repository.deleteValue(environment.project.id, {
7253
id: variable.id,
7354
environmentId: environment.id,
7455
});
@@ -89,7 +70,7 @@ export async function action({ params, request }: ActionFunctionArgs) {
8970
return json({ error: "Invalid request body", issues: body.error.issues }, { status: 400 });
9071
}
9172

92-
const result = await repository.edit(project.id, user.id, {
73+
const result = await repository.edit(environment.project.id, {
9374
values: [
9475
{
9576
value: body.data.value,
@@ -116,44 +97,23 @@ export async function loader({ params, request }: LoaderFunctionArgs) {
11697
return json({ error: "Invalid params" }, { status: 400 });
11798
}
11899

119-
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
100+
const authenticationResult = await authenticateProjectApiKeyOrPersonalAccessToken(request);
120101

121102
if (!authenticationResult) {
122103
return json({ error: "Invalid or Missing API key" }, { status: 401 });
123104
}
124105

125-
const user = await prisma.user.findUnique({
126-
where: {
127-
id: authenticationResult.userId,
128-
},
129-
});
130-
131-
if (!user) {
132-
return json({ error: "Invalid or Missing API key" }, { status: 401 });
133-
}
134-
135-
const project = await findProjectByRef(parsedParams.data.projectRef, user.id);
136-
137-
if (!project) {
138-
return json({ error: "Project not found" }, { status: 404 });
139-
}
140-
141-
const environment = await prisma.runtimeEnvironment.findFirst({
142-
where: {
143-
projectId: project.id,
144-
slug: parsedParams.data.slug,
145-
},
146-
});
147-
148-
if (!environment) {
149-
return json({ error: "Environment not found" }, { status: 404 });
150-
}
106+
const environment = await authenticatedEnvironmentForAuthentication(
107+
authenticationResult,
108+
parsedParams.data.projectRef,
109+
parsedParams.data.slug
110+
);
151111

152112
// Find the environment variable
153113
const variable = await prisma.environmentVariable.findFirst({
154114
where: {
155115
key: parsedParams.data.name,
156-
projectId: project.id,
116+
projectId: environment.project.id,
157117
},
158118
});
159119

@@ -163,7 +123,7 @@ export async function loader({ params, request }: LoaderFunctionArgs) {
163123

164124
const repository = new EnvironmentVariablesRepository();
165125

166-
const variables = await repository.getEnvironment(project.id, user.id, environment.id, true);
126+
const variables = await repository.getEnvironment(environment.project.id, environment.id, true);
167127

168128
const environmentVariable = variables.find((v) => v.key === parsedParams.data.name);
169129

apps/webapp/app/routes/api.v1.projects.$projectRef.envvars.$slug.import.ts

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import { ActionFunctionArgs, json } from "@remix-run/server-runtime";
22
import { ImportEnvironmentVariablesRequestBody } from "@trigger.dev/core/v3";
33
import { parse } from "dotenv";
44
import { z } from "zod";
5-
import { prisma } from "~/db.server";
6-
import { findProjectByRef } from "~/models/project.server";
7-
import { authenticateApiRequestWithPersonalAccessToken } from "~/services/personalAccessToken.server";
5+
import {
6+
authenticateProjectApiKeyOrPersonalAccessToken,
7+
authenticatedEnvironmentForAuthentication,
8+
} from "~/services/apiAuth.server";
89
import { EnvironmentVariablesRepository } from "~/v3/environmentVariables/environmentVariablesRepository.server";
910

1011
const ParamsSchema = z.object({
@@ -19,44 +20,23 @@ export async function action({ params, request }: ActionFunctionArgs) {
1920
return json({ error: "Invalid params" }, { status: 400 });
2021
}
2122

22-
const authenticationResult = await authenticateApiRequestWithPersonalAccessToken(request);
23+
const authenticationResult = await authenticateProjectApiKeyOrPersonalAccessToken(request);
2324

2425
if (!authenticationResult) {
2526
return json({ error: "Invalid or Missing API key" }, { status: 401 });
2627
}
2728

28-
const user = await prisma.user.findUnique({
29-
where: {
30-
id: authenticationResult.userId,
31-
},
32-
});
33-
34-
if (!user) {
35-
return json({ error: "Invalid or Missing API key" }, { status: 401 });
36-
}
37-
38-
const project = await findProjectByRef(parsedParams.data.projectRef, user.id);
39-
40-
if (!project) {
41-
return json({ error: "Project not found" }, { status: 404 });
42-
}
43-
44-
const environment = await prisma.runtimeEnvironment.findFirst({
45-
where: {
46-
projectId: project.id,
47-
slug: parsedParams.data.slug,
48-
},
49-
});
50-
51-
if (!environment) {
52-
return json({ error: "Environment not found" }, { status: 404 });
53-
}
29+
const environment = await authenticatedEnvironmentForAuthentication(
30+
authenticationResult,
31+
parsedParams.data.projectRef,
32+
parsedParams.data.slug
33+
);
5434

5535
const repository = new EnvironmentVariablesRepository();
5636

5737
const body = await parseImportBody(request);
5838

59-
const result = await repository.create(project.id, user.id, {
39+
const result = await repository.create(environment.project.id, {
6040
overwrite: body.overwrite === true ? true : false,
6141
environmentIds: [environment.id],
6242
variables: Object.entries(body.variables).map(([key, value]) => ({
@@ -75,15 +55,21 @@ export async function action({ params, request }: ActionFunctionArgs) {
7555
async function parseImportBody(request: Request): Promise<ImportEnvironmentVariablesRequestBody> {
7656
const contentType = request.headers.get("content-type") ?? "application/json";
7757

78-
if (contentType.includes("application/octet-stream")) {
79-
// We have a "dotenv" formatted file uploaded
80-
const buffer = await request.arrayBuffer();
58+
if (contentType.includes("multipart/form-data")) {
59+
const formData = await request.formData();
60+
61+
const file = formData.get("file");
62+
const overwrite = formData.get("overwrite") === "true";
8163

82-
const variables = parse(Buffer.from(buffer));
64+
if (file instanceof File) {
65+
const buffer = await file.arrayBuffer();
8366

84-
const overwrite = request.headers.get("x-overwrite") === "true";
67+
const variables = parse(Buffer.from(buffer));
8568

86-
return { variables, overwrite };
69+
return { variables, overwrite };
70+
} else {
71+
throw json({ error: "Invalid file" }, { status: 400 });
72+
}
8773
} else {
8874
const rawBody = await request.json();
8975

0 commit comments

Comments
 (0)