mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-21 10:08:34 -06:00
chore: API key types (#4610)
Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { type ApiKey } from "@prisma/client";
|
||||
import { z } from "zod";
|
||||
|
||||
export const ZApiKey = z.object({
|
||||
@@ -7,12 +8,4 @@ export const ZApiKey = z.object({
|
||||
label: z.string().nullable(),
|
||||
hashedKey: z.string(),
|
||||
environmentId: z.string().cuid2(),
|
||||
apiKey: z.string().optional(),
|
||||
});
|
||||
|
||||
export type TApiKey = z.infer<typeof ZApiKey>;
|
||||
|
||||
export const ZApiKeyCreateInput = z.object({
|
||||
label: z.string(),
|
||||
});
|
||||
export type TApiKeyCreateInput = z.infer<typeof ZApiKeyCreateInput>;
|
||||
}) satisfies z.ZodType<ApiKey>;
|
||||
@@ -1,29 +0,0 @@
|
||||
import "server-only";
|
||||
import { ZId } from "@formbricks/types/common";
|
||||
import { cache } from "../cache";
|
||||
import { hasUserEnvironmentAccess } from "../environment/auth";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { apiKeyCache } from "./cache";
|
||||
import { getApiKey } from "./service";
|
||||
|
||||
export const canUserAccessApiKey = (userId: string, apiKeyId: string): Promise<boolean> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([userId, ZId], [apiKeyId, ZId]);
|
||||
|
||||
try {
|
||||
const apiKeyFromServer = await getApiKey(apiKeyId);
|
||||
if (!apiKeyFromServer) return false;
|
||||
|
||||
const hasAccessToEnvironment = await hasUserEnvironmentAccess(userId, apiKeyFromServer.environmentId);
|
||||
if (!hasAccessToEnvironment) return false;
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
[`canUserAccessApiKey-${userId}-${apiKeyId}`],
|
||||
{ tags: [apiKeyCache.tag.byId(apiKeyId)] }
|
||||
)();
|
||||
@@ -1,34 +0,0 @@
|
||||
import { revalidateTag } from "next/cache";
|
||||
|
||||
interface RevalidateProps {
|
||||
id?: string;
|
||||
environmentId?: string;
|
||||
hashedKey?: string;
|
||||
}
|
||||
|
||||
export const apiKeyCache = {
|
||||
tag: {
|
||||
byId(id: string) {
|
||||
return `apiKeys-${id}`;
|
||||
},
|
||||
byEnvironmentId(environmentId: string) {
|
||||
return `environments-${environmentId}-apiKeys`;
|
||||
},
|
||||
byHashedKey(hashedKey: string) {
|
||||
return `apiKeys-${hashedKey}-apiKey`;
|
||||
},
|
||||
},
|
||||
revalidate({ id, environmentId, hashedKey }: RevalidateProps): void {
|
||||
if (id) {
|
||||
revalidateTag(this.tag.byId(id));
|
||||
}
|
||||
|
||||
if (environmentId) {
|
||||
revalidateTag(this.tag.byEnvironmentId(environmentId));
|
||||
}
|
||||
|
||||
if (hashedKey) {
|
||||
revalidateTag(this.tag.byHashedKey(hashedKey));
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -1,109 +0,0 @@
|
||||
import "server-only";
|
||||
import { Prisma } from "@prisma/client";
|
||||
import { cache as reactCache } from "react";
|
||||
import { prisma } from "@formbricks/database";
|
||||
import { TApiKey } from "@formbricks/types/api-keys";
|
||||
import { ZOptionalNumber, ZString } from "@formbricks/types/common";
|
||||
import { ZId } from "@formbricks/types/common";
|
||||
import { DatabaseError, InvalidInputError } from "@formbricks/types/errors";
|
||||
import { cache } from "../cache";
|
||||
import { ITEMS_PER_PAGE } from "../constants";
|
||||
import { getHash } from "../crypto";
|
||||
import { validateInputs } from "../utils/validate";
|
||||
import { apiKeyCache } from "./cache";
|
||||
|
||||
export const getApiKey = reactCache(
|
||||
async (apiKeyId: string): Promise<TApiKey | null> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([apiKeyId, ZString]);
|
||||
|
||||
if (!apiKeyId) {
|
||||
throw new InvalidInputError("API key cannot be null or undefined.");
|
||||
}
|
||||
|
||||
try {
|
||||
const apiKeyData = await prisma.apiKey.findUnique({
|
||||
where: {
|
||||
id: apiKeyId,
|
||||
},
|
||||
});
|
||||
|
||||
return apiKeyData;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[`getApiKey-${apiKeyId}`],
|
||||
{
|
||||
tags: [apiKeyCache.tag.byId(apiKeyId)],
|
||||
}
|
||||
)()
|
||||
);
|
||||
|
||||
export const getApiKeys = reactCache(
|
||||
async (environmentId: string, page?: number): Promise<TApiKey[]> =>
|
||||
cache(
|
||||
async () => {
|
||||
validateInputs([environmentId, ZId], [page, ZOptionalNumber]);
|
||||
|
||||
try {
|
||||
const apiKeys = await prisma.apiKey.findMany({
|
||||
where: {
|
||||
environmentId,
|
||||
},
|
||||
take: page ? ITEMS_PER_PAGE : undefined,
|
||||
skip: page ? ITEMS_PER_PAGE * (page - 1) : undefined,
|
||||
});
|
||||
|
||||
return apiKeys;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[`getApiKeys-${environmentId}-${page}`],
|
||||
{
|
||||
tags: [apiKeyCache.tag.byEnvironmentId(environmentId)],
|
||||
}
|
||||
)()
|
||||
);
|
||||
|
||||
export const getApiKeyFromKey = reactCache(async (apiKey: string): Promise<TApiKey | null> => {
|
||||
const hashedKey = getHash(apiKey);
|
||||
return cache(
|
||||
async () => {
|
||||
validateInputs([apiKey, ZString]);
|
||||
|
||||
if (!apiKey) {
|
||||
throw new InvalidInputError("API key cannot be null or undefined.");
|
||||
}
|
||||
|
||||
try {
|
||||
const apiKeyData = await prisma.apiKey.findUnique({
|
||||
where: {
|
||||
hashedKey,
|
||||
},
|
||||
});
|
||||
|
||||
return apiKeyData;
|
||||
} catch (error) {
|
||||
if (error instanceof Prisma.PrismaClientKnownRequestError) {
|
||||
throw new DatabaseError(error.message);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[`getApiKeyFromKey-${apiKey}`],
|
||||
{
|
||||
tags: [apiKeyCache.tag.byHashedKey(hashedKey)],
|
||||
}
|
||||
)();
|
||||
});
|
||||
@@ -18,6 +18,7 @@
|
||||
".",
|
||||
"../types/*.d.ts",
|
||||
"../../apps/web/lib/cache/contact-attribute-key.ts",
|
||||
"../../apps/web/modules/utils/hooks"
|
||||
"../../apps/web/modules/utils/hooks",
|
||||
"../../apps/web/lib/cache/api-key.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { z } from "zod";
|
||||
import { ZId } from "./common";
|
||||
|
||||
export const ZContact = z.object({
|
||||
id: ZId,
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
environmentId: ZId,
|
||||
});
|
||||
|
||||
export type TContact = z.infer<typeof ZContact>;
|
||||
@@ -20,12 +20,6 @@ export const ZDisplayCreateInput = z.object({
|
||||
|
||||
export type TDisplayCreateInput = z.infer<typeof ZDisplayCreateInput>;
|
||||
|
||||
export const ZDisplaysWithSurveyName = ZDisplay.extend({
|
||||
surveyName: z.string(),
|
||||
});
|
||||
|
||||
export type TDisplaysWithSurveyName = z.infer<typeof ZDisplaysWithSurveyName>;
|
||||
|
||||
export const ZDisplayFilters = z.object({
|
||||
createdAt: z
|
||||
.object({
|
||||
|
||||
Reference in New Issue
Block a user