0
Fork 0
mirror of https://github.com/penpot/penpot-plugins.git synced 2025-01-06 14:50:21 -05:00

feat(plugins-runtime): adds new permissions comment:read, comment:write and allow:downloads

This commit is contained in:
alonso.torres 2024-09-24 14:42:42 +02:00 committed by Alonso Torres
parent 86f98eb536
commit 5adbee2b23
10 changed files with 37 additions and 6 deletions

View file

@ -8,8 +8,9 @@ export const openUIApi = z
z.string(), z.string(),
z.string(), z.string(),
z.enum(['dark', 'light']), z.enum(['dark', 'light']),
openUISchema.optional() openUISchema.optional(),
z.boolean().optional()
) )
.implement((title, url, theme, options) => { .implement((title, url, theme, options, allowDownloads) => {
return createModal(title, url, theme, options); return createModal(title, url, theme, options, allowDownloads);
}); });

View file

@ -18,6 +18,9 @@ describe('Plugin api', () => {
'library:read', 'library:read',
'library:write', 'library:write',
'user:read', 'user:read',
'comment:read',
'comment:write',
'allow:downloads',
], ],
}, },
openModal: vi.fn(), openModal: vi.fn(),
@ -107,7 +110,7 @@ describe('Plugin api', () => {
name: 'test', name: 'test',
id: '123', id: '123',
revn: 0, revn: 0,
} as File; } as File;
pluginManager.context.getFile.mockImplementation(() => exampleFile); pluginManager.context.getFile.mockImplementation(() => exampleFile);

View file

@ -6,7 +6,8 @@ export function createModal(
name: string, name: string,
url: string, url: string,
theme: Theme, theme: Theme,
options?: OpenUIOptions options?: OpenUIOptions,
allowDownloads?: boolean
) { ) {
const modal = document.createElement('plugin-modal') as PluginModalElement; const modal = document.createElement('plugin-modal') as PluginModalElement;
@ -44,6 +45,10 @@ export function createModal(
modal.setAttribute('width', String(width)); modal.setAttribute('width', String(width));
modal.setAttribute('height', String(height)); modal.setAttribute('height', String(height));
if (allowDownloads) {
modal.setAttribute('allow-downloads', 'true');
}
document.body.appendChild(modal); document.body.appendChild(modal);
return modal; return modal;

View file

@ -32,6 +32,9 @@ describe('createPlugin', () => {
'library:read', 'library:read',
'library:write', 'library:write',
'user:read', 'user:read',
'comment:read',
'comment:write',
'allow:downloads',
], ],
}; };

View file

@ -55,6 +55,7 @@ export function createSandbox(
penpot: proxyApi, penpot: proxyApi,
fetch: ses.harden(safeFetch), fetch: ses.harden(safeFetch),
console: ses.harden(window.console), console: ses.harden(window.console),
Date: ses.harden(Date),
Math: ses.harden(Math), Math: ses.harden(Math),
setTimeout: ses.harden( setTimeout: ses.harden(
(...[handler, timeout]: Parameters<typeof setTimeout>) => { (...[handler, timeout]: Parameters<typeof setTimeout>) => {

View file

@ -43,6 +43,9 @@ describe('plugin-loader', () => {
'library:read', 'library:read',
'library:write', 'library:write',
'user:read', 'user:read',
'comment:read',
'comment:write',
'allow:downloads',
], ],
}; };

View file

@ -43,6 +43,7 @@ export class PluginModalElement extends HTMLElement {
const iframeSrc = this.getAttribute('iframe-src'); const iframeSrc = this.getAttribute('iframe-src');
const width = Number(this.getAttribute('width') || '300'); const width = Number(this.getAttribute('width') || '300');
const height = Number(this.getAttribute('height') || '400'); const height = Number(this.getAttribute('height') || '400');
const allowDownloads = this.getAttribute('allow-downloads') || false;
if (!title || !iframeSrc) { if (!title || !iframeSrc) {
throw new Error('title and iframe-src attributes are required'); throw new Error('title and iframe-src attributes are required');
@ -100,6 +101,10 @@ export class PluginModalElement extends HTMLElement {
'allow-storage-access-by-user-activation' 'allow-storage-access-by-user-activation'
); );
if (allowDownloads) {
iframe.sandbox.add('allow-downloads');
}
iframe.addEventListener('load', () => { iframe.addEventListener('load', () => {
this.shadowRoot?.dispatchEvent( this.shadowRoot?.dispatchEvent(
new CustomEvent('load', { new CustomEvent('load', {

View file

@ -14,6 +14,9 @@ export const manifestSchema = z.object({
'library:read', 'library:read',
'library:write', 'library:write',
'user:read', 'user:read',
'comment:read',
'comment:write',
'allow:downloads',
]) ])
), ),
}); });

View file

@ -40,6 +40,9 @@ describe('createPluginManager', () => {
'library:read', 'library:read',
'library:write', 'library:write',
'user:read', 'user:read',
'comment:read',
'comment:write',
'allow:downloads',
], ],
}; };

View file

@ -21,6 +21,10 @@ export async function createPluginManager(
let uiMessagesCallbacks: ((message: unknown) => void)[] = []; let uiMessagesCallbacks: ((message: unknown) => void)[] = [];
const timeouts = new Set<ReturnType<typeof setTimeout>>(); const timeouts = new Set<ReturnType<typeof setTimeout>>();
const allowDownloads = !!manifest.permissions.find(
(s) => s === 'allow:downloads'
);
const themeChangeId = context.addListener('themechange', (theme: Theme) => { const themeChangeId = context.addListener('themechange', (theme: Theme) => {
modal?.setTheme(theme); modal?.setTheme(theme);
}); });
@ -83,7 +87,7 @@ export async function createPluginManager(
return; return;
} }
modal = openUIApi(name, modalUrl, theme, options); modal = openUIApi(name, modalUrl, theme, options, allowDownloads);
modal.setTheme(theme); modal.setTheme(theme);