feat: check for quota on upload

This commit is contained in:
b1ek 2024-05-11 20:26:34 +10:00
parent 5a415586b7
commit 89a6efb4a3
Signed by: blek
GPG Key ID: 14546221E3595D0C
2 changed files with 51 additions and 3 deletions

View File

@ -8,7 +8,7 @@ import {
ValidationError, ValidationError,
} from '../errors.js'; } from '../errors.js';
import { config } from '../config.js'; import { config } from '../config.js';
import { save } from '../store.js'; import { getTakenQuota, save } from '../store.js';
type UploadPayload = { type UploadPayload = {
data: string; // base64-encoded data: string; // base64-encoded

View File

@ -3,14 +3,62 @@ import { config } from './config.js';
import path from 'path'; import path from 'path';
import fsp from 'node:fs/promises'; import fsp from 'node:fs/promises';
function getClient(
clientName: string,
): { name: string; quota: number } | undefined {
const client = config.clients.find((x) => x.name === clientName) as
| { name: string; quota: number; keySha256Sum?: string }
| undefined;
delete client?.keySha256Sum;
return client;
}
function getClientOrThrowErr(
clientName: string,
error?: string,
): { name: string; quota: number } {
const client = getClient(clientName);
if (typeof client === 'undefined')
throw Error(error ?? 'Client does not exist.');
return client;
}
export function getPathFor(name: string, clientName: string): string { export function getPathFor(name: string, clientName: string): string {
return path.join(config.storePath, clientName + '-' + name); return path.join(config.storePath, clientName + '-' + name);
} }
export async function getFilesFor(clientName: string): Promise<string[]> {
const files = await fsp.readdir(config.storePath);
return files.filter((x) => x.startsWith(clientName + '-'));
}
/**
* @returns { number } In megabytes
*/
export async function getTakenQuota(clientName: string): Promise<number> {
const files = await getFilesFor(clientName);
const stats = await Promise.all(
files.map((x) => fsp.stat(path.join(config.storePath, x))),
);
let size = 0;
stats.forEach((x) => (size += x.size));
return size / 1000000;
}
export async function save( export async function save(
data: string | Buffer | NodeJS.ArrayBufferView, data: Buffer,
name: string, name: string,
clientName: string, clientName: string,
): Promise<undefined> { ): Promise<undefined | 'Quota exceeded'> {
const client = getClientOrThrowErr(clientName);
const quota = await getTakenQuota(clientName);
if (data.length + quota > client.quota) {
return 'Quota exceeded';
}
await fsp.writeFile(getPathFor(name, clientName), data); await fsp.writeFile(getPathFor(name, clientName), data);
} }