adds hashedKey to api key model, add frontend api keys in security page

pull/2277/head
Agusti Fernandez Pardo 2022-04-07 21:57:41 +02:00
parent c2cd32995d
commit d0af8bc57c
3 changed files with 45 additions and 19 deletions

View File

@ -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}

View File

@ -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", {

View File

@ -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;
}