adds hashedKey to api key model, add frontend api keys in security page
parent
c2cd32995d
commit
d0af8bc57c
|
@ -48,15 +48,9 @@ export default function ApiKeyDialogForm(props: { defaultValues?: TApiKeys; hand
|
|||
data-testid="ApiKeyDialogForm"
|
||||
form={form}
|
||||
handleSubmit={async (event) => {
|
||||
if (event.id) {
|
||||
await utils.client.mutation("viewer.apiKeys.edit", event);
|
||||
await utils.invalidateQueries(["viewer.apiKeys.list"]);
|
||||
showToast(t("apiKeys_updated_successfully"), "success");
|
||||
} else {
|
||||
await utils.client.mutation("viewer.apiKeys.create", e);
|
||||
await utils.invalidateQueries(["viewer.apiKeys.list"]);
|
||||
showToast(t("apiKeys_created_successfully"), "success");
|
||||
}
|
||||
await utils.client.mutation("viewer.apiKeys.create", event);
|
||||
await utils.invalidateQueries(["viewer.apiKeys.list"]);
|
||||
showToast(t("apiKeys_created_successfully"), "success");
|
||||
props.handleClose();
|
||||
}}
|
||||
className="space-y-4">
|
||||
|
@ -73,7 +67,7 @@ export default function ApiKeyDialogForm(props: { defaultValues?: TApiKeys; hand
|
|||
<div className="flex flex-col">
|
||||
<div className="flex justify-between py-2">
|
||||
<span className="text-md text-gray-600">Expire date</span>
|
||||
<Switch label={"Never expire"} onCheckedChange={onNeverExpired} checked={neverExpired} />
|
||||
{/* <Switch label={"Never expire"} onCheckedChange={onNeverExpired} checked={neverExpired} />
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="neverExpires"
|
||||
|
@ -86,11 +80,11 @@ export default function ApiKeyDialogForm(props: { defaultValues?: TApiKeys; hand
|
|||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
/> */}
|
||||
</div>
|
||||
<DatePicker
|
||||
// disabled={neverExpired}
|
||||
minDate={new Date()}
|
||||
// minDate={new Date()}
|
||||
// {...form.register("expiresAt")}
|
||||
date={selectedDate as Date}
|
||||
onDatesChange={handleDateChange}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { v4 } from "uuid";
|
||||
import { z } from "zod";
|
||||
|
||||
import { generateUniqueAPIKey } from "@calcom/ee/lib/api/apiKeys";
|
||||
import { getErrorFromUnknown } from "@calcom/lib/errors";
|
||||
|
||||
// import { WEBHOOK_TRIGGER_EVENTS } from "@lib/apiKeys/constants";
|
||||
|
@ -27,13 +28,20 @@ export const apiKeysRouter = createProtectedRouter()
|
|||
expiresAt: z.date().optional(),
|
||||
}),
|
||||
async resolve({ ctx, input }) {
|
||||
return await ctx.prisma.apiKey.create({
|
||||
data: {
|
||||
id: v4(),
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
},
|
||||
});
|
||||
const [hashedApiKey, apiKey] = generateUniqueAPIKey();
|
||||
await ctx.prisma.apiKey
|
||||
.create({
|
||||
data: {
|
||||
id: v4(),
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
hashedKey: hashedApiKey,
|
||||
},
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
return apiKey;
|
||||
},
|
||||
})
|
||||
.mutation("edit", {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { randomBytes } from "crypto";
|
||||
|
||||
import prisma from "@calcom/prisma";
|
||||
|
||||
export function generateUniqueAPIKey() {
|
||||
const apiKey = randomBytes(16).toString("hex");
|
||||
const hashedAPIKey = hashAPIKey(apiKey);
|
||||
// const exists = await prisma.apiKey.findMany({ where: { hashedKey: hashedAPIKey } });
|
||||
// Ensure API key is unique done at db level
|
||||
// if (!exists) {
|
||||
// generateUniqueAPIKey();
|
||||
// } else {
|
||||
return [hashedAPIKey, apiKey];
|
||||
// }
|
||||
}
|
||||
|
||||
// Hash the API key
|
||||
export function hashAPIKey(apiKey: string): string {
|
||||
const { createHash } = require("crypto");
|
||||
|
||||
const hashedAPIKey = createHash("sha256").update(apiKey).digest("hex");
|
||||
|
||||
return hashedAPIKey;
|
||||
}
|
Loading…
Reference in New Issue