Add size and owner fields to files
This commit is contained in:
parent
f6d9db6243
commit
6db8b1cd21
@ -1,7 +1,7 @@
|
||||
import Controller from "wms-core/Controller";
|
||||
import {REQUIRE_AUTH_MIDDLEWARE} from "wms-core/auth/AuthComponent";
|
||||
import {Request, Response, Router} from "express";
|
||||
import {BadRequestError, NotFoundHttpError, ServerError} from "wms-core/HttpError";
|
||||
import {BadRequestError, ForbiddenHttpError, NotFoundHttpError, ServerError} from "wms-core/HttpError";
|
||||
import FileModel from "../models/FileModel";
|
||||
import {cryptoRandomDictionary} from "wms-core/Utils";
|
||||
import config from "config";
|
||||
@ -19,10 +19,10 @@ export default class FileController extends Controller {
|
||||
this.get('/files/:page?', this.getFileManager, 'file-manager', REQUIRE_AUTH_MIDDLEWARE);
|
||||
this.get('/files/delete/:slug', this.deleteFile, 'delete-file-frontend', REQUIRE_AUTH_MIDDLEWARE);
|
||||
|
||||
this.get('/:slug', this.downloadFile, 'get-file');
|
||||
this.post('/', this.postFile, 'post-file', REQUIRE_AUTH_MIDDLEWARE);
|
||||
this.delete('/delete/:slug', this.deleteFile, 'delete-file', REQUIRE_AUTH_MIDDLEWARE);
|
||||
this.get('/:slug', this.downloadFile, 'get-file');
|
||||
this.put('/:slug', this.putFile, 'put-file', REQUIRE_AUTH_MIDDLEWARE);
|
||||
this.delete('/:slug', this.deleteFile, 'delete-file', REQUIRE_AUTH_MIDDLEWARE);
|
||||
}
|
||||
|
||||
protected async getFileManager(req: Request, res: Response): Promise<void> {
|
||||
@ -33,6 +33,7 @@ export default class FileController extends Controller {
|
||||
}
|
||||
|
||||
protected async downloadFile(req: Request, res: Response): Promise<void> {
|
||||
console.log('heeey');
|
||||
const file = await FileModel.getBySlug(req.params.slug);
|
||||
if (!file || file.shouldBeDeleted()) throw new NotFoundHttpError('File', req.url);
|
||||
|
||||
@ -71,10 +72,12 @@ export default class FileController extends Controller {
|
||||
else if (req.body.expire_after_days !== undefined) ttl = parseInt(req.body.expire_after_days) * 24 * 3600;
|
||||
|
||||
const file = new FileModel({
|
||||
user_id: req.models.user!.id,
|
||||
slug: slug,
|
||||
real_name: upload.originalname,
|
||||
storage_type: 'local',
|
||||
storage_path: 'storage/uploads/' + slug,
|
||||
size: upload.size,
|
||||
ttl: ttl,
|
||||
});
|
||||
|
||||
@ -94,8 +97,12 @@ export default class FileController extends Controller {
|
||||
}
|
||||
|
||||
protected async deleteFile(req: Request, res: Response): Promise<void> {
|
||||
const slug = req.params.slug;
|
||||
if (!slug) throw new BadRequestError('Cannot delete nothing.', 'Please provide a slug.', req.url);
|
||||
|
||||
const file = await FileModel.getBySlug(req.params.slug);
|
||||
if (!file) throw new NotFoundHttpError('File', req.url);
|
||||
if (!file.canDelete(req.models.user!.id!)) throw new ForbiddenHttpError('file', req.url);
|
||||
|
||||
switch (file.storage_type) {
|
||||
case 'local':
|
||||
|
@ -5,10 +5,12 @@ export default class CreateFilesTable extends Migration {
|
||||
public async install(connection: Connection): Promise<void> {
|
||||
await this.query('CREATE TABLE files(' +
|
||||
'id INT NOT NULL AUTO_INCREMENT,' +
|
||||
'user_id INT NOT NULL,' +
|
||||
'slug VARCHAR(259) UNIQUE NOT NULL,' +
|
||||
'real_name VARCHAR(259) NOT NULL,' +
|
||||
'storage_type VARCHAR(64) NOT NULL,' +
|
||||
'storage_path VARCHAR(1745) NOT NULL,' +
|
||||
'size INT UNSIGNED NOT NULL,' +
|
||||
'created_at DATETIME NOT NULL DEFAULT NOW(),' +
|
||||
'ttl INT UNSIGNED NOT NULL,' +
|
||||
'PRIMARY KEY (id)' +
|
||||
|
@ -2,6 +2,7 @@ import Model from "wms-core/db/Model";
|
||||
import Validator from "wms-core/db/Validator";
|
||||
import Controller from "wms-core/Controller";
|
||||
import config from "config";
|
||||
import User from "wms-core/auth/models/User";
|
||||
|
||||
export default class FileModel extends Model {
|
||||
public static get table(): string {
|
||||
@ -13,18 +14,22 @@ export default class FileModel extends Model {
|
||||
return models.length > 0 ? models[0] : null;
|
||||
}
|
||||
|
||||
public readonly user_id!: number;
|
||||
public readonly slug!: string;
|
||||
public readonly real_name!: string;
|
||||
public readonly storage_type!: FileStorage;
|
||||
public readonly storage_path!: string;
|
||||
public readonly size!: number;
|
||||
public created_at?: Date;
|
||||
public readonly ttl!: number;
|
||||
|
||||
protected defineProperties() {
|
||||
this.defineProperty('user_id', new Validator().defined().exists(User, 'id'));
|
||||
this.defineProperty('slug', new Validator().defined().minLength(1).maxLength(259).unique(this, 'slug'));
|
||||
this.defineProperty('real_name', new Validator().defined().minLength(1).maxLength(259));
|
||||
this.defineProperty('storage_type', new Validator().defined().maxLength(64));
|
||||
this.defineProperty('storage_path', new Validator().defined().maxLength(1745));
|
||||
this.defineProperty('size', new Validator().defined().min(0));
|
||||
this.defineProperty('created_at', new Validator());
|
||||
this.defineProperty('ttl', new Validator().defined().min(0).max(4294967295));
|
||||
}
|
||||
@ -47,6 +52,10 @@ export default class FileModel extends Model {
|
||||
if (!expirationDate) return false;
|
||||
return new Date().getTime() >= expirationDate.getTime();
|
||||
}
|
||||
|
||||
public canDelete(user_id: number): boolean {
|
||||
return this.user_id === user_id;
|
||||
}
|
||||
}
|
||||
|
||||
export type FileStorage = 'local';
|
||||
|
@ -34,9 +34,11 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>url</th>
|
||||
<th>name</th>
|
||||
<th>URL</th>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Expires at</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@ -51,8 +53,12 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>{{ file.real_name }}</td>
|
||||
<td>{{ (file.size / (1024 * 1024)).toFixed(2) }}MB</td>
|
||||
{% set expires_at = file.getExpirationDate() %}
|
||||
<td>{% if expires_at %}{{ expires_at.toISOString() }}{% else %}Never{% endif %}</td>
|
||||
<td>
|
||||
<a href="{{ route('delete-file-frontend', file.slug) }}" class="button danger"><i data-feather="trash"></i> Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
Loading…
Reference in New Issue
Block a user