mirror of
https://github.com/sct/overseerr.git
synced 2025-09-17 17:24:35 +02:00
feat: generate real api key
This also hides the api key from users without the ADMIN permission. It will not be returned from the api for them. Regenerate functionality is not in the commit.
This commit is contained in:
@@ -102,7 +102,7 @@ class Settings {
|
||||
this.data = {
|
||||
clientId: '',
|
||||
main: {
|
||||
apiKey: 'temp',
|
||||
apiKey: '',
|
||||
applicationUrl: '',
|
||||
},
|
||||
plex: {
|
||||
@@ -144,6 +144,10 @@ class Settings {
|
||||
}
|
||||
|
||||
get main(): MainSettings {
|
||||
if (!this.data.main.apiKey) {
|
||||
this.data.main.apiKey = this.generateApiKey();
|
||||
this.save();
|
||||
}
|
||||
return this.data.main;
|
||||
}
|
||||
|
||||
@@ -200,6 +204,16 @@ class Settings {
|
||||
return this.data.clientId;
|
||||
}
|
||||
|
||||
public regenerateApiKey(): MainSettings {
|
||||
this.main.apiKey = this.generateApiKey();
|
||||
this.save();
|
||||
return this.main;
|
||||
}
|
||||
|
||||
private generateApiKey(): string {
|
||||
return Buffer.from(`${Date.now()}${this.clientId}`).toString('base64');
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings Load
|
||||
*
|
||||
|
@@ -4,6 +4,7 @@ import {
|
||||
RadarrSettings,
|
||||
SonarrSettings,
|
||||
Library,
|
||||
MainSettings,
|
||||
} from '../lib/settings';
|
||||
import { getRepository } from 'typeorm';
|
||||
import { User } from '../entity/User';
|
||||
@@ -19,9 +20,15 @@ import { merge } from 'lodash';
|
||||
|
||||
const settingsRoutes = Router();
|
||||
|
||||
settingsRoutes.get('/main', (_req, res) => {
|
||||
settingsRoutes.get('/main', (req, res) => {
|
||||
const settings = getSettings();
|
||||
|
||||
if (!req.user?.hasPermission(Permission.ADMIN)) {
|
||||
return res.status(200).json({
|
||||
applicationUrl: settings.main.applicationUrl,
|
||||
} as Partial<MainSettings>);
|
||||
}
|
||||
|
||||
res.status(200).json(settings.main);
|
||||
});
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import { Form, Formik, Field } from 'formik';
|
||||
import axios from 'axios';
|
||||
import Button from '../Common/Button';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useUser, Permission } from '../../hooks/useUser';
|
||||
|
||||
const messages = defineMessages({
|
||||
generalsettings: 'General Settings',
|
||||
@@ -19,6 +20,7 @@ const messages = defineMessages({
|
||||
});
|
||||
|
||||
const SettingsMain: React.FC = () => {
|
||||
const { hasPermission } = useUser();
|
||||
const intl = useIntl();
|
||||
const { data, error, revalidate } = useSWR<MainSettings>(
|
||||
'/api/v1/settings/main'
|
||||
@@ -41,7 +43,6 @@ const SettingsMain: React.FC = () => {
|
||||
<div className="mt-6 sm:mt-5">
|
||||
<Formik
|
||||
initialValues={{
|
||||
apiKey: data?.apiKey,
|
||||
applicationUrl: data?.applicationUrl,
|
||||
}}
|
||||
onSubmit={async (values) => {
|
||||
@@ -59,6 +60,7 @@ const SettingsMain: React.FC = () => {
|
||||
{({ isSubmitting }) => {
|
||||
return (
|
||||
<Form>
|
||||
{hasPermission(Permission.ADMIN) && (
|
||||
<div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
|
||||
<label
|
||||
htmlFor="username"
|
||||
@@ -70,7 +72,7 @@ const SettingsMain: React.FC = () => {
|
||||
<div className="max-w-lg flex rounded-md shadow-sm">
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
id="apiKey"
|
||||
className="flex-1 form-input block w-full min-w-0 rounded-none rounded-l-md transition duration-150 ease-in-out sm:text-sm sm:leading-5 bg-gray-700 border border-gray-500"
|
||||
value={data?.apiKey}
|
||||
readOnly
|
||||
@@ -93,6 +95,7 @@ const SettingsMain: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-800 sm:pt-5">
|
||||
<label
|
||||
htmlFor="name"
|
||||
|
@@ -6,7 +6,7 @@ import useRouteGuard from '../../hooks/useRouteGuard';
|
||||
import { Permission } from '../../hooks/useUser';
|
||||
|
||||
const SettingsPage: NextPage = () => {
|
||||
useRouteGuard(Permission.MANAGE_USERS);
|
||||
useRouteGuard(Permission.MANAGE_SETTINGS);
|
||||
return (
|
||||
<SettingsLayout>
|
||||
<SettingsMain />
|
||||
|
@@ -6,7 +6,7 @@ import { Permission } from '../../hooks/useUser';
|
||||
import useRouteGuard from '../../hooks/useRouteGuard';
|
||||
|
||||
const SettingsMainPage: NextPage = () => {
|
||||
useRouteGuard(Permission.MANAGE_USERS);
|
||||
useRouteGuard(Permission.MANAGE_SETTINGS);
|
||||
return (
|
||||
<SettingsLayout>
|
||||
<SettingsJobs />
|
||||
|
@@ -6,7 +6,7 @@ import { Permission } from '../../hooks/useUser';
|
||||
import useRouteGuard from '../../hooks/useRouteGuard';
|
||||
|
||||
const SettingsMainPage: NextPage = () => {
|
||||
useRouteGuard(Permission.MANAGE_USERS);
|
||||
useRouteGuard(Permission.MANAGE_SETTINGS);
|
||||
return (
|
||||
<SettingsLayout>
|
||||
<SettingsMain />
|
||||
|
@@ -6,7 +6,7 @@ import { Permission } from '../../hooks/useUser';
|
||||
import useRouteGuard from '../../hooks/useRouteGuard';
|
||||
|
||||
const PlexSettingsPage: NextPage = () => {
|
||||
useRouteGuard(Permission.MANAGE_USERS);
|
||||
useRouteGuard(Permission.MANAGE_SETTINGS);
|
||||
return (
|
||||
<SettingsLayout>
|
||||
<SettingsPlex />
|
||||
|
@@ -6,7 +6,7 @@ import { Permission } from '../../hooks/useUser';
|
||||
import useRouteGuard from '../../hooks/useRouteGuard';
|
||||
|
||||
const ServicesSettingsPage: NextPage = () => {
|
||||
useRouteGuard(Permission.MANAGE_USERS);
|
||||
useRouteGuard(Permission.MANAGE_SETTINGS);
|
||||
return (
|
||||
<SettingsLayout>
|
||||
<SettingsServices />
|
||||
|
Reference in New Issue
Block a user