mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🔑 feat: infinite key expiry (#3252)
This commit is contained in:
parent
1aad315de6
commit
1edbfdbce2
4 changed files with 37 additions and 23 deletions
|
|
@ -93,7 +93,7 @@ const getUserKeyExpiry = async ({ userId, name }) => {
|
||||||
if (!keyValue) {
|
if (!keyValue) {
|
||||||
return { expiresAt: null };
|
return { expiresAt: null };
|
||||||
}
|
}
|
||||||
return { expiresAt: keyValue.expiresAt };
|
return { expiresAt: keyValue.expiresAt || 'never' };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -108,18 +108,23 @@ const getUserKeyExpiry = async ({ userId, name }) => {
|
||||||
* @description This function either updates an existing user key or inserts a new one into the database,
|
* @description This function either updates an existing user key or inserts a new one into the database,
|
||||||
* after encrypting the provided value. It sets the provided expiry date for the key.
|
* after encrypting the provided value. It sets the provided expiry date for the key.
|
||||||
*/
|
*/
|
||||||
const updateUserKey = async ({ userId, name, value, expiresAt }) => {
|
const updateUserKey = async ({ userId, name, value, expiresAt = null }) => {
|
||||||
const encryptedValue = encrypt(value);
|
const encryptedValue = encrypt(value);
|
||||||
return await Key.findOneAndUpdate(
|
let updateObject = {
|
||||||
{ userId, name },
|
userId,
|
||||||
{
|
name,
|
||||||
userId,
|
value: encryptedValue,
|
||||||
name,
|
};
|
||||||
value: encryptedValue,
|
|
||||||
expiresAt: new Date(expiresAt),
|
// Only add expiresAt to the update object if it's not null
|
||||||
},
|
if (expiresAt) {
|
||||||
{ upsert: true, new: true },
|
updateObject.expiresAt = new Date(expiresAt);
|
||||||
).lean();
|
}
|
||||||
|
|
||||||
|
return await Key.findOneAndUpdate({ userId, name }, updateObject, {
|
||||||
|
upsert: true,
|
||||||
|
new: true,
|
||||||
|
}).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ const EXPIRY = {
|
||||||
ONE_DAY: { display: 'in 1 day', value: 24 * 60 * 60 * 1000 },
|
ONE_DAY: { display: 'in 1 day', value: 24 * 60 * 60 * 1000 },
|
||||||
ONE_WEEK: { display: 'in 7 days', value: 7 * 24 * 60 * 60 * 1000 },
|
ONE_WEEK: { display: 'in 7 days', value: 7 * 24 * 60 * 60 * 1000 },
|
||||||
ONE_MONTH: { display: 'in 30 days', value: 30 * 24 * 60 * 60 * 1000 },
|
ONE_MONTH: { display: 'in 30 days', value: 30 * 24 * 60 * 60 * 1000 },
|
||||||
|
NEVER: { display: 'never', value: 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const SetKeyDialog = ({
|
const SetKeyDialog = ({
|
||||||
|
|
@ -84,7 +85,13 @@ const SetKeyDialog = ({
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
const selectedOption = expirationOptions.find((option) => option.display === expiresAtLabel);
|
const selectedOption = expirationOptions.find((option) => option.display === expiresAtLabel);
|
||||||
const expiresAt = Date.now() + (selectedOption ? selectedOption.value : 0);
|
let expiresAt;
|
||||||
|
|
||||||
|
if (selectedOption?.value === 0) {
|
||||||
|
expiresAt = null;
|
||||||
|
} else {
|
||||||
|
expiresAt = Date.now() + (selectedOption ? selectedOption.value : 0);
|
||||||
|
}
|
||||||
|
|
||||||
const saveKey = (key: string) => {
|
const saveKey = (key: string) => {
|
||||||
saveUserKey(key, expiresAt);
|
saveUserKey(key, expiresAt);
|
||||||
|
|
@ -160,12 +167,12 @@ const SetKeyDialog = ({
|
||||||
main={
|
main={
|
||||||
<div className="grid w-full items-center gap-2">
|
<div className="grid w-full items-center gap-2">
|
||||||
<small className="text-red-600">
|
<small className="text-red-600">
|
||||||
{`${localize('com_endpoint_config_key_encryption')} ${
|
{expiryTime === 'never'
|
||||||
!expiryTime
|
? localize('com_endpoint_config_key_never_expires')
|
||||||
? localize('com_endpoint_config_key_expiry')
|
: `${localize('com_endpoint_config_key_encryption')} ${new Date(
|
||||||
: `${new Date(expiryTime).toLocaleString()}`
|
expiryTime,
|
||||||
}`}
|
).toLocaleString()}`}
|
||||||
</small>
|
</small>{' '}
|
||||||
<Dropdown
|
<Dropdown
|
||||||
label="Expires "
|
label="Expires "
|
||||||
value={expiresAtLabel}
|
value={expiresAtLabel}
|
||||||
|
|
|
||||||
|
|
@ -21,16 +21,17 @@ const useUserKey = (endpoint: string) => {
|
||||||
|
|
||||||
const updateKey = useUpdateUserKeysMutation();
|
const updateKey = useUpdateUserKeysMutation();
|
||||||
const checkUserKey = useUserKeyQuery(keyName);
|
const checkUserKey = useUserKeyQuery(keyName);
|
||||||
|
|
||||||
const getExpiry = useCallback(() => {
|
const getExpiry = useCallback(() => {
|
||||||
if (checkUserKey.data) {
|
if (checkUserKey.data) {
|
||||||
return checkUserKey.data.expiresAt;
|
return checkUserKey.data?.expiresAt || 'never';
|
||||||
}
|
}
|
||||||
}, [checkUserKey.data]);
|
}, [checkUserKey.data]);
|
||||||
|
|
||||||
const checkExpiry = useCallback(() => {
|
const checkExpiry = useCallback(() => {
|
||||||
const expiresAt = getExpiry();
|
const expiresAt = getExpiry();
|
||||||
if (!expiresAt) {
|
if (!expiresAt) {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const expiresAtDate = new Date(expiresAt);
|
const expiresAtDate = new Date(expiresAt);
|
||||||
|
|
@ -41,8 +42,8 @@ const useUserKey = (endpoint: string) => {
|
||||||
}, [getExpiry]);
|
}, [getExpiry]);
|
||||||
|
|
||||||
const saveUserKey = useCallback(
|
const saveUserKey = useCallback(
|
||||||
(userKey: string, expiresAt: number) => {
|
(userKey: string, expiresAt: number | null) => {
|
||||||
const dateStr = new Date(expiresAt).toISOString();
|
const dateStr = expiresAt ? new Date(expiresAt).toISOString() : '';
|
||||||
updateKey.mutate({
|
updateKey.mutate({
|
||||||
name: keyName,
|
name: keyName,
|
||||||
value: userKey,
|
value: userKey,
|
||||||
|
|
|
||||||
|
|
@ -507,6 +507,7 @@ export default {
|
||||||
com_endpoint_config_value: 'Enter value for',
|
com_endpoint_config_value: 'Enter value for',
|
||||||
com_endpoint_config_key_name_placeholder: 'Set API key first',
|
com_endpoint_config_key_name_placeholder: 'Set API key first',
|
||||||
com_endpoint_config_key_encryption: 'Your key will be encrypted and deleted at',
|
com_endpoint_config_key_encryption: 'Your key will be encrypted and deleted at',
|
||||||
|
com_endpoint_config_key_never_expires: 'Your key will never expire',
|
||||||
com_endpoint_config_key_expiry: 'the expiry time',
|
com_endpoint_config_key_expiry: 'the expiry time',
|
||||||
com_endpoint_config_click_here: 'Click Here',
|
com_endpoint_config_click_here: 'Click Here',
|
||||||
com_endpoint_config_google_service_key: 'Google Service Account Key',
|
com_endpoint_config_google_service_key: 'Google Service Account Key',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue