diff --git a/packages/design-system/src/assets/icons/resource-type-url-fill.svg b/packages/design-system/src/assets/icons/resource-type-url-fill.svg new file mode 100644 index 00000000000..2efc62595c3 --- /dev/null +++ b/packages/design-system/src/assets/icons/resource-type-url-fill.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/design-system/src/helpers/resourceIconMapping.json b/packages/design-system/src/helpers/resourceIconMapping.json index 95ec7bcad08..1c6765c280e 100644 --- a/packages/design-system/src/helpers/resourceIconMapping.json +++ b/packages/design-system/src/helpers/resourceIconMapping.json @@ -387,6 +387,10 @@ "name": "resource-type-text", "color": "var(--oc-color-text-default)" }, + "url": { + "name": "resource-type-url", + "color": "var(--oc-color-text-default)" + }, "vsd": { "name": "resource-type-document", "color": "var(--oc-color-icon-document)" diff --git a/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue b/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue index d6e658fdaea..f1eb15bb667 100644 --- a/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue +++ b/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue @@ -1,4 +1,9 @@ @@ -123,7 +134,8 @@ :disabled="isActionDisabled(action)" @click="action.handler" > - + @@ -159,16 +171,13 @@ diff --git a/packages/web-pkg/src/components/FilesList/ContextActions.vue b/packages/web-pkg/src/components/FilesList/ContextActions.vue index 9fc8d86e027..e26a2ab0aca 100644 --- a/packages/web-pkg/src/components/FilesList/ContextActions.vue +++ b/packages/web-pkg/src/components/FilesList/ContextActions.vue @@ -5,7 +5,11 @@ ', + setup: async ({ actions }) => { + await unref(actions)[0].handler({ + resources: [mock()], + space: null + }) + expect(window.open).toHaveBeenCalledWith('https://owncloud.com?default=') + } + }) + }) + }) + }) + describe('method "extractUrl"', () => { + it('extracts url correctly', () => { + getWrapper({ + setup: ({ extractUrl }) => { + expect(extractUrl('[InternetShortcut]\n' + 'URL=https://owncloud.com')).toEqual( + 'https://owncloud.com' + ) + } + }) + }) + it('throws error if url cannot be extracted', () => { + getWrapper({ + setup: ({ extractUrl }) => { + expect(() => extractUrl('�������')).toThrow('unable to extract url') + } + }) + }) + }) +}) + +function getWrapper({ + setup, + getFileContentsValue = null +}: { + getFileContentsValue?: string + setup: ( + instance: ReturnType, + options: { + storeOptions: typeof defaultStoreMockOptions + } + ) => void +}) { + const mocks = { + ...defaultComponentMocks({ + currentRoute: mock({ name: 'files-spaces-generic' }) + }) + } + + // url contains xss code to test xss protection + mocks.$clientService.webdav.getFileContents.mockResolvedValue( + mock({ + body: getFileContentsValue + }) + ) + + jest + .mocked(useRoute) + .mockImplementation(() => + ref(mock({ name: 'files-spaces-generic', path: '/files/' }) as any) + ) + + const storeOptions = { + ...defaultStoreMockOptions + } + + const store = createStore(storeOptions) + + return { + wrapper: getComposableWrapper( + () => { + const instance = useFileActionsOpenShortcut({ store }) + setup(instance, { storeOptions }) + }, + { + store, + mocks, + provide: mocks + } + ) + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fa000ce30fe..517c60d699a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1010,6 +1010,9 @@ importers: design-system: specifier: workspace:@ownclouders/design-system@* version: link:../design-system + dompurify: + specifier: ^3.0.6 + version: 3.0.6 filesize: specifier: ^9.0.11 version: 9.0.11 @@ -10943,6 +10946,10 @@ packages: dependencies: domelementtype: 2.2.0 + /dompurify@3.0.6: + resolution: {integrity: sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w==} + dev: false + /domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} dependencies: