import fs from"node:fs";import path from"node:path";import crypto from"node:crypto";import{cleanHTML}from"./validators.mjs";import Files from"../files/files.mjs";import{expandObjectInPlace,isEmpty,isPlainObject}from"../../common/utils/helpers.mjs";import{DataField}from"../../common/data/fields.mjs";export function sanitizeTypeDataField(t,e,i){if(e.skipSystem)return t;const n=i.sanitization?.schema?.[this.name];return isEmpty(n)||_sanitizeObject(t,n,e,i,[this.name]),t}function _sanitizeObject(t,e,i,n,a){const s=1===Object.keys(e).length&&"*"in e;s||expandObjectInPlace(t,{shallow:!0});for(const[r,o]of Object.entries(t)){if(s&&r.includes(".")){const s=_resolveSanitizationField(e,r.split("."));s instanceof DataField&&!isPlainObject(o)&&!Array.isArray(o)?t[r]=s._sanitize(o,i,n):!s||s instanceof DataField||!isPlainObject(o)||_sanitizeObject(o,s,i,n,a.concat([r]))}const l=s?e["*"]:e[r];if(!l)continue;const c=a.concat([r]);if(l instanceof DataField)t[r]=l._sanitize(o,i,n);else if(Array.isArray(o)){let t=Array.isArray(l)?l[0]:l;if(1===Object.keys(l).length&&"*"in l&&(t=l["*"],c.push("*")),t instanceof DataField)for(let e=0;e<o.length;e++)o[e]=t._sanitize(o,i,n);else for(const e of o)_sanitizeObject(e,t,i,n,c)}else o instanceof Object&&_sanitizeObject(o,l,i,n,c)}}function _resolveSanitizationField(t,e){let i=t;for(const t of e){if(!i||"object"!=typeof i||i instanceof DataField)return;i=1===Object.keys(i).length&&"*"in i?i["*"]:i[t]}return i}export function sanitizeFilePathField(t,{assetPath:e,user:i},n){if(null==t||""===t)return t;if(this.texture&&t.startsWith("#"))return t;if("string"!=typeof t)return null;if(this.base64)return t;const a=t.match(/^data:([a-z]+)\/([a-z0-9]+);base64,(.*)/);if(!a)return t;if(i&&!i.can("FILES_UPLOAD"))throw new Error(`You lack FILES_UPLOAD permission and may not upload base64 data to the ${this.name} field.`);const[s,r]=a.slice(2,4),o=crypto.createHash("md5").update(t).digest("base64url"),l=`${this.fieldPath.split(".").filterJoin("-")}-${o}.${s}`,c=path.join(e,l);return n.sanitization.images||={},n.sanitization.images[c]=r,Files.standardizePath(path.relative(global.paths.data,c))}export function commitSanitizedImage(t,e){const i=path.dirname(t);fs.mkdirSync(i,{recursive:!0}),fs.writeFileSync(t,Buffer.from(e,"base64")),global.logger.info(`Persisted base64 image to "${t}"`)}export function sanitizeHTMLField(t,e,i){return null==t||""===t?t:"string"!=typeof t?"":cleanHTML(t)}export function sanitizeDocumentOwnershipField(t,{user:e},i){if(!1!==e?.isGM)return t;let n=!1;for(const[a,s]of Object.entries(t))s!==i.model?.ownership[a]&&("default"===a?i.creation||(n=!0):a!==e.id&&(i.creation?delete t[a]:n=!0));if(n)throw new Error(`${this.fieldPath} may only be modified by a GM or Assistant GM user.`);return t}export function sanitizeDocumentAuthorField(t,{user:e},i){if(i.creation&&!1===e?.isGM)return e.id;if(!1===e?.isGM)throw new Error(`${this.fieldPath} may only be modified by a GM or Assistant GM user.`);return t}