feat: add legal page with configuration options (#724)
* Addconfig entries for legal notice * Add legal route handling to middleware * Make legal notice public * Add legal category to config sidebar * Add legal notice page * Add German translations for legal notice and configuration options * Replace legal page with separate imprint and privacy pages * Update middleware * Add footer component * Update legal text descriptions to indicate Markdown support again * Refactor footer layout * Add zIndex to footer component * improve mobile layout * run formatter --------- Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
@@ -349,6 +349,33 @@ const configVariables: ConfigVariables = {
|
|||||||
defaultValue: "",
|
defaultValue: "",
|
||||||
obscured: true,
|
obscured: true,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
legal: {
|
||||||
|
enabled: {
|
||||||
|
type: "boolean",
|
||||||
|
defaultValue: "false",
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
imprintText: {
|
||||||
|
type: "text",
|
||||||
|
defaultValue: "",
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
imprintUrl: {
|
||||||
|
type: "string",
|
||||||
|
defaultValue: "",
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
privacyPolicyText: {
|
||||||
|
type: "text",
|
||||||
|
defaultValue: "",
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
|
privacyPolicyUrl: {
|
||||||
|
type: "string",
|
||||||
|
defaultValue: "",
|
||||||
|
secret: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,7 @@ export class ConfigService extends EventEmitter {
|
|||||||
|
|
||||||
if (configVariable.type == "number" || configVariable.type == "filesize")
|
if (configVariable.type == "number" || configVariable.type == "filesize")
|
||||||
return parseInt(value);
|
return parseInt(value);
|
||||||
if (configVariable.type == "boolean")
|
if (configVariable.type == "boolean") return value == "true";
|
||||||
return value == "true";
|
|
||||||
if (configVariable.type == "string" || configVariable.type == "text")
|
if (configVariable.type == "string" || configVariable.type == "text")
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
TbBucket,
|
TbBucket,
|
||||||
TbBinaryTree,
|
TbBinaryTree,
|
||||||
TbSettings,
|
TbSettings,
|
||||||
|
TbScale,
|
||||||
} from "react-icons/tb";
|
} from "react-icons/tb";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ const categories = [
|
|||||||
{ name: "OAuth", icon: <TbSocial /> },
|
{ name: "OAuth", icon: <TbSocial /> },
|
||||||
{ name: "LDAP", icon: <TbBinaryTree /> },
|
{ name: "LDAP", icon: <TbBinaryTree /> },
|
||||||
{ name: "S3", icon: <TbBucket /> },
|
{ name: "S3", icon: <TbBucket /> },
|
||||||
|
{ name: "Legal", icon: <TbScale /> },
|
||||||
];
|
];
|
||||||
|
|
||||||
const useStyles = createStyles((theme) => ({
|
const useStyles = createStyles((theme) => ({
|
||||||
|
|||||||
@@ -11,12 +11,16 @@ const multipliers = {
|
|||||||
GiB: 1024 ** 3,
|
GiB: 1024 ** 3,
|
||||||
TB: 1000 ** 4,
|
TB: 1000 ** 4,
|
||||||
TiB: 1024 ** 4,
|
TiB: 1024 ** 4,
|
||||||
}
|
};
|
||||||
|
|
||||||
const units = (["B", "KB", "KiB", "MB", "MiB", "GB", "GiB", "TB", "TiB"] as const).map(unit => ({ label: unit, value: unit }));
|
const units = (
|
||||||
|
["B", "KB", "KiB", "MB", "MiB", "GB", "GiB", "TB", "TiB"] as const
|
||||||
|
).map((unit) => ({ label: unit, value: unit }));
|
||||||
|
|
||||||
function getLargestApplicableUnit(value: number) {
|
function getLargestApplicableUnit(value: number) {
|
||||||
return units.findLast(unit => value % multipliers[unit.value] === 0) || units[0];
|
return (
|
||||||
|
units.findLast((unit) => value % multipliers[unit.value] === 0) || units[0]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileSizeInput = ({
|
const FileSizeInput = ({
|
||||||
@@ -46,8 +50,9 @@ const FileSizeInput = ({
|
|||||||
marginRight: -2,
|
marginRight: -2,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
onChange={event => {
|
onChange={(event) => {
|
||||||
const unit = event.currentTarget.value as typeof units[number]["value"];
|
const unit = event.currentTarget
|
||||||
|
.value as (typeof units)[number]["value"];
|
||||||
setUnit(unit);
|
setUnit(unit);
|
||||||
onChange(multipliers[unit] * inputValue);
|
onChange(multipliers[unit] * inputValue);
|
||||||
}}
|
}}
|
||||||
@@ -63,7 +68,7 @@ const FileSizeInput = ({
|
|||||||
precision={0}
|
precision={0}
|
||||||
rightSection={unitSelect}
|
rightSection={unitSelect}
|
||||||
rightSectionWidth={76}
|
rightSectionWidth={76}
|
||||||
onChange={value => {
|
onChange={(value) => {
|
||||||
const inputVal = value || 0;
|
const inputVal = value || 0;
|
||||||
setInputValue(inputVal);
|
setInputValue(inputVal);
|
||||||
onChange(multipliers[unit] * inputVal);
|
onChange(multipliers[unit] * inputVal);
|
||||||
|
|||||||
62
frontend/src/components/footer/Footer.tsx
Normal file
62
frontend/src/components/footer/Footer.tsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { Anchor, Footer as MFooter, SimpleGrid, Text } from "@mantine/core";
|
||||||
|
import { useMediaQuery } from "@mantine/hooks";
|
||||||
|
import useConfig from "../../hooks/config.hook";
|
||||||
|
import useTranslate from "../../hooks/useTranslate.hook";
|
||||||
|
|
||||||
|
const Footer = () => {
|
||||||
|
const t = useTranslate();
|
||||||
|
const config = useConfig();
|
||||||
|
const hasImprint = !!(
|
||||||
|
config.get("legal.imprintUrl") || config.get("legal.imprintText")
|
||||||
|
);
|
||||||
|
const hasPrivacy = !!(
|
||||||
|
config.get("legal.privacyPolicyUrl") ||
|
||||||
|
config.get("legal.privacyPolicyText")
|
||||||
|
);
|
||||||
|
const imprintUrl =
|
||||||
|
(!config.get("legal.imprintText") && config.get("legal.imprintUrl")) ||
|
||||||
|
"/imprint";
|
||||||
|
const privacyUrl =
|
||||||
|
(!config.get("legal.privacyPolicyText") &&
|
||||||
|
config.get("legal.privacyPolicyUrl")) ||
|
||||||
|
"/privacy";
|
||||||
|
|
||||||
|
const isMobile = useMediaQuery("(max-width: 700px)");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MFooter height="auto" py={6} px="xl" zIndex={100}>
|
||||||
|
<SimpleGrid cols={isMobile ? 2 : 3} m={0}>
|
||||||
|
{!isMobile && <div></div>}
|
||||||
|
<Text size="xs" color="dimmed" align={isMobile ? "left" : "center"}>
|
||||||
|
Powered by{" "}
|
||||||
|
<Anchor
|
||||||
|
size="xs"
|
||||||
|
href="https://github.com/stonith404/pingvin-share"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Pingvin Share
|
||||||
|
</Anchor>
|
||||||
|
</Text>
|
||||||
|
<div>
|
||||||
|
{config.get("legal.enabled") && (
|
||||||
|
<Text size="xs" color="dimmed" align="right">
|
||||||
|
{hasImprint && (
|
||||||
|
<Anchor size="xs" href={imprintUrl}>
|
||||||
|
{t("imprint.title")}
|
||||||
|
</Anchor>
|
||||||
|
)}
|
||||||
|
{hasImprint && hasPrivacy && " • "}
|
||||||
|
{hasPrivacy && (
|
||||||
|
<Anchor size="xs" href={privacyUrl}>
|
||||||
|
{t("privacy.title")}
|
||||||
|
</Anchor>
|
||||||
|
)}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</SimpleGrid>
|
||||||
|
</MFooter>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Footer;
|
||||||
@@ -295,6 +295,12 @@ export default {
|
|||||||
"share.edit.notify.generic-error": "Während der Erstellung der Freigabe ist ein Fehler aufgetreten.",
|
"share.edit.notify.generic-error": "Während der Erstellung der Freigabe ist ein Fehler aufgetreten.",
|
||||||
"share.edit.notify.save-success": "Freigabe erfolgreich aktualisiert",
|
"share.edit.notify.save-success": "Freigabe erfolgreich aktualisiert",
|
||||||
// END /share/[id]/edit
|
// END /share/[id]/edit
|
||||||
|
// /imprint
|
||||||
|
"imprint.title": "Imprint",
|
||||||
|
// END /imprint
|
||||||
|
// /privacy
|
||||||
|
"privacy.title": "Privacy Policy",
|
||||||
|
// END /privacy
|
||||||
// /admin/config
|
// /admin/config
|
||||||
"admin.config.title": "Einstellungen",
|
"admin.config.title": "Einstellungen",
|
||||||
"admin.config.category.general": "Allgemein",
|
"admin.config.category.general": "Allgemein",
|
||||||
@@ -457,6 +463,17 @@ export default {
|
|||||||
"admin.config.s3.key.description": "Der Schlüssel, der den Zugriff auf den S3-Bucket ermöglicht.",
|
"admin.config.s3.key.description": "Der Schlüssel, der den Zugriff auf den S3-Bucket ermöglicht.",
|
||||||
"admin.config.s3.secret": "Geheimnis",
|
"admin.config.s3.secret": "Geheimnis",
|
||||||
"admin.config.s3.secret.description": "Das Geheimnis, das den Zugriff auf den S3-Bucket ermöglicht.",
|
"admin.config.s3.secret.description": "Das Geheimnis, das den Zugriff auf den S3-Bucket ermöglicht.",
|
||||||
|
"admin.config.category.legal": "Rechtliches",
|
||||||
|
"admin.config.legal.enabled": "Impressum und Datenschutz aktivieren",
|
||||||
|
"admin.config.legal.enabled.description": "Gibt an, ob die Links zum Impressum und zur Datenschutzerklärung im Footer angezeigt werden sollen.",
|
||||||
|
"admin.config.legal.imprint-text": "Impressum-Text",
|
||||||
|
"admin.config.legal.imprint-text.description": "Der Text, der im Impressum angezeigt wird. Unterstützt Markdown. Leer lassen, um auf eine externe Impressumsseite zu verlinken.",
|
||||||
|
"admin.config.legal.imprint-url": "Impressum-URL",
|
||||||
|
"admin.config.legal.imprint-url.description": "Wenn bereits eine Impressumsseite vorhanden ist, kann sie hier verlinkt werden, anstatt den Text einzugeben.",
|
||||||
|
"admin.config.legal.privacy-policy-text": "Datenschutzerklärungstext",
|
||||||
|
"admin.config.legal.privacy-policy-text.description": "Der Text, der in der Datenschutzerklärung angezeigt wird. Unterstützt Markdown. Leer lassen, um auf eine externe Datenschutzerklärungsseite zu verlinken.",
|
||||||
|
"admin.config.legal.privacy-policy-url": "Datenschutzerklärungs-URL",
|
||||||
|
"admin.config.legal.privacy-policy-url.description": "Wenn bereits eine Datenschutzerklärungsseite vorhanden ist, kann sie hier verlinkt werden, anstatt den Text einzugeben.",
|
||||||
// 404
|
// 404
|
||||||
"404.description": "Ups, diese Seite existiert nicht.",
|
"404.description": "Ups, diese Seite existiert nicht.",
|
||||||
"404.button.home": "Zurück zur Startseite",
|
"404.button.home": "Zurück zur Startseite",
|
||||||
|
|||||||
@@ -405,6 +405,14 @@ export default {
|
|||||||
"share.edit.notify.save-success": "Share updated successfully",
|
"share.edit.notify.save-success": "Share updated successfully",
|
||||||
// END /share/[id]/edit
|
// END /share/[id]/edit
|
||||||
|
|
||||||
|
// /imprint
|
||||||
|
"imprint.title": "Imprint",
|
||||||
|
// END /imprint
|
||||||
|
|
||||||
|
// /privacy
|
||||||
|
"privacy.title": "Privacy Policy",
|
||||||
|
// END /privacy
|
||||||
|
|
||||||
// /admin/config
|
// /admin/config
|
||||||
"admin.config.title": "Configuration",
|
"admin.config.title": "Configuration",
|
||||||
"admin.config.category.general": "General",
|
"admin.config.category.general": "General",
|
||||||
@@ -645,6 +653,18 @@ export default {
|
|||||||
"admin.config.s3.secret": "Secret",
|
"admin.config.s3.secret": "Secret",
|
||||||
"admin.config.s3.secret.description": "The secret which allows you to access the S3 bucket.",
|
"admin.config.s3.secret.description": "The secret which allows you to access the S3 bucket.",
|
||||||
|
|
||||||
|
"admin.config.category.legal": "Legal",
|
||||||
|
"admin.config.legal.enabled": "Enable legal notices",
|
||||||
|
"admin.config.legal.enabled.description": "Whether to show a link to imprint and privacy policy in the footer.",
|
||||||
|
"admin.config.legal.imprint-text": "Imprint text",
|
||||||
|
"admin.config.legal.imprint-text.description": "The text which should be shown in the imprint. Supports Markdown. Leave blank to link to an external imprint page.",
|
||||||
|
"admin.config.legal.imprint-url": "Imprint URL",
|
||||||
|
"admin.config.legal.imprint-url.description": "If you already have an imprint page you can link it here instead of using the text field.",
|
||||||
|
"admin.config.legal.privacy-policy-text": "Privacy policy text",
|
||||||
|
"admin.config.legal.privacy-policy-text.description": "The text which should be shown in the privacy policy. Supports Markdown. Leave blank to link to an external privacy policy page.",
|
||||||
|
"admin.config.legal.privacy-policy-url": "Privacy policy URL",
|
||||||
|
"admin.config.legal.privacy-policy-url.description": "If you already have a privacy policy page you can link it here instead of using the text field.",
|
||||||
|
|
||||||
// 404
|
// 404
|
||||||
"404.description": "Oops this page doesn't exist.",
|
"404.description": "Oops this page doesn't exist.",
|
||||||
"404.button.home": "Bring me back home",
|
"404.button.home": "Bring me back home",
|
||||||
|
|||||||
@@ -14,7 +14,14 @@ export const config = {
|
|||||||
export async function middleware(request: NextRequest) {
|
export async function middleware(request: NextRequest) {
|
||||||
const routes = {
|
const routes = {
|
||||||
unauthenticated: new Routes(["/auth/*", "/"]),
|
unauthenticated: new Routes(["/auth/*", "/"]),
|
||||||
public: new Routes(["/share/*", "/s/*", "/upload/*", "/error"]),
|
public: new Routes([
|
||||||
|
"/share/*",
|
||||||
|
"/s/*",
|
||||||
|
"/upload/*",
|
||||||
|
"/error",
|
||||||
|
"/imprint",
|
||||||
|
"/privacy",
|
||||||
|
]),
|
||||||
admin: new Routes(["/admin/*"]),
|
admin: new Routes(["/admin/*"]),
|
||||||
account: new Routes(["/account*"]),
|
account: new Routes(["/account*"]),
|
||||||
disabled: new Routes([]),
|
disabled: new Routes([]),
|
||||||
@@ -55,6 +62,20 @@ export async function middleware(request: NextRequest) {
|
|||||||
routes.disabled.routes.push("/auth/resetPassword*");
|
routes.disabled.routes.push("/auth/resetPassword*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!getConfig("legal.enabled")) {
|
||||||
|
routes.disabled.routes.push("/imprint", "/privacy");
|
||||||
|
} else {
|
||||||
|
if (!getConfig("legal.imprintText") && !getConfig("legal.imprintUrl")) {
|
||||||
|
routes.disabled.routes.push("/imprint");
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!getConfig("legal.privacyPolicyText") &&
|
||||||
|
!getConfig("legal.privacyPolicyUrl")
|
||||||
|
) {
|
||||||
|
routes.disabled.routes.push("/privacy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const rules = [
|
const rules = [
|
||||||
// Disabled routes
|
// Disabled routes
|
||||||
@@ -86,6 +107,16 @@ export async function middleware(request: NextRequest) {
|
|||||||
condition: (!getConfig("general.showHomePage") || user) && route == "/",
|
condition: (!getConfig("general.showHomePage") || user) && route == "/",
|
||||||
path: "/upload",
|
path: "/upload",
|
||||||
},
|
},
|
||||||
|
// Imprint redirect
|
||||||
|
{
|
||||||
|
condition: route == "/imprint" && !getConfig("legal.imprintText") && getConfig("legal.imprintUrl"),
|
||||||
|
path: getConfig("legal.imprintUrl"),
|
||||||
|
},
|
||||||
|
// Privacy redirect
|
||||||
|
{
|
||||||
|
condition: route == "/privacy" && !getConfig("legal.privacyPolicyText") && getConfig("legal.privacyPolicyUrl"),
|
||||||
|
path: getConfig("legal.privacyPolicyUrl"),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
for (const rule of rules) {
|
for (const rule of rules) {
|
||||||
if (rule.condition) {
|
if (rule.condition) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
ColorSchemeProvider,
|
ColorSchemeProvider,
|
||||||
Container,
|
Container,
|
||||||
MantineProvider,
|
MantineProvider,
|
||||||
|
Stack,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { useColorScheme } from "@mantine/hooks";
|
import { useColorScheme } from "@mantine/hooks";
|
||||||
import { ModalsProvider } from "@mantine/modals";
|
import { ModalsProvider } from "@mantine/modals";
|
||||||
@@ -30,6 +31,7 @@ import Config from "../types/config.type";
|
|||||||
import { CurrentUser } from "../types/user.type";
|
import { CurrentUser } from "../types/user.type";
|
||||||
import i18nUtil from "../utils/i18n.util";
|
import i18nUtil from "../utils/i18n.util";
|
||||||
import userPreferences from "../utils/userPreferences.util";
|
import userPreferences from "../utils/userPreferences.util";
|
||||||
|
import Footer from "../components/footer/Footer";
|
||||||
|
|
||||||
const excludeDefaultLayoutRoutes = ["/admin/config/[category]"];
|
const excludeDefaultLayoutRoutes = ["/admin/config/[category]"];
|
||||||
|
|
||||||
@@ -134,10 +136,18 @@ function App({ Component, pageProps }: AppProps) {
|
|||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
<Stack
|
||||||
|
justify="space-between"
|
||||||
|
sx={{ minHeight: "100vh" }}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
<Header />
|
<Header />
|
||||||
<Container>
|
<Container>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</Container>
|
</Container>
|
||||||
|
</div>
|
||||||
|
<Footer />
|
||||||
|
</Stack>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</UserContext.Provider>
|
</UserContext.Provider>
|
||||||
|
|||||||
55
frontend/src/pages/imprint/index.tsx
Normal file
55
frontend/src/pages/imprint/index.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { Anchor, Title, useMantineTheme } from "@mantine/core";
|
||||||
|
import Meta from "../../components/Meta";
|
||||||
|
import useTranslate from "../../hooks/useTranslate.hook";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
import useConfig from "../../hooks/config.hook";
|
||||||
|
import Markdown from "markdown-to-jsx";
|
||||||
|
|
||||||
|
const Imprint = () => {
|
||||||
|
const t = useTranslate();
|
||||||
|
const { colorScheme } = useMantineTheme();
|
||||||
|
const config = useConfig();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Meta title={t("imprint.title")} />
|
||||||
|
<Title mb={30} order={1}>
|
||||||
|
<FormattedMessage id="imprint.title" />
|
||||||
|
</Title>
|
||||||
|
<Markdown
|
||||||
|
options={{
|
||||||
|
forceBlock: true,
|
||||||
|
overrides: {
|
||||||
|
pre: {
|
||||||
|
props: {
|
||||||
|
style: {
|
||||||
|
backgroundColor:
|
||||||
|
colorScheme == "dark"
|
||||||
|
? "rgba(50, 50, 50, 0.5)"
|
||||||
|
: "rgba(220, 220, 220, 0.5)",
|
||||||
|
padding: "0.75em",
|
||||||
|
whiteSpace: "pre-wrap",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
props: {
|
||||||
|
className: "md",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
a: {
|
||||||
|
props: {
|
||||||
|
target: "_blank",
|
||||||
|
rel: "noreferrer",
|
||||||
|
},
|
||||||
|
component: Anchor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{config.get("legal.imprintText")}
|
||||||
|
</Markdown>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Imprint;
|
||||||
55
frontend/src/pages/privacy/index.tsx
Normal file
55
frontend/src/pages/privacy/index.tsx
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { Anchor, Title, useMantineTheme } from "@mantine/core";
|
||||||
|
import Meta from "../../components/Meta";
|
||||||
|
import useTranslate from "../../hooks/useTranslate.hook";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
import useConfig from "../../hooks/config.hook";
|
||||||
|
import Markdown from "markdown-to-jsx";
|
||||||
|
|
||||||
|
const PrivacyPolicy = () => {
|
||||||
|
const t = useTranslate();
|
||||||
|
const { colorScheme } = useMantineTheme();
|
||||||
|
const config = useConfig();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Meta title={t("privacy.title")} />
|
||||||
|
<Title mb={30} order={1}>
|
||||||
|
<FormattedMessage id="privacy.title" />
|
||||||
|
</Title>
|
||||||
|
<Markdown
|
||||||
|
options={{
|
||||||
|
forceBlock: true,
|
||||||
|
overrides: {
|
||||||
|
pre: {
|
||||||
|
props: {
|
||||||
|
style: {
|
||||||
|
backgroundColor:
|
||||||
|
colorScheme == "dark"
|
||||||
|
? "rgba(50, 50, 50, 0.5)"
|
||||||
|
: "rgba(220, 220, 220, 0.5)",
|
||||||
|
padding: "0.75em",
|
||||||
|
whiteSpace: "pre-wrap",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
props: {
|
||||||
|
className: "md",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
a: {
|
||||||
|
props: {
|
||||||
|
target: "_blank",
|
||||||
|
rel: "noreferrer",
|
||||||
|
},
|
||||||
|
component: Anchor,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{config.get("legal.privacyPolicyText")}
|
||||||
|
</Markdown>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PrivacyPolicy;
|
||||||
@@ -27,8 +27,7 @@ const get = (key: string, configVariables: Config[]): any => {
|
|||||||
|
|
||||||
if (configVariable.type == "number" || configVariable.type == "filesize")
|
if (configVariable.type == "number" || configVariable.type == "filesize")
|
||||||
return parseInt(value);
|
return parseInt(value);
|
||||||
if (configVariable.type == "boolean")
|
if (configVariable.type == "boolean") return value == "true";
|
||||||
return value == "true";
|
|
||||||
if (configVariable.type == "string" || configVariable.type == "text")
|
if (configVariable.type == "string" || configVariable.type == "text")
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user