mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-11-02 16:15:39 +00:00
37 lines
1.4 KiB
TypeScript
37 lines
1.4 KiB
TypeScript
import { createHash } from 'node:crypto';
|
|
import { InvalidStoreKeyError } from './types';
|
|
|
|
// One path segment: letters, digits and . _ @ + ~ -, but never "." or "..".
|
|
const SEGMENT = /^(?!\.{1,2}$)[A-Za-z0-9._@+~-]{1,200}$/;
|
|
const NAME = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
|
|
/** A document id: one or more segments joined by "/". Throws on anything else. */
|
|
export function assertDocId(id: string): void {
|
|
if (typeof id !== 'string' || id.length === 0 || id.length > 1024) throw new InvalidStoreKeyError(String(id));
|
|
for (const segment of id.split('/')) {
|
|
if (!SEGMENT.test(segment)) throw new InvalidStoreKeyError(id);
|
|
}
|
|
}
|
|
|
|
/** A collection, log or lease name. */
|
|
export function assertName(name: string): void {
|
|
if (!NAME.test(name)) throw new InvalidStoreKeyError(name);
|
|
}
|
|
|
|
/** A kv or counter key: anything printable without control characters, at most 512 chars. */
|
|
export function assertKey(key: string): void {
|
|
// eslint-disable-next-line no-control-regex
|
|
if (typeof key !== 'string' || key.length === 0 || key.length > 512 || /[\u0000-\u001f\u007f]/.test(key)) {
|
|
throw new InvalidStoreKeyError(String(key));
|
|
}
|
|
}
|
|
|
|
/** The version of a document: changes whenever its bytes do. */
|
|
export function versionOf(data: Buffer): string {
|
|
return createHash('sha256').update(data).digest('base64url').slice(0, 22);
|
|
}
|
|
|
|
export function toBuffer(data: Buffer | string): Buffer {
|
|
return typeof data === 'string' ? Buffer.from(data, 'utf8') : data;
|
|
}
|