From 299f8fdf8ec9a09ca22158428ecde481006703b2 Mon Sep 17 00:00:00 2001 From: Ilyassbennanii Date: Wed, 26 Nov 2025 12:52:25 +0100 Subject: [PATCH 1/2] AccessUrl: Add confirmation page before deleting URL refs #6272 --- assets/vue/components/Breadcrumb.vue | 17 +++ assets/vue/router/index.js | 6 + assets/vue/services/accessurlService.js | 45 ++++++++ .../vue/views/accessurl/DeleteAccessUrl.vue | 104 ++++++++++++++++++ public/main/admin/access_urls.php | 9 +- 5 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 assets/vue/views/accessurl/DeleteAccessUrl.vue diff --git a/assets/vue/components/Breadcrumb.vue b/assets/vue/components/Breadcrumb.vue index 5ae72f682dc..5d44a8397c7 100644 --- a/assets/vue/components/Breadcrumb.vue +++ b/assets/vue/components/Breadcrumb.vue @@ -193,7 +193,24 @@ function addDocumentBreadcrumb() { watchEffect(() => { if ("/" === route.fullPath) return itemList.value = [] +// special-case accessurl routes + if (/^\/resources\/accessurl\/[^\/]+\/delete(?:\/|$)/.test(route.path)) { + itemList.value = [] + itemList.value.push({ + label: t("Administration"), + url: "/main/admin/index.php", + }) + + itemList.value.push({ + label: t("Multiple access URL / Branding"), + url: "/main/admin/access_urls.php", + }) + + itemList.value.push({ label: t("Delete access") }) + + return + } if (buildManualBreadcrumbIfNeeded()) return // Static route categories diff --git a/assets/vue/router/index.js b/assets/vue/router/index.js index b89fc3e339e..7d362fa6cc1 100644 --- a/assets/vue/router/index.js +++ b/assets/vue/router/index.js @@ -65,6 +65,12 @@ const router = createRouter({ showBreadcrumb: false, }, }, + { + path: '/resources/accessurl/:id/delete', + name: 'AccessUrlDelete', + component: () => import('../views/accessurl/DeleteAccessUrl.vue'), + props: route => ({ id: Number(route.params.id) }) + }, { path: "/home", name: "Home", diff --git a/assets/vue/services/accessurlService.js b/assets/vue/services/accessurlService.js index 441151f4de6..5bcc43a575e 100644 --- a/assets/vue/services/accessurlService.js +++ b/assets/vue/services/accessurlService.js @@ -10,3 +10,48 @@ export async function findUserActivePortals(userIri) { return items } + +async function getUrl(id) { + const apiUrl = `/api/access_urls/${encodeURIComponent(id)}`; + try { + const resp = await fetch(apiUrl, { + credentials: "same-origin", + headers: { Accept: "application/json" }, + }); + if (resp.ok) { + const contentType = resp.headers.get("content-type") || ""; + return contentType.includes("application/json") ? resp.json() : { url: await resp.text() }; + } + } catch (err) { + } +} + +async function deleteAccessUrl(id, confirmValue, secToken = "") { + const url = `/api/access_urls/${encodeURIComponent(id)}` + const resp = await fetch(url, { + method: "DELETE", + credentials: "same-origin", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + ...(secToken ? { "X-CSRF-Token": secToken } : {}), + }, + body: JSON.stringify({ confirm_value: String(confirmValue) }), + }) + + if (!resp.ok) { + const txt = await resp.text() + throw new Error(txt || "Delete failed") + } + + const contentType = resp.headers.get("content-type") || "" + if (contentType.includes("application/json")) { + return resp.json() + } + return { message: await resp.text(), redirectUrl: "/main/admin/access_urls.php" } +} + +export default { + deleteAccessUrl, + getUrl, +} diff --git a/assets/vue/views/accessurl/DeleteAccessUrl.vue b/assets/vue/views/accessurl/DeleteAccessUrl.vue new file mode 100644 index 00000000000..faed7b63762 --- /dev/null +++ b/assets/vue/views/accessurl/DeleteAccessUrl.vue @@ -0,0 +1,104 @@ + + + diff --git a/public/main/admin/access_urls.php b/public/main/admin/access_urls.php index 78fe84d9689..4adf7647207 100644 --- a/public/main/admin/access_urls.php +++ b/public/main/admin/access_urls.php @@ -77,7 +77,7 @@ } $parameters['sec_token'] = Security::get_token(); - +echo ''; // Checking if the admin is registered in all sites $url_string = ''; foreach ($url_list as $u) { @@ -209,8 +209,11 @@ ); if ($u->getId() !== 1) { - $rowActions .= '' . + // build a link to the Vue route that will open DeleteAccessUrl.vue + $urlEncoded = rawurlencode($u->getUrl()); + $secTokenEncoded = rawurlencode($parameters['sec_token']); + $vueHref = api_get_path(WEB_PATH) . 'resources/accessurl/' . $u->getId() . '/delete?url=' . $urlEncoded . '&sec_token=' . $secTokenEncoded; + $rowActions .= '' . Display::getMdiIcon('delete', 'ch-tool-icon', null, ICON_SIZE_SMALL, get_lang('Delete')) . ''; } From 395d529fc957eefd95f0ac8414a1c7bda958c77e Mon Sep 17 00:00:00 2001 From: Ilyassbennanii Date: Thu, 27 Nov 2025 09:29:35 +0100 Subject: [PATCH 2/2] Minor : Fix language variable - refs#6272 --- assets/vue/views/accessurl/DeleteAccessUrl.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/vue/views/accessurl/DeleteAccessUrl.vue b/assets/vue/views/accessurl/DeleteAccessUrl.vue index faed7b63762..c42b76332fc 100644 --- a/assets/vue/views/accessurl/DeleteAccessUrl.vue +++ b/assets/vue/views/accessurl/DeleteAccessUrl.vue @@ -1,6 +1,6 @@