mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 16:13:15 +00:00
Stalwart 1.0 checks names more strictly than its capability says: a reserved name may not be the stem either (`con.txt`, `Aux.tar.gz`), and control characters are refused (macOS `Icon\r`). Names over 255 bytes of UTF-8 were never accepted. Uploaded names are now made acceptable before they are sent: control characters become "_", a reserved stem gets "_" after it (`con.txt` becomes `con_.txt`), and a long name is shortened, keeping its extension. The rename and new-folder dialogs refuse such names with their own messages. The rules apply wherever the server publishes naming rules, so 0.16.6 to 0.16.23 get `con_.txt` too. One refused file used to abort a whole upload. Uploads now go on and report the files that failed at the end, and a folder upload skips the contents of a folder it could not create instead of dropping them into the folder the upload started in. What would sit deeper than 1.0's `maxFileNodeDepth` (64) is left out before it is uploaded, and a folder copy that would go past it fails before the first create. File errors keep their JMAP type, and the Files toasts now say why an action failed: too many files or folders (`overQuota`), folders nested too deeply, a refused name, missing rights, or a file too large. New and copied files get a bare lowercase media type, which 1.0 requires.
41 lines
1.5 KiB
TypeScript
41 lines
1.5 KiB
TypeScript
import { jmapError, jmapErrorProperties, jmapErrorType } from '@/lib/jmap/jmap-error';
|
|
|
|
/**
|
|
* Why a FileNode write failed, from the SetError the JMAP client threw
|
|
* (see jmapError), for the Files toasts to explain under their own title.
|
|
*/
|
|
export type FileErrorKind = 'overQuota' | 'tooDeep' | 'invalidName' | 'forbidden' | 'tooLarge';
|
|
|
|
// Stalwart 1.0's description for a node past maxFileNodeDepth.
|
|
const TOO_DEEP = 'Maximum folder depth exceeded.';
|
|
|
|
/** The error for a node that would sit deeper than the server allows, worded as Stalwart 1.0 does. */
|
|
export function folderDepthError(): Error {
|
|
return jmapError(TOO_DEEP, { type: 'invalidProperties', properties: ['parentId'] });
|
|
}
|
|
|
|
export function fileErrorKind(error: unknown): FileErrorKind | null {
|
|
switch (jmapErrorType(error)) {
|
|
// Stalwart 1.0, once an administrator limits files or folders per account.
|
|
case 'overQuota':
|
|
return 'overQuota';
|
|
// 1.0 for content over 4 GiB.
|
|
case 'tooLarge':
|
|
return 'tooLarge';
|
|
case 'forbidden':
|
|
return 'forbidden';
|
|
case 'invalidProperties': {
|
|
const properties = jmapErrorProperties(error);
|
|
if (properties.includes('name')) return 'invalidName';
|
|
// `parentId` is refused for other reasons too (the folder is gone, a
|
|
// folder moved into itself); only the description tells depth apart.
|
|
if (properties.includes('parentId') && error instanceof Error && /depth/i.test(error.message)) {
|
|
return 'tooDeep';
|
|
}
|
|
return null;
|
|
}
|
|
default:
|
|
return null;
|
|
}
|
|
}
|