calcom/apps/web/components/security/ChangePasswordSection.tsx
Agusti Fernandez faa67e0bb6
Feature: Adds api keys to cal.com webapp (#2277)
* feat: add ApiKey model for new Api auth, owned by a user

* fix: remove metadata:Json and add note:String instead in new apiKey model

* fix: rename apiKey to apiKeys in moder User relation in schema.prisma

* feat: add hashedKey to apiKey and lastUsedAt datetime to keep track of usage of keys and makiung them securely stored in db

* fix 30 day -> 30 days in expiresAt

* feat: api keys frontend in security page

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

* Make frontend work to create api keys with or without expiry, note, defaults to 1 month expiry

* remove migration for now, add env.example to swagger, sync api

* feat: hashed api keys

* fix: minor refactor and cleanup in apiKeys generator

* add api key success modal

* sync apps/api

* feat: We have API Keys in Security =)

* remove swagger env from pr

* apps api sync

* remove comments in password section

* feat: migration for api keys schema

* sync api w main

* delete apps/api

* add back apps/api

* make min date and disabled optional props in datepicker

* feat fix type check errors

* fix : types

* fix: rmeove renaming of verificationrequest token indexes in migration

* fix: remove extra div

* Fixes for feedback in PR

* fix button />

* fix: rename weird naming of translation for you_will_only_view_it_once

* fix: remove ternary and use && to avoid null for false

* fix sync apps/api with main not old commit

* fix empty className

* fix: remove unused imports

* fix remove commented jsx fragment close

* fix rename editing

* improve translations

* feat: adds beta tag in security tab under api keys

* fix: use api keys everywhere

* fix: cleanup code in api keys

* fix: use watch and controller for neverexpires/datepicker

* Fixes: improve api key never expires

* add back change password h2 title section in security page

* fix update env API_KEY_ prefix default to cal_

* fix: improve eidt api keys modal

* fix: update edit mutation in viewer.apiKeys

* Update apps/web/ee/components/apiKeys/ApiKeyListItem.tsx

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* fix: item: any to pass build

Co-authored-by: Agusti Fernandez Pardo <git@agusti.me>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2022-04-15 20:58:34 -06:00

112 lines
3.8 KiB
TypeScript

import React, { SyntheticEvent, useState } from "react";
import showToast from "@calcom/lib/notification";
import Button from "@calcom/ui/Button";
import { ErrorCode } from "@lib/auth";
import { useLocale } from "@lib/hooks/useLocale";
const ChangePasswordSection = () => {
const [oldPassword, setOldPassword] = useState("");
const [newPassword, setNewPassword] = useState("");
const [errorMessage, setErrorMessage] = useState<string | null>(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const { t } = useLocale();
const errorMessages: { [key: string]: string } = {
[ErrorCode.IncorrectPassword]: t("current_incorrect_password"),
[ErrorCode.NewPasswordMatchesOld]: t("new_password_matches_old_password"),
};
async function changePasswordHandler(e: SyntheticEvent) {
e.preventDefault();
if (isSubmitting) {
return;
}
setIsSubmitting(true);
setErrorMessage(null);
try {
const response = await fetch("/api/auth/changepw", {
method: "PATCH",
body: JSON.stringify({ oldPassword, newPassword }),
headers: {
"Content-Type": "application/json",
},
});
if (response.status === 200) {
setOldPassword("");
setNewPassword("");
showToast(t("password_has_been_changed"), "success");
return;
}
const body = await response.json();
setErrorMessage(errorMessages[body.error] || `${t("something_went_wrong")}${t("please_try_again")}`);
} catch (err) {
console.error(t("error_changing_password"), err);
setErrorMessage(`${t("something_went_wrong")}${t("please_try_again")}`);
} finally {
setIsSubmitting(false);
}
}
return (
<>
<form className="divide-y divide-gray-200 lg:col-span-9" onSubmit={changePasswordHandler}>
<div className="py-6 lg:pb-5">
<div className="my-3">
<h2 className="font-cal text-lg font-medium leading-6 text-gray-900">{t("change_password")}</h2>
</div>
<div className="flex">
<div className="w-1/2 ltr:mr-2 rtl:ml-2">
<label htmlFor="current_password" className="block text-sm font-medium text-gray-700">
{t("current_password")}
</label>
<div className="mt-1">
<input
type="password"
value={oldPassword}
onInput={(e) => setOldPassword(e.currentTarget.value)}
name="current_password"
id="current_password"
required
className="block w-full rounded-sm border-gray-300 shadow-sm sm:text-sm"
placeholder={t("your_old_password")}
/>
</div>
</div>
<div className="ml-2 w-1/2">
<label htmlFor="new_password" className="block text-sm font-medium text-gray-700">
{t("new_password")}
</label>
<div className="mt-1">
<input
type="password"
name="new_password"
id="new_password"
value={newPassword}
required
onInput={(e) => setNewPassword(e.currentTarget.value)}
className="block w-full rounded-sm border-gray-300 shadow-sm sm:text-sm"
placeholder={t("super_secure_new_password")}
/>
</div>
</div>
</div>
{errorMessage && <p className="mt-1 text-sm text-red-700">{errorMessage}</p>}
<div className="flex justify-end py-8">
<Button color="secondary" type="submit">
{t("save")}
</Button>
</div>
</div>
</form>
</>
);
};
export default ChangePasswordSection;