Goal
AEM Cloud Version : 2021.4.5226.20210427T070726Z-210325 (April 27, 2021)
Maximum asset size for uploads from AEM UI can be configured by overlaying /libs/dam/gui/content/assets/jcr:content/actions/secondary/create/items/fileupload@sizeLimit in /apps, however if the requirement is to configure limit per asset type (eg. jpg, png, mp4 etc.) the following extension could be useful....
Demo | Package Install | Github
Error shown in UI
Custom Configuration Nav
Configure Limit
https://author-pxxxx-exxxx.adobeaemcloud.com/apps/eaem-cs-restrict-assets-size/dam-tools/eaem-dam-config.html/conf/global/settings/dam/eaem-dam-config
Limit Saved in CRX
Solution
1) Create a custom widget /apps/eaem-cs-restrict-assets-size/dam-tools/textfield/textfield.jsp to read the values from config resource /conf/global/settings/dam/eaem-dam-config
<%@include file="/libs/granite/ui/global.jsp" %>
<%@page session="false"
import="com.adobe.granite.ui.components.AttrBuilder,
com.adobe.granite.ui.components.Config,
com.adobe.granite.ui.components.Tag" %>
<%
Config cfg = cmp.getConfig();
String CONFIG_RES = "/conf/global/settings/dam/eaem-dam-config";
Resource configRes = resourceResolver.getResource(CONFIG_RES);
String name = cfg.get("name", String.class);
String value = "";
if(configRes != null){
value = configRes.getValueMap().get(name, String.class);
}
if(value == null){
value = cfg.get("defaultValue", String.class);
}
if(value == null){
value = "";
}
Tag tag = cmp.consumeTag();
AttrBuilder attrs = tag.getAttrs();
cmp.populateCommonAttrs(attrs);
attrs.add("name", name);
String fieldLabel = cfg.get("fieldLabel", String.class);
String fieldDesc = cfg.get("fieldDescription", String.class);
%>
<div class="coral-Form-fieldwrapper">
<label class="coral-Form-fieldlabel"><%=fieldLabel%></label>
<input is="coral-textfield" name="<%=name%>" value="<%=value%>" style="width: 100%;">
<coral-icon class="coral-Form-fieldinfo" icon="infoCircle" size="S"></coral-icon>
<coral-tooltip target="_prev" placement="left" class="coral3-Tooltip" variant="info" role="tooltip" style="display: none;">
<coral-tooltip-content><%=fieldDesc%></coral-tooltip-content>
</coral-tooltip>
</div>
2) Create the tools navigation /apps/cq/core/content/nav/tools/eaem-dam-tools/eaem-dam-config
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:description="EAEM Custom Configuration"
jcr:primaryType="nt:unstructured"
jcr:title="EAEM Configuration"
href="/apps/eaem-cs-restrict-assets-size/dam-tools/eaem-dam-config.html/conf/global/settings/dam/eaem-dam-config"
icon="asset"
id="eaem-dam-config"
size="XL"/>
3) Create the configuration page /apps/eaem-cs-restrict-assets-size/dam-tools/eaem-dam-config saving max upload limits to /conf/global/settings/dam/eaem-dam-config accessed using Tools> EAEM Configuration> EAEM Configuration or https://author-pxxxxx-exxxxx.adobeaemcloud.com/apps/eaem-cs-restrict-assets-size/dam-tools/eaem-dam-config.html/conf/global/settings/dam/eaem-dam-config
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="cq:Page">
<jcr:content
jcr:mixinTypes="[sling:VanityPath]"
jcr:primaryType="nt:unstructured"
jcr:title="EAEM DAM Configuration"
sling:resourceType="granite/ui/components/coral/foundation/page">
<head jcr:primaryType="nt:unstructured">
<favicon
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/page/favicon"/>
<viewport
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/admin/page/viewport"/>
<clientlibs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/includeclientlibs"
categories="[coralui3,granite.ui.coral.foundation,granite.ui.shell,dam.gui.admin.coral]"/>
</head>
<body
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/page/body">
<items jcr:primaryType="nt:unstructured">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form"
action="/conf/global/settings/dam/eaem-dam-config"
foundationForm="{Boolean}true"
maximized="{Boolean}true"
method="post"
novalidate="{Boolean}true"
style="vertical">
<successresponse
jcr:primaryType="nt:unstructured"
jcr:title="Success"
sling:resourceType="granite/ui/components/coral/foundation/form/responses/openprompt"
open="/assets.html"
redirect="/apps/eaem-cs-restrict-assets-size/dam-tools/eaem-dam-config.html/conf/global/settings/dam/eaem-dam-config"
text="Configuration saved"/>
<items jcr:primaryType="nt:unstructured">
<type
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/hidden"
name="./jcr:primaryType"
value="nt:unstructured"/>
<wizard
jcr:primaryType="nt:unstructured"
jcr:title="Configuration"
sling:resourceType="granite/ui/components/coral/foundation/wizard">
<items jcr:primaryType="nt:unstructured">
<area
jcr:primaryType="nt:unstructured"
jcr:title="Configure Thumbnails"
sling:resourceType="granite/ui/components/coral/foundation/container"
maximized="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<columns
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
margin="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<png-size
jcr:primaryType="nt:unstructured"
sling:resourceType="/apps/eaem-cs-restrict-assets-size/dam-tools/textfield"
fieldDescription="Enter the max size allowed for PNG upload, in bytes..."
fieldLabel="PNG upload max size allowed"
name="./pngSize"/>
<jpg-size
jcr:primaryType="nt:unstructured"
sling:resourceType="/apps/eaem-cs-restrict-assets-size/dam-tools/textfield"
fieldDescription="Enter the max size allowed for JPG upload, in bytes..."
fieldLabel="JPG upload max size allowed"
name="./jpgSize"/>
<mp4-size
jcr:primaryType="nt:unstructured"
sling:resourceType="/apps/eaem-cs-restrict-assets-size/dam-tools/textfield"
fieldDescription="Enter the max size allowed for MP4 upload, in bytes..."
fieldLabel="MP4 upload max size allowed"
name="./mp4Size"/>
</items>
</column>
</items>
</columns>
</items>
<parentConfig jcr:primaryType="nt:unstructured">
<prev
granite:class="foundation-wizard-control"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/anchorbutton"
href="/aem/start.html"
text="Cancel">
<granite:data
jcr:primaryType="nt:unstructured"
foundation-wizard-control-action="cancel"/>
</prev>
<next
granite:class="foundation-wizard-control"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/button"
text="Save"
type="submit"
variant="primary">
<granite:data
jcr:primaryType="nt:unstructured"
foundation-wizard-control-action="next"/>
</next>
</parentConfig>
</area>
</items>
</wizard>
</items>
</content>
</items>
</body>
</jcr:content>
</jcr:root>
4) Create a clientlib /apps/eaem-cs-restrict-assets-size/supported-file-sizes with categories=dam.gui.coral.fileupload and dependencies=eaem.lodash
(function ($, $document) {
"use strict";
var _ = window._,
CONFIG_PATH = "/conf/global/settings/dam/eaem-dam-config.json",
allowedSizes = {},
ENDS_WITH_SIZE = "Size";
loadAllowedSizes();
var _origConfirmUpload = window.DamFileUpload.prototype._confirmUpload,
_origOnInputChange = window.Dam.ChunkFileUpload.prototype._onInputChange;
window.Dam.ChunkFileUpload.prototype._onInputChange = function(event){
var files = event.target.files;
if(!files && event.dataTransfer && event.dataTransfer.files){
files = event.dataTransfer.files;
}
if(_.isEmpty(files)){
_origOnInputChange.call(this, event);
return;
}
var errorMessage = "";
_.each(files, function(file){
var fileErrorMessage = checkWithinSize(file);
if(!fileErrorMessage){
return;
}
errorMessage = errorMessage + fileErrorMessage;
});
if(errorMessage){
showAlert(errorMessage);
}else{
_origOnInputChange.call(this, event);
}
};
window.DamFileUpload.prototype._confirmUpload = function (event) {
var errorMessage = "";
this.fileUpload.uploadQueue.forEach(function(item) {
var fileErrorMessage = checkWithinSize(item);
if(!fileErrorMessage){
return;
}
errorMessage = errorMessage + fileErrorMessage;
});
if(errorMessage){
showAlert(errorMessage);
}else{
_origConfirmUpload.call(this, event);
}
};
function checkWithinSize(file){
var fileName = file.name, errorMessage = "";
if(!fileName.includes(".")){
return;
}
var ext = fileName.substring(fileName.lastIndexOf(".") + 1);
_.each(allowedSizes, function(allowedSize, fileType){
if(fileType !== ext){
return;
}
if(file.size > allowedSize){
errorMessage = "<b>" + fileName + "</b> size <b>" + formatBytes(file.size, 2)
+ "</b> is more than allowed <b>" + formatBytes(allowedSize, 2) + "</b>";
}
});
return errorMessage;
}
function loadAllowedSizes(){
$.ajax(CONFIG_PATH).done(function(data){
if(_.isEmpty(data)){
return;
}
_.each(data, function(value, key){
if(!key.endsWith(ENDS_WITH_SIZE)){
return;
}
allowedSizes[key.substring(0, key.lastIndexOf(ENDS_WITH_SIZE))] = parseInt(value);
})
})
}
function formatBytes(bytes, decimals) {
if (bytes === 0){
return '0 Bytes';
}
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + '' + sizes[i];
}
function showAlert(message, title, callback){
var fui = $(window).adaptTo("foundation-ui"),
options = [{
id: "ok",
text: "OK",
primary: true
}];
message = message || "Unknown Error";
title = title || "Error";
fui.prompt(title, message, "warning", options, callback);
}
}(jQuery, jQuery(document)));