feat: Add alternate mimetype support, enhance validation for alternate mimetypes, and improve script loading performance
All checks were successful
CI / container-job (push) Successful in 36s
All checks were successful
CI / container-job (push) Successful in 36s
- mime_type.ts: Added a new column `public alternate_mimetype: string;` - MimetypeController.ts: Extended validation and storage logic to accommodate the new `alternate_mimetype` attribute - adonisrc.ts: Integrated new validation rule to validate user-provided mimetypes - vite.ts: Set `defer: true` for script attributes to improve loading performance - update_1_to_mime_types.ts: Added migration for the new `alternate_mimetype` column in the database - UI improvements: Updated components such as AsideMenuLayer.vue, FormCheckRadioGroup.vue, MimeTypeInput.vue, NavBar.vue (lime-green background), NavBarMenu.vue, SectionBannerStarOnGitea.vue, Admin/mimetype/Create.vue, Admin/mimetype/Delete.vue, Admin/mimetype/Index.vue - allowed_extensions_mimetype.ts: Enhanced rule to also check for alternate mimetypes - referenceValidation.ts: Improved validation to allow only ISBNs with a '-' delimiter - package-lock.json: Updated npm dependencie
This commit is contained in:
parent
4c5a8f5a42
commit
a3031169ca
20 changed files with 719 additions and 704 deletions
|
@ -14,10 +14,6 @@ import MimeType from '#models/mime_type';
|
|||
/**
|
||||
* Options accepted by the unique rule
|
||||
*/
|
||||
// type Options = {
|
||||
// mainLanguageField: string;
|
||||
// typeField: string;
|
||||
// };
|
||||
type Options = {
|
||||
// size: string | number;
|
||||
// extnames: string[];
|
||||
|
@ -26,13 +22,8 @@ type Options = {
|
|||
allowedMimeTypes: string[];
|
||||
};
|
||||
|
||||
|
||||
// async function allowedMimetypeExtensions(file: VineMultipartFile | unknown, options: Options | unknown, field: FieldContext) {
|
||||
async function allowedMimetypeExtensions(file: VineMultipartFile | unknown, options: Options, field: FieldContext) {
|
||||
// if (typeof value !== 'string' && typeof value != 'number') {
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (!isBodyParserFile(file)) {
|
||||
return;
|
||||
}
|
||||
|
@ -41,10 +32,18 @@ async function allowedMimetypeExtensions(file: VineMultipartFile | unknown, opti
|
|||
const fileExtension = validatedFile?.extname?.toLocaleLowerCase() as string; // Get file extension from the file
|
||||
|
||||
// validate if file extension is allowed in combination with mimetype
|
||||
const mimeRecord = await MimeType.query().select('file_extension').where('name', mimeType).andWhere('enabled', true).first();
|
||||
let mimeRecord = await MimeType.query().select('file_extension').where('name', mimeType).andWhere('enabled', true).first();
|
||||
|
||||
if (!mimeRecord) {
|
||||
const allowedMimetypes = await MimeType.query().select('name').where('enabled', true)
|
||||
mimeRecord = await MimeType.query()
|
||||
.select('file_extension')
|
||||
.whereRaw("? = ANY (string_to_array(alternate_mimetype, '|'))", [mimeType])
|
||||
.andWhere('enabled', true)
|
||||
.first();
|
||||
}
|
||||
|
||||
if (!mimeRecord) {
|
||||
const allowedMimetypes = await MimeType.query().select('name').where('enabled', true);
|
||||
// Transform allowed MIME types to a concatenated string
|
||||
const allowedMimetypesString = allowedMimetypes.map((mime) => mime.name).join(', ');
|
||||
// throw new Error('Invalid MIME type');
|
||||
|
|
|
@ -76,7 +76,8 @@ async function validateReference(value: unknown, options: Options, field: FieldC
|
|||
}
|
||||
}
|
||||
} else if (type === ReferenceIdentifierTypes.ISBN) {
|
||||
if (!/^(?=(?:[^0-9]*[0-9]){10}(?:(?:[^0-9]*[0-9]){3})?$)[\d-]+$/.test(value)) {
|
||||
const isbnRegex = /^(?:\d{1,5}-\d{1,7}-\d{1,7}-[\dX]$|97[89]-\d{1,5}-\d{1,7}-\d{1,7}-\d)$/;
|
||||
if (!isbnRegex.test(value)) {
|
||||
field.report('The {{ field }} must be a valid ISBN', 'validateReference', field);
|
||||
} else {
|
||||
try {
|
||||
|
|
29
start/rules/valid_mimetype.ts
Normal file
29
start/rules/valid_mimetype.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { FieldContext } from '@vinejs/vine/types';
|
||||
import vine from '@vinejs/vine';
|
||||
import { VineString } from '@vinejs/vine';
|
||||
|
||||
async function isValidMimetype(value: unknown, options: unknown, field: FieldContext) {
|
||||
if (typeof value !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Regex pattern to match valid mimetypes (e.g., "application/json", "text/html")
|
||||
const mimetypePattern = /^[a-zA-Z0-9!#$&^_.+-]+\/[a-zA-Z0-9!#$&^_.+-]+$/;
|
||||
if (!mimetypePattern.test(value)) {
|
||||
field.report('The given value is not a valid mimetype', 'isValidMimetype', field);
|
||||
}
|
||||
}
|
||||
|
||||
export const isValidMimetypeRule = vine.createRule(isValidMimetype);
|
||||
|
||||
declare module '@vinejs/vine' {
|
||||
interface VineString {
|
||||
isValidMimetype(): this;
|
||||
}
|
||||
}
|
||||
|
||||
VineString.macro('isValidMimetype', function (this: VineString) {
|
||||
return this.use(isValidMimetypeRule());
|
||||
});
|
||||
|
||||
|
Loading…
Add table
editor.link_modal.header
Reference in a new issue