feat: check for quota on upload
This commit is contained in:
parent
5a415586b7
commit
89a6efb4a3
|
@ -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
|
||||||
|
|
52
src/store.ts
52
src/store.ts
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue