Skip to content

Commit

Permalink
convert last classes & misc changes
Browse files Browse the repository at this point in the history
  • Loading branch information
inetol committed Nov 25, 2024
1 parent c11008d commit 190cf79
Show file tree
Hide file tree
Showing 25 changed files with 139 additions and 137 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"dependencies": {
"@hono/zod-openapi": "~0.18.0",
"env-var": "~7.5.0",
"hono": "~4.6.10"
"hono": "~4.6.12"
},
"devDependencies": {
"@biomejs/biome": "~1.9.4",
Expand Down
8 changes: 4 additions & 4 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { env } from '@x-util/env.ts';

export const config = {
protocol: env.tls ? 'https://' : 'http://',
apiPath: '/api',
storagePath: 'storage/',
documentNameLengthMin: 2,
documentNameLengthDefault: 8,
documentNameLengthMax: 32,
documentNameLengthDefault: 8
documentNameLengthMin: 2,
protocol: env.tls ? 'https://' : 'http://',
storagePath: 'storage/'
} as const;
27 changes: 13 additions & 14 deletions src/document/validator.ts → src/document/assert.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { validator } from '@x-util/validator.ts';
import { config } from '../config.ts';
import { errorHandler } from '../server/errorHandler.ts';
import type { Document } from '../types/Document.ts';
import { ErrorCode } from '../types/ErrorHandler.ts';
import { ValidatorUtils } from '../utils/ValidatorUtils.ts';
import { crypto } from './crypto.ts';

export const validator = {
validateName: (name: string): void => {
export const assert = {
name: (name: string): void => {
if (
!ValidatorUtils.isValidBase64URL(name) ||
!ValidatorUtils.isLengthWithinRange(
!validator.isBase64URL(name) ||
!validator.isLengthWithinRange(
Bun.stringWidth(name),
config.documentNameLengthMin,
config.documentNameLengthMax
Expand All @@ -19,39 +19,38 @@ export const validator = {
}
},

validateNameLength: (length: number | undefined): void => {
nameLength: (length?: number): void => {
if (
length &&
!ValidatorUtils.isLengthWithinRange(length, config.documentNameLengthMin, config.documentNameLengthMax)
!validator.isLengthWithinRange(length, config.documentNameLengthMin, config.documentNameLengthMax)
) {
errorHandler.send(ErrorCode.documentInvalidNameLength);
}
},

validatePassword: (password: string, dataHash: Document['header']['passwordHash']): void => {
password: (password: string, dataHash: Document['header']['passwordHash']): void => {
if (dataHash && !crypto.compare(password, dataHash)) {
errorHandler.send(ErrorCode.documentInvalidPassword);
}
},

validatePasswordLength: (password: string | undefined): void => {
passwordLength: (password?: string): void => {
if (
password &&
(ValidatorUtils.isEmptyString(password) ||
!ValidatorUtils.isLengthWithinRange(Bun.stringWidth(password), 1, 255))
(validator.isEmptyString(password) || !validator.isLengthWithinRange(Bun.stringWidth(password), 1, 255))
) {
errorHandler.send(ErrorCode.documentInvalidPasswordLength);
}
},

validateSecret: (secret: string, secretHash: Document['header']['secretHash']): void => {
secret: (secret: string, secretHash: Document['header']['secretHash']): void => {
if (!crypto.compare(secret, secretHash)) {
errorHandler.send(ErrorCode.documentInvalidSecret);
}
},

validateSecretLength: (secret: string): void => {
if (!ValidatorUtils.isLengthWithinRange(Bun.stringWidth(secret), 1, 255)) {
secretLength: (secret: string): void => {
if (!validator.isLengthWithinRange(Bun.stringWidth(secret), 1, 255)) {
errorHandler.send(ErrorCode.documentInvalidSecretLength);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/document/compression.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { type InputType, brotliCompressSync, brotliDecompressSync } from 'node:zlib';
import { constants as zlibConstants } from 'zlib';
import { type InputType, brotliCompressSync, brotliDecompressSync, constants as zlibConstants } from 'node:zlib';

export const compression = {
encode: (data: InputType): Buffer => {
Expand Down
1 change: 1 addition & 0 deletions src/document/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Buffer } from 'node:buffer';
import { randomBytes } from 'node:crypto';
import { CryptoHasher } from 'bun';

Expand Down
13 changes: 4 additions & 9 deletions src/document/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,14 @@ import { config } from '../config.ts';
import { errorHandler } from '../server/errorHandler.ts';
import type { Document } from '../types/Document.ts';
import { ErrorCode } from '../types/ErrorHandler.ts';
import { validator } from './validator.ts';

export const storage = {
read: async (name: string): Promise<Document> => {
validator.validateName(name);

const file = Bun.file(config.storagePath + name);

if (!(await file.exists())) {
errorHandler.send(ErrorCode.documentNotFound);
try {
return deserialize(await Bun.file(config.storagePath + name).arrayBuffer());
} catch {
return errorHandler.send(ErrorCode.documentNotFound);
}

return deserialize(await file.arrayBuffer());
},

write: async (name: string, document: Document): Promise<void> => {
Expand Down
3 changes: 3 additions & 0 deletions src/endpoints/v1/access.route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { config } from '../../config.ts';
import { compression } from '../../document/compression.ts';
import { storage } from '../../document/storage.ts';
Expand Down Expand Up @@ -49,6 +50,8 @@ export const accessRoute = (endpoint: OpenAPIHono): void => {
async (ctx) => {
const params = ctx.req.valid('param');

assert.name(params.name);

const document = await storage.read(params.name);

// V1 Endpoint does not support document protected password
Expand Down
3 changes: 3 additions & 0 deletions src/endpoints/v1/accessRaw.route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { config } from '../../config.ts';
import { compression } from '../../document/compression.ts';
import { storage } from '../../document/storage.ts';
Expand Down Expand Up @@ -43,6 +44,8 @@ export const accessRawRoute = (endpoint: OpenAPIHono): void => {
async (ctx) => {
const params = ctx.req.valid('param');

assert.name(params.name);

const document = await storage.read(params.name);

// V1 Endpoint does not support document protected password
Expand Down
6 changes: 3 additions & 3 deletions src/endpoints/v1/publish.route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { StringUtils } from '@x-util/StringUtils.ts';
import { string } from '@x-util/string.ts';
import { compression } from '../../document/compression.ts';
import { crypto } from '../../document/crypto.ts';
import { storage } from '../../document/storage.ts';
Expand Down Expand Up @@ -56,8 +56,8 @@ export const publishRoute = (endpoint: OpenAPIHono): void => {
route,
async (ctx) => {
const body = await ctx.req.arrayBuffer();
const name = await StringUtils.createName();
const secret = StringUtils.createSecret();
const name = await string.createName();
const secret = string.createSecret();

await storage.write(name, {
data: compression.encode(body),
Expand Down
6 changes: 4 additions & 2 deletions src/endpoints/v1/remove.route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { unlink } from 'node:fs/promises';
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { config } from '../../config.ts';
import { storage } from '../../document/storage.ts';
import { validator } from '../../document/validator.ts';
import { errorHandler, schema } from '../../server/errorHandler.ts';
import { ErrorCode } from '../../types/ErrorHandler.ts';

Expand Down Expand Up @@ -53,9 +53,11 @@ export const removeRoute = (endpoint: OpenAPIHono): void => {
const params = ctx.req.valid('param');
const headers = ctx.req.valid('header');

assert.name(params.name);

const document = await storage.read(params.name);

validator.validateSecret(headers.secret, document.header.secretHash);
assert.secret(headers.secret, document.header.secretHash);

const result = await unlink(config.storagePath + params.name)
.then(() => true)
Expand Down
6 changes: 4 additions & 2 deletions src/endpoints/v2/access.route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { storage } from '@x-document/storage.ts';
import { config } from '../../config.ts';
import { compression } from '../../document/compression.ts';
import { validator } from '../../document/validator.ts';
import { errorHandler, schema } from '../../server/errorHandler.ts';
import { ErrorCode } from '../../types/ErrorHandler.ts';

Expand Down Expand Up @@ -65,14 +65,16 @@ export const accessRoute = (endpoint: OpenAPIHono): void => {
const params = ctx.req.valid('param');
const headers = ctx.req.valid('header');

assert.name(params.name);

const document = await storage.read(params.name);

if (document.header.passwordHash) {
if (!headers.password) {
return errorHandler.send(ErrorCode.documentPasswordNeeded);
}

validator.validatePassword(headers.password, document.header.passwordHash);
assert.password(headers.password, document.header.passwordHash);
}

const buffer = compression.decode(document.data);
Expand Down
6 changes: 4 additions & 2 deletions src/endpoints/v2/accessRaw.route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { storage } from '@x-document/storage.ts';
import { config } from '../../config.ts';
import { compression } from '../../document/compression.ts';
import { validator } from '../../document/validator.ts';
import { errorHandler, schema } from '../../server/errorHandler.ts';
import { ErrorCode } from '../../types/ErrorHandler.ts';

Expand Down Expand Up @@ -62,14 +62,16 @@ export const accessRawRoute = (endpoint: OpenAPIHono): void => {
password: headers.password || query.p
};

assert.name(params.name);

const document = await storage.read(params.name);

if (document.header.passwordHash) {
if (!options.password) {
return errorHandler.send(ErrorCode.documentPasswordNeeded);
}

validator.validatePassword(options.password, document.header.passwordHash);
assert.password(options.password, document.header.passwordHash);
}

// @ts-ignore: Return the buffer directly
Expand Down
6 changes: 4 additions & 2 deletions src/endpoints/v2/edit.route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { storage } from '@x-document/storage.ts';
import { config } from '../../config.ts';
import { compression } from '../../document/compression.ts';
import { validator } from '../../document/validator.ts';
import { errorHandler, schema } from '../../server/errorHandler.ts';
import { middleware } from '../../server/middleware.ts';
import { ErrorCode } from '../../types/ErrorHandler.ts';
Expand Down Expand Up @@ -70,9 +70,11 @@ export const editRoute = (endpoint: OpenAPIHono): void => {
const params = ctx.req.valid('param');
const headers = ctx.req.valid('header');

assert.name(params.name);

const document = await storage.read(params.name);

validator.validateSecret(headers.secret, document.header.secretHash);
assert.secret(headers.secret, document.header.secretHash);

document.data = compression.encode(body);

Expand Down
4 changes: 2 additions & 2 deletions src/endpoints/v2/exists.route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { config } from '../../config.ts';
import { validator } from '../../document/validator.ts';
import { errorHandler, schema } from '../../server/errorHandler.ts';
import { ErrorCode } from '../../types/ErrorHandler.ts';

Expand Down Expand Up @@ -50,7 +50,7 @@ export const existsRoute = (endpoint: OpenAPIHono): void => {
async (ctx) => {
const params = ctx.req.valid('param');

validator.validateName(params.name);
assert.name(params.name);

return ctx.text(String(await Bun.file(config.storagePath + params.name).exists()));
},
Expand Down
16 changes: 8 additions & 8 deletions src/endpoints/v2/publish.route.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { storage } from '@x-document/storage.ts';
import { StringUtils } from '@x-util/StringUtils.ts';
import { string } from '@x-util/string.ts';
import { config } from '../../config.ts';
import { compression } from '../../document/compression.ts';
import { crypto } from '../../document/crypto.ts';
import { validator } from '../../document/validator.ts';
import { errorHandler, schema } from '../../server/errorHandler.ts';
import { middleware } from '../../server/middleware.ts';
import { DocumentVersion } from '../../types/Document.ts';
Expand Down Expand Up @@ -87,33 +87,33 @@ export const publishRoute = (endpoint: OpenAPIHono): void => {
const headers = ctx.req.valid('header');

if (headers.password) {
validator.validatePasswordLength(headers.password);
assert.passwordLength(headers.password);
}

let secret: string;

if (headers.secret) {
validator.validateSecretLength(headers.secret);
assert.secretLength(headers.secret);

secret = headers.secret;
} else {
secret = StringUtils.createSecret();
secret = string.createSecret();
}

let name: string;

if (headers.key) {
validator.validateName(headers.key);
assert.name(headers.key);

if (await StringUtils.nameExists(headers.key)) {
if (await string.nameExists(headers.key)) {
errorHandler.send(ErrorCode.documentNameAlreadyExists);
}

name = headers.key;
} else {
const nameLength = Number(headers.keylength || config.documentNameLengthDefault);

name = await StringUtils.createName(nameLength);
name = await string.createName(nameLength);
}

const data = compression.encode(body);
Expand Down
6 changes: 4 additions & 2 deletions src/endpoints/v2/remove.route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { unlink } from 'node:fs/promises';
import { type OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
import { assert } from '@x-document/assert.ts';
import { storage } from '@x-document/storage.ts';
import { config } from '../../config.ts';
import { validator } from '../../document/validator.ts';
import { errorHandler, schema } from '../../server/errorHandler.ts';
import { ErrorCode } from '../../types/ErrorHandler.ts';

Expand Down Expand Up @@ -52,9 +52,11 @@ export const removeRoute = (endpoint: OpenAPIHono): void => {
const params = ctx.req.valid('param');
const headers = ctx.req.valid('header');

assert.name(params.name);

const document = await storage.read(params.name);

validator.validateSecret(headers.secret, document.header.secretHash);
assert.secret(headers.secret, document.header.secretHash);

const result = await unlink(config.storagePath + params.name)
.then(() => true)
Expand Down
7 changes: 2 additions & 5 deletions src/types/Document.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
enum DocumentVersion {
export enum DocumentVersion {
V1 = 1
}

interface Document {
export interface Document {
data: Uint8Array;
header: {
name: string;
Expand All @@ -11,6 +11,3 @@ interface Document {
};
version: DocumentVersion;
}

export type { Document };
export { DocumentVersion };
Loading

0 comments on commit 190cf79

Please sign in to comment.