feat: override domain header

This commit is contained in:
diced 2023-02-18 10:53:46 -08:00
parent e80627a3c3
commit 83718d7b31
No known key found for this signature in database
GPG key ID: 370BD1BA142842D1
10 changed files with 224 additions and 101 deletions

View file

@ -0,0 +1,5 @@
import { Globe } from 'react-feather';
export default function GlobeIcon({ ...props }) {
return <Globe size={15} {...props} />;
}

View file

@ -38,6 +38,7 @@ import InfoIcon from './InfoIcon';
import FolderIcon from './FolderIcon';
import FolderMinusIcon from './FolderMinusIcon';
import FolderPlusIcon from './FolderPlusIcon';
import GlobeIcon from './GlobeIcon';
export {
ActivityIcon,
@ -80,4 +81,5 @@ export {
FolderIcon,
FolderMinusIcon,
FolderPlusIcon,
GlobeIcon,
};

View file

@ -61,6 +61,12 @@ export default function Flameshot({ user, open, setOpen }) {
delete extraHeaders['Original-Name'];
}
if (values.overrideDomain && values.overrideDomain.trim() !== '') {
extraHeaders['Override-Domain'] = values.overrideDomain;
} else {
delete extraHeaders['Override-Domain'];
}
for (const [key, value] of Object.entries(extraHeaders)) {
curl.push('-H');
curl.push(`"${key}: ${value}"`);

View file

@ -10,13 +10,16 @@ import {
Stack,
Switch,
Text,
TextInput,
Title,
} from '@mantine/core';
import { useForm } from '@mantine/form';
import { DownloadIcon } from 'components/icons';
import { DownloadIcon, GlobeIcon } from 'components/icons';
import Link from 'components/Link';
import MutedText from 'components/MutedText';
import { useState } from 'react';
import { useReducer, useState } from 'react';
const DEFAULT_OD_DESC = 'Override the default domain(s). Type in a URL, e.g https://example.com';
export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
const form = useForm({
@ -30,6 +33,7 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
wlCompositorNotSupported: false,
noJSON: false,
originalName: false,
overrideDomain: null,
},
});
@ -40,6 +44,42 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
form.setFieldValue('type', value);
};
const [odState, setODState] = useReducer((state, newState) => ({ ...state, ...newState }), {
description: DEFAULT_OD_DESC,
error: '',
domain: '',
});
const handleOD = (e) => {
setODState({ error: '' });
if (e.currentTarget.value === '') {
setODState({ description: DEFAULT_OD_DESC, error: '', domain: null });
form.setFieldValue('overrideDomain', null);
return;
}
try {
const url = new URL(e.currentTarget.value);
setODState({
description: (
<>
{DEFAULT_OD_DESC}
<br />
<br />
Using domain &quot;<b>{url.hostname}</b>&quot;
</>
),
error: '',
domain: url.hostname,
});
form.setFieldValue('overrideDomain', url.hostname);
} catch (e) {
setODState({ error: 'Invalid URL', domain: '' });
form.setFieldValue('overrideDomain', null);
}
};
return (
<Modal opened={opened} onClose={onClose} title={<Title order={3}>{title}</Title>} size='lg'>
{other.desc && (
@ -85,6 +125,14 @@ export function GeneratorModal({ opened, onClose, title, onSubmit, ...other }) {
{...form.getInputProps('imageCompression')}
/>
<TextInput
label='Override Domain'
onChange={handleOD}
icon={<GlobeIcon />}
description={odState.description}
error={odState.error}
/>
<Stack my='md'>
<Switch
label='Zero Width Space'

View file

@ -79,6 +79,12 @@ export default function ShareX({ user, open, setOpen }) {
delete config.Headers['Original-Name'];
}
if (values.overrideDomain && values.overrideDomain.trim() !== '') {
config.Headers['Override-Domain'] = values.overrideDomain;
} else {
delete config.Headers['Override-Domain'];
}
const pseudoElement = document.createElement('a');
pseudoElement.setAttribute(
'href',

View file

@ -276,6 +276,7 @@ export default function File({ chunks: chunks_config }) {
options.zeroWidth && req.setRequestHeader('Zws', 'true');
options.format !== 'default' && req.setRequestHeader('Format', options.format);
options.originalName && req.setRequestHeader('Original-Name', 'true');
options.overrideDomain && req.setRequestHeader('Override-Domain', options.overrideDomain);
req.send(body);
}
@ -283,7 +284,7 @@ export default function File({ chunks: chunks_config }) {
return (
<>
<OptionsModal />
{OptionsModal}
<Title mb='md'>Upload Files</Title>
<Dropzone loading={loading} onDrop={(f) => setFiles([...files, ...f])}>

View file

@ -71,13 +71,14 @@ export default function Text() {
options.zeroWidth && req.setRequestHeader('Zws', 'true');
options.format !== 'default' && req.setRequestHeader('Format', options.format);
options.originalName && req.setRequestHeader('Original-Name', 'true');
options.overrideDomain && req.setRequestHeader('Override-Domain', options.overrideDomain);
req.send(body);
};
return (
<>
<OptionsModal />
{OptionsModal}
<Title mb='md'>Upload Text</Title>
<Tabs defaultValue='text' variant='pills'>

View file

@ -7,52 +7,72 @@ import {
Select,
Stack,
Switch,
TextInput,
Title,
} from '@mantine/core';
import { ClockIcon, ImageIcon, KeyIcon, TypeIcon, UserIcon } from 'components/icons';
import { ClockIcon, ImageIcon, KeyIcon, TypeIcon, UserIcon, GlobeIcon } from 'components/icons';
import React, { Dispatch, SetStateAction, useReducer, useState } from 'react';
export default function useUploadOptions(): [
{
expires: string;
password: string;
maxViews: number;
compression: string;
zeroWidth: boolean;
embedded: boolean;
format: string;
originalName: boolean;
},
Dispatch<SetStateAction<boolean>>,
React.FC
] {
const [state, setState] = useReducer((state, newState) => ({ ...state, ...newState }), {
expires: 'never',
password: '',
maxViews: 0,
compression: 'none',
zeroWidth: false,
embedded: false,
format: 'default',
originalName: false,
export type UploadOptionsState = {
expires: string;
password: string;
maxViews: number;
compression: string;
zeroWidth: boolean;
embedded: boolean;
format: string;
originalName: boolean;
overrideDomain: string;
};
const DEFAULT_OD_DESC = 'Override the default domain(s). Type in a URL, e.g https://example.com';
export function OptionsModal({
opened,
setOpened,
state,
setState,
reset,
}: {
opened: boolean;
setOpened: Dispatch<SetStateAction<boolean>>;
state: UploadOptionsState;
setState: Dispatch<SetStateAction<any>>;
reset: () => void;
}) {
const [odState, setODState] = useReducer((state, newState) => ({ ...state, ...newState }), {
description: DEFAULT_OD_DESC,
error: '',
});
const [opened, setOpened] = useState(false);
const handleOD = (e) => {
setODState({ error: '' });
const reset = () => {
setState({
expires: 'never',
password: '',
maxViews: 0,
compression: 'none',
zeroWidth: false,
embedded: false,
format: 'default',
originalName: false,
});
if (e.currentTarget.value === '') {
setODState({ description: DEFAULT_OD_DESC, error: '' });
setState({ overrideDomain: '' });
return;
}
try {
const url = new URL(e.currentTarget.value);
setODState({
description: (
<>
{DEFAULT_OD_DESC}
<br />
<br />
Using domain &quot;<b>{url.hostname}</b>&quot;
</>
),
});
setState({ overrideDomain: url.hostname });
} catch (e) {
setODState({ error: 'Invalid URL' });
}
};
const OptionsModal: React.FC = () => (
return (
<Modal title={<Title>Upload Options</Title>} size='lg' opened={opened} onClose={() => setOpened(false)}>
<Stack>
<NumberInput
@ -134,6 +154,13 @@ export default function useUploadOptions(): [
onChange={(e) => setState({ password: e.currentTarget.value })}
icon={<KeyIcon />}
/>
<TextInput
label='Override Domain'
onChange={handleOD}
icon={<GlobeIcon />}
description={odState.description}
error={odState.error}
/>
<Group>
<Switch
label='Zero Width'
@ -165,6 +192,47 @@ export default function useUploadOptions(): [
</Stack>
</Modal>
);
return [state, setOpened, OptionsModal];
}
export default function useUploadOptions(): [UploadOptionsState, Dispatch<SetStateAction<boolean>>, any] {
const [state, setState] = useReducer((state, newState) => ({ ...state, ...newState }), {
expires: 'never',
password: '',
maxViews: 0,
compression: 'none',
zeroWidth: false,
embedded: false,
format: 'default',
originalName: false,
overrideDomain: '',
} as UploadOptionsState);
const [opened, setOpened] = useState(false);
const reset = () => {
setState({
expires: 'never',
password: '',
maxViews: 0,
compression: 'none',
zeroWidth: false,
embedded: false,
format: 'default',
originalName: false,
overrideDomain: '',
});
};
return [
state,
setOpened,
<OptionsModal
state={state}
setState={setState}
reset={reset}
opened={opened}
setOpened={setOpened}
key={1}
/>,
];
}

View file

@ -56,27 +56,31 @@ async function handler(req: NextApiReq, res: NextApiRes) {
logger.info(`User ${user.username} (${user.id}) shortenned a url ${url.destination} (${url.id})`);
if (config.discord?.shorten) {
await sendShorten(
user,
url,
`${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${
zconfig.urls.route === '/' ? '/' : `${zconfig.urls.route}/`
}${req.body.vanity ? req.body.vanity : invis ? invis.invis : url.id}`
);
let domain;
if (req.headers['override-domain']) {
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers['override-domain']}`;
} else if (user.domains.length) {
const randomDomain = user.domains[Math.floor(Math.random() * user.domains.length)];
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${randomDomain}`;
} else {
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}`;
}
const fullUrl = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${
zconfig.urls.route === '/' ? '/' : zconfig.urls.route
}/${req.body.vanity ? req.body.vanity : invis ? invis.invis : url.id}`;
const responseUrl = `${domain}${zconfig.uploader.route === '/' ? '/' : zconfig.uploader.route}${
req.body.vanity ? req.body.vanity : invis ? invis.invis : url.id
}`;
if (config.discord?.shorten) {
await sendShorten(user, url, responseUrl);
}
if (req.headers['no-json']) {
res.setHeader('Content-Type', 'text/plain');
return res.end(fullUrl);
return res.end(responseUrl);
}
return res.json({
url: fullUrl,
url: responseUrl,
});
}

View file

@ -171,32 +171,24 @@ async function handler(req: NextApiReq, res: NextApiRes) {
await datasource.save(file.name, Buffer.from(chunks));
logger.info(`User ${user.username} (${user.id}) uploaded ${file.name} (${file.id}) (chunked)`);
if (user.domains.length) {
const domain = user.domains[Math.floor(Math.random() * user.domains.length)];
response.files.push(
`${domain}${zconfig.uploader.route === '/' ? '/' : zconfig.uploader.route}/${
invis ? invis.invis : file.name
}`
);
let domain;
if (req.headers['override-domain']) {
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers['override-domain']}`;
} else if (user.domains.length) {
const randomDomain = user.domains[Math.floor(Math.random() * user.domains.length)];
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${randomDomain}`;
} else {
response.files.push(
`${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${
zconfig.uploader.route === '/' ? '/' : zconfig.uploader.route
}/${invis ? invis.invis : file.name}`
);
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}`;
}
const responseUrl = `${domain}${zconfig.uploader.route === '/' ? '/' : zconfig.uploader.route}${
invis ? invis.invis : file.name
}`;
response.files.push(responseUrl);
if (zconfig.discord?.upload) {
await sendUpload(
user,
file,
`${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}/r/${
invis ? invis.invis : file.name
}`,
`${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${
zconfig.uploader.route === '/' ? '/' : zconfig.uploader.route
}/${invis ? invis.invis : file.name}`
);
await sendUpload(user, file, `${domain}/r/${invis ? invis.invis : file.name}`, responseUrl);
}
if (zconfig.exif.enabled && zconfig.exif.remove_gps && mimetype.startsWith('image/')) {
@ -318,34 +310,24 @@ async function handler(req: NextApiReq, res: NextApiRes) {
}
logger.info(`User ${user.username} (${user.id}) uploaded ${fileUpload.name} (${fileUpload.id})`);
if (user.domains.length) {
const domain = user.domains[Math.floor(Math.random() * user.domains.length)];
response.files.push(
`${domain}${zconfig.uploader.route === '/' ? '' : zconfig.uploader.route}/${
invis ? invis.invis : fileUpload.name
}`
);
let domain;
if (req.headers['override-domain']) {
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers['override-domain']}`;
} else if (user.domains.length) {
const randomDomain = user.domains[Math.floor(Math.random() * user.domains.length)];
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${randomDomain}`;
} else {
response.files.push(
`${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${
zconfig.uploader.route === '/' ? '' : zconfig.uploader.route
}/${invis ? invis.invis : fileUpload.name}`
);
domain = `${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}`;
}
logger.debug(`sent response: ${JSON.stringify(response)}`);
const responseUrl = `${domain}${zconfig.uploader.route === '/' ? '/' : zconfig.uploader.route}${
invis ? invis.invis : fileUpload.name
}`;
response.files.push(responseUrl);
if (zconfig.discord?.upload) {
await sendUpload(
user,
fileUpload,
`${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}/r/${
invis ? invis.invis : fileUpload.name
}`,
`${zconfig.core.return_https ? 'https' : 'http'}://${req.headers.host}${
zconfig.uploader.route === '/' ? '' : zconfig.uploader.route
}/${invis ? invis.invis : fileUpload.name}`
);
await sendUpload(user, fileUpload, `${domain}/r/${invis ? invis.invis : fileUpload.name}`, responseUrl);
}
if (zconfig.exif.enabled && zconfig.exif.remove_gps && fileUpload.mimetype.startsWith('image/')) {