@forge/manifest
12.1.0-next.2-experimental-d99730712.1.0-next.3-experimental-44a932f
out/validators/permissions-validator.jsout/validators/permissions-validator.js+25
Index: package/out/validators/permissions-validator.js
===================================================================
--- package/out/validators/permissions-validator.js
+++ package/out/validators/permissions-validator.js
@@ -69,8 +69,20 @@
/^sha512-[a-zA-Z0-9=+/]{88}$/
];
return BASE_64_HASH_PATTERNS.some((pattern) => pattern.test(cspString));
}
+ hasPathComponent(url) {
+ try {
+ const protocolRegex = /^(.*?:\/\/)/;
+ const urlWithProtocol = protocolRegex.test(url) ? url : `https://${url}`;
+ const parsedUrl = new url_1.URL(urlWithProtocol);
+ const pathname = parsedUrl.pathname;
+ return pathname.length > 0 && pathname !== '/';
+ }
+ catch {
+ return false;
+ }
+ }
addValidationErrors(result, element, values, manifest) {
values.forEach((value) => {
result.push({
message: text_1.errors.permissions.invalidPermission(element, value),
@@ -114,8 +126,21 @@
});
});
}
}
+ if (extPermType === 'external.fetch.backend') {
+ const urlsWithPaths = perms?.filter((key) => this.hasPathComponent(key));
+ if (urlsWithPaths?.length) {
+ urlsWithPaths.forEach((url) => {
+ result.push({
+ message: text_1.errors.permissions.backendEgressPathIgnored(url),
+ reference: text_1.References.Permissions,
+ level: 'warning',
+ ...(0, utils_1.findPosition)(url, manifest.yamlContentByLine)
+ });
+ });
+ }
+ }
}
async validate(manifest) {
if (!manifest || !manifest.typedContent || !manifest.typedContent.permissions) {
return {