Skip to content

Commit

Permalink
feat: reenable file upload
Browse files Browse the repository at this point in the history
  • Loading branch information
bjarneo committed Aug 20, 2022
1 parent e3daa26 commit d59d7e8
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 8 deletions.
2 changes: 1 addition & 1 deletion config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const {
SECRET_REDIS_PASSWORD = null,
SECRET_REDIS_TLS = false,
SECRET_JWT_SECRET = 'good_luck_have_fun',
SECRET_DO_SPACES_ENDPOINT = 'https://ams3.digitaloceanspaces.com',
SECRET_DO_SPACES_ENDPOINT = 'https://fra1.digitaloceanspaces.com',
SECRET_DO_SPACES_KEY = '',
SECRET_DO_SPACES_SECRET = '',
SECRET_DO_SPACES_BUCKET = 'hemmelig',
Expand Down
3 changes: 3 additions & 0 deletions src/client/config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ export default {
api: {
host: 'http://localhost:3000/api',
},
settings: {
enableFileUpload: true,
},
};
53 changes: 50 additions & 3 deletions src/client/routes/home/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
Text,
Collapse,
Divider,
FileButton,
} from '@mantine/core';
import {
IconSquarePlus,
Expand All @@ -30,19 +31,23 @@ import {
IconHeading,
} from '@tabler/icons';

import config from '../../config';

import Error from '../../components/info/error';

import { getToken } from '../../helpers/token';
import { getToken, hasToken } from '../../helpers/token';

import { createSecret, burnSecret } from '../../api/secret';

const Home = () => {
const [text, setText] = useState('');
const [title, setTitle] = useState('');

const [enableFileUpload] = useState(config.get('settings.enableFileUpload', false));
const [file, setFile] = useState(null);
const [ttl, setTTL] = useState(14400);
const [password, setPassword] = useState('');
const [enablePassword, setOnEnablePassword] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(hasToken() ? true : false);
const [allowedIp, setAllowedIp] = useState('');
const [preventBurn, setPreventBurn] = useState(false);
const [formData, setFormData] = useState(null);
Expand Down Expand Up @@ -116,6 +121,7 @@ const Home = () => {
setPassword('');
setEncryptionKey('');
setAllowedIp('');
setFile('');
setPreventBurn(false);
setFormData(new FormData());
};
Expand All @@ -130,7 +136,7 @@ const Home = () => {
event.preventDefault();

formData.append('text', text);

formData.append('file', file);
formData.append('title', title);
formData.append('password', password);
formData.append('ttl', ttl);
Expand Down Expand Up @@ -257,6 +263,47 @@ const Home = () => {
/>
</Group>

<Group>
{enableFileUpload && (
<FileButton
onChange={setFile}
accept="image/*,application/pdf"
disabled={!isLoggedIn}
>
{(props) => (
<Button
{...props}
label={!isLoggedIn ? 'Sign in to upload images' : ''}
styles={() => ({
root: {
backgroundColor: 'var(--color-contrast)',

'&:hover': {
backgroundColor: 'var(--color-contrast)',
filter: 'brightness(115%)',
},
},
})}
>
Upload image
</Button>
)}
</FileButton>
)}

{enableFileUpload && !isLoggedIn && (
<Text size="sm" align="center" mt="sm">
Sign in to upload images
</Text>
)}

{file && (
<Text size="sm" align="center" mt="sm">
Picked file: {file.name}
</Text>
)}
</Group>

<Group>
<Stack>
<Button
Expand Down
16 changes: 14 additions & 2 deletions src/server/decorators/attachment-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,26 @@ const FileType = require('file-type');
const MAX_FILE_BYTES = 1024 * 16 * 1000; // 16mb - 16 024 000 bytes
const { upload } = require('../services/do');

function acceptedFileType(file) {
if (file.mimetype.startsWith('image/')) {
return true;
}

if (file.mimetype.startsWith('application/pdf')) {
return true;
}

return false;
}

module.exports = fp(async (fastify) => {
fastify.decorate('attachment', async (req, reply) => {
const file = await req.body.file;
const { encryptionKey } = req.secret;

// First release it will be images only. Have to look into how
// to solve this for the ext, and mime types for other files.
if (file?.filename && file.mimetype.startsWith('image/')) {
if (file?.filename && acceptedFileType(file)) {
try {
await req.jwtVerify();
} catch (err) {
Expand All @@ -37,7 +49,7 @@ module.exports = fp(async (fastify) => {
Object.assign(req.secret, { file: { ext, mime, key: imageData.key } });
}

if (file?.filename && !file.mimetype.startsWith('image/')) {
if (file?.filename && !acceptedFileType(file)) {
return reply.code(415).send({
error: `This file type "${file.mimetype}" is not supported, yet.`,
});
Expand Down
6 changes: 4 additions & 2 deletions src/server/services/do.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const s3 = new AWS.S3({
async function upload(encryptionKey, fileUpload) {
const filename = nanoid();

const encryptedFile = encrypt(fileUpload, encryptionKey);
const encryptedFile = encrypt(fileUpload.toString('hex'), encryptionKey);

const data = await s3
.upload({
Expand All @@ -43,7 +43,9 @@ async function download(key, encryptionKey) {

const { encryptedFile } = JSON.parse(data.Body);

return decrypt(encryptedFile, encryptionKey);
const file = decrypt(encryptedFile, encryptionKey);

return Buffer.from(file, 'hex');
}

async function remove(key) {
Expand Down

0 comments on commit d59d7e8

Please sign in to comment.