diff --git a/libs/blocks/bulk-publish-v2/components/bulk-publisher.js b/libs/blocks/bulk-publish-v2/components/bulk-publisher.js index 712f663fa0..c0c88ae5db 100644 --- a/libs/blocks/bulk-publish-v2/components/bulk-publisher.js +++ b/libs/blocks/bulk-publish-v2/components/bulk-publisher.js @@ -1,7 +1,7 @@ import './job-process.js'; import { LitElement, html } from '../../../deps/lit-all.min.js'; import { getSheet } from '../../../../tools/utils/utils.js'; -import { authenticate, getPublishable, startJob } from '../services.js'; +import { authenticate, startJob } from '../services.js'; import { getConfig } from '../../../utils/utils.js'; import { delay, @@ -95,8 +95,7 @@ class BulkPublish2 extends LitElement { this.validateUrls(); } - setJobErrors(jobErrors, authErrors) { - const errors = [...jobErrors, ...authErrors]; + setJobErrors(errors) { const urls = []; errors.forEach((error) => { const matched = this.urls.filter((url) => { @@ -324,8 +323,7 @@ class BulkPublish2 extends LitElement { class="panel-title" @click=${handleToggle}> - ${this.jobs.length ? html`${this.jobs.length}` : ''} - Job Result${this.jobs.length > 1 ? 's' : ''} + Job Results
{ - /* c8 ignore next 4 */ const loader = this.renderRoot.querySelector('.load-indicator'); const message = this.renderRoot.querySelector('.message'); loader?.classList.add('hide'); @@ -431,7 +427,6 @@ class BulkPublish2 extends LitElement { const canUse = Object.values(this.user.permissions).filter((perms) => perms.canUse); if (canUse.length) return html``; message = 'Current user is not authorized to use Bulk Publishing Tool'; - /* c8 ignore next 3 */ } else { message = 'Please sign in to AEM sidekick to continue'; } diff --git a/libs/blocks/bulk-publish-v2/services.js b/libs/blocks/bulk-publish-v2/services.js index 76af892bf2..2889aa5660 100644 --- a/libs/blocks/bulk-publish-v2/services.js +++ b/libs/blocks/bulk-publish-v2/services.js @@ -1,4 +1,3 @@ -import userCanPublishPage from '../../tools/utils/publish.js'; import { PROCESS_TYPES, getErrorText, @@ -247,32 +246,8 @@ const updateRetry = async ({ queue, urls, process }) => { return newQueue; }; -// publish authentication service -const getPublishable = async ({ urls, process, user }) => { - let publishable = { authorized: [], unauthorized: [] }; - if (!isLive(process)) { - publishable.authorized = urls; - } else { - const { permissions, profile } = user; - const live = { permissions: ['read'] }; - if (permissions?.publish?.canUse) { - live.permissions.push('write'); - } - publishable = await urls.reduce(async (init, url) => { - const result = await init; - const detail = { webPath: new URL(url).pathname, live, profile }; - const { canPublish, message } = await userCanPublishPage(detail); - if (canPublish) result.authorized.push(url); - else result.unauthorized.push({ href: url, message }); - return result; - }, Promise.resolve(publishable)); - } - return publishable; -}; - export { authenticate, - getPublishable, pollJobStatus, startJob, updateRetry, diff --git a/libs/tools/utils/publish.js b/libs/tools/utils/publish.js deleted file mode 100644 index 49acf0928d..0000000000 --- a/libs/tools/utils/publish.js +++ /dev/null @@ -1,32 +0,0 @@ -import { getCustomConfig } from '../../../tools/utils/utils.js'; - -const userCanPublishPage = async (detail, isBulk = true) => { - if (!detail) return false; - const { live, profile, webPath } = detail; - let canPublish = isBulk ? live?.permissions?.includes('write') : true; - let message = 'Publishing is currently disabled for this page'; - const config = await getCustomConfig('/.milo/publish-permissions-config.json'); - const item = config?.urls?.data?.find(({ url }) => ( - url.endsWith('**') ? webPath.includes(url.slice(0, -2)) : url === webPath - )); - if (item) { - canPublish = false; - if (item.message) message = item.message; - const group = config[item.group]; - if (group && profile?.email) { - let isDeny; - const user = group.data?.find(({ allow, deny }) => { - if (deny) { - /* c8 ignore next 3 */ - isDeny = true; - return deny === profile.email; - } - return allow === profile.email; - }); - canPublish = isDeny ? !user : !!user; - } - } - return { canPublish, message }; -}; - -export default userCanPublishPage; diff --git a/libs/utils/sidekick-decorate.js b/libs/utils/sidekick-decorate.js index acaa428716..ec125ef650 100644 --- a/libs/utils/sidekick-decorate.js +++ b/libs/utils/sidekick-decorate.js @@ -1,22 +1,4 @@ -import userCanPublishPage from '../tools/utils/publish.js'; - -const PUBLISH_BTN = '.publish.plugin button'; -const BACKUP_PROFILE = '.profile-email'; -const CONFIRM_MESSAGE = 'Are you sure? This will publish to production.'; - export default function stylePublish(sk) { - const setupPublishBtn = async (page, btn) => { - const { canPublish, message } = await userCanPublishPage(page, false); - btn.setAttribute('disabled', !canPublish); - const messageText = btn.querySelector('span'); - const text = canPublish ? CONFIRM_MESSAGE : message; - if (messageText) { - messageText.innerText = text; - } else { - btn.insertAdjacentHTML('beforeend', `${text}`); - } - }; - const style = new CSSStyleSheet(); style.replaceSync(` :host { @@ -28,21 +10,19 @@ export default function stylePublish(sk) { order: 100; } .publish.plugin button { - position: relative; - } - .publish.plugin button:not([disabled=true]) { background: var(--bg-color); border-color: #b46157; color: var(--text-color); + position: relative; } - .publish.plugin button:not([disabled=true]):hover { + .publish.plugin button:hover { background-color: var(--hlx-sk-button-hover-bg); border-color: unset; color: var(--hlx-sk-button-hover-color); } .publish.plugin button > span { display: none; - background: #666; + background: var(--bg-color); border-radius: 4px; line-height: 1.2rem; padding: 8px 12px; @@ -53,9 +33,6 @@ export default function stylePublish(sk) { width: 150px; white-space: pre-wrap; } - .publish.plugin button:not([disabled=true]) > span { - background: var(--bg-color); - } .publish.plugin button:hover > span { display: block; color: var(--text-color); @@ -64,39 +41,19 @@ export default function stylePublish(sk) { content: ''; border-left: 6px solid transparent; border-right: 6px solid transparent; - border-bottom: 6px solid #666; + border-bottom: 6px solid var(--bg-color); position: absolute; text-align: center; top: -6px; left: 50%; transform: translateX(-50%); } - .publish.plugin button:not([disabled=true]) > span:before { - border-bottom: 6px solid var(--bg-color); - } `); - sk.shadowRoot.adoptedStyleSheets = [style]; - - sk.addEventListener('statusfetched', async (event) => { - const page = event?.detail?.data; - const btn = event?.target?.shadowRoot?.querySelector(PUBLISH_BTN); - if (page && btn) { - setupPublishBtn(page, btn); - } - }); - - setTimeout(async () => { - const btn = sk.shadowRoot.querySelector(PUBLISH_BTN); - btn?.setAttribute('disabled', true); - const message = btn?.querySelector('span'); - if (btn && !message) { - const page = { - webPath: window.location.pathname, - // added for edge case where the statusfetched event isnt fired on refresh - profile: { email: sk.shadowRoot.querySelector(BACKUP_PROFILE)?.innerText }, - }; - setupPublishBtn(page, btn); - } + setTimeout(() => { + const btn = sk.shadowRoot.querySelector('.publish.plugin button'); + btn?.insertAdjacentHTML('beforeend', ` + Are you sure? This will publish to production. + `); }, 500); } diff --git a/test/blocks/bulk-publish-v2/bulk-publish-v2.test.js b/test/blocks/bulk-publish-v2/bulk-publish-v2.test.js index 7cd56109b4..3b634681d2 100644 --- a/test/blocks/bulk-publish-v2/bulk-publish-v2.test.js +++ b/test/blocks/bulk-publish-v2/bulk-publish-v2.test.js @@ -114,16 +114,6 @@ describe('Bulk Publish Tool', () => { await mouseEvent(rootEl.querySelector('.fix-btn')); }); - it('can trigger cannot publish config', async () => { - await clock.runAllAsync(); - await setProcess(rootEl, 'publish'); - await setTextArea(rootEl, 'https://error--milo--adobecom.hlx.page/not/a/valid/path'); - await mouseEvent(rootEl.querySelector('#RunProcess')); - const errors = rootEl.querySelector('.errors'); - expect(errors.querySelector('strong').innerText).to.equal('Publishing disabled until the test is over'); - await mouseEvent(rootEl.querySelector('.fix-btn')); - }); - it('can validate milo urls and enable form', async () => { await clock.runAllAsync(); await setProcess(rootEl, 'publish'); @@ -142,17 +132,6 @@ describe('Bulk Publish Tool', () => { await mouseEvent(rootEl.querySelector('.switch.half')); }); - it('can toggle job timing flyout', async () => { - await clock.runAllAsync(); - const doneJobProcess = rootEl.querySelector('job-process'); - const jobInfo = doneJobProcess?.shadowRoot.querySelector('job-info'); - const timerDetail = jobInfo?.shadowRoot.querySelector('.timer'); - await mouseEvent(timerDetail); - await clock.runAllAsync(); - await mouseEvent(timerDetail); - expect(timerDetail.classList.contains('show-times')).to.be.false; - }); - it('can submit valid bulk preview job', async () => { await clock.runAllAsync(); await setProcess(rootEl, 'preview'); @@ -195,6 +174,17 @@ describe('Bulk Publish Tool', () => { expect(rootEl.querySelectorAll('job-process')).to.have.lengthOf(4); }); + it('can toggle job timing flyout', async () => { + await clock.runAllAsync(); + const doneJobProcess = rootEl.querySelector('job-process'); + const jobInfo = doneJobProcess?.shadowRoot.querySelector('job-info'); + const timerDetail = jobInfo?.shadowRoot.querySelector('.timer'); + await mouseEvent(timerDetail); + await clock.runAllAsync(); + await mouseEvent(timerDetail); + expect(timerDetail.classList.contains('show-times')).to.be.false; + }); + it('can toggle view mode', async () => { await mouseEvent(rootEl.querySelector('.switch.full')); await clock.runAllAsync(); @@ -228,6 +218,7 @@ describe('Bulk Publish Tool', () => { it('can clear bulk jobs', async () => { await clock.runAllAsync(); await mouseEvent(rootEl.querySelector('.clear-jobs')); + await clock.runAllAsync(); expect(rootEl.querySelectorAll('job-process')).to.have.lengthOf(0); }); }); diff --git a/test/blocks/bulk-publish-v2/mocks/authentication.js b/test/blocks/bulk-publish-v2/mocks/authentication.js index ca826fa82d..22d01045ad 100644 --- a/test/blocks/bulk-publish-v2/mocks/authentication.js +++ b/test/blocks/bulk-publish-v2/mocks/authentication.js @@ -23,7 +23,7 @@ class MockAuth extends HTMLElement { bubbles: true, detail: { data: { - profile: { name: 'Unit Test', email: 'tester@adobe.com' }, + profile: { name: 'Unit Test' }, preview: { permissions }, live: { permissions }, }, diff --git a/test/blocks/bulk-publish-v2/mocks/fetch.js b/test/blocks/bulk-publish-v2/mocks/fetch.js index 48d7637f54..8ab62d86d3 100644 --- a/test/blocks/bulk-publish-v2/mocks/fetch.js +++ b/test/blocks/bulk-publish-v2/mocks/fetch.js @@ -11,7 +11,6 @@ const requests = { delstatus: 'https://admin.hlx.page/job/adobecom/milo/main/preview-remove/job-2024-01-24t23-16-20-377z/details', retry: 'https://admin.hlx.page/preview/adobecom/milo/main/tools/bulk-publish-v2-test', index: 'https://admin.hlx.page/index/adobecom/milo/main/tools/bulk-publish-v2-test', - permissions: '/.milo/publish-permissions-config.json', }; const getMocks = async () => { @@ -26,7 +25,7 @@ const getMocks = async () => { export async function mockFetch() { const mocks = await getMocks(); stub(window, 'fetch').callsFake((...args) => { - const headers = args[1]?.body ?? null; + const headers = args[1].body ?? null; const body = headers ? JSON.parse(headers) : false; const [resource] = args; const response = mocks.find((mock) => (body.delete ? mock.request === 'delete' : mock.url === resource)); diff --git a/test/blocks/bulk-publish-v2/mocks/response/permissions.json b/test/blocks/bulk-publish-v2/mocks/response/permissions.json deleted file mode 100644 index 37fe5eaec9..0000000000 --- a/test/blocks/bulk-publish-v2/mocks/response/permissions.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "urls": { - "total": 4, - "offset": 0, - "limit": 4, - "data": [ - { - "url": "/not/a/valid/path", - "group": "gwp-test", - "message": "Publishing disabled until the test is over" - } - ] - }, - "gwp-test": { - "total": 2, - "offset": 0, - "limit": 2, - "data": [ - { "allow": "testuser@adobe.com" }, - { "allow": "testuser1@adobe.com" } - ] - }, - ":version": 3, - ":names": ["urls", "gwp-US", "no-publish", "gwp-FR"], - ":type": "multi-sheet" -} diff --git a/tools/utils/utils.js b/tools/utils/utils.js index 8193d21fdf..29d68397d8 100644 --- a/tools/utils/utils.js +++ b/tools/utils/utils.js @@ -1,7 +1,6 @@ const IMS_CLIENT_ID = 'milo_ims'; const IMS_PROD_URL = 'https://auth.services.adobe.com/imslib/imslib.min.js'; const STYLE_SHEETS = {}; -const CONFIGS = {}; const getImsToken = async (loadScript) => { window.adobeid = { @@ -26,15 +25,4 @@ const getSheet = async (url) => { return sheet; }; -const getCustomConfig = async (path) => { - /* c8 ignore next 3 */ - if (CONFIGS[path] !== undefined) { - return CONFIGS[path]; - } - const resp = await fetch(path); - const config = resp.ok ? await resp.json() : null; - CONFIGS[path] = config; - return config; -}; - -export { getImsToken, getSheet, getCustomConfig }; +export { getImsToken, getSheet };