From a02370265e9e39d38dc1dfa4e4587de31ef56497 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 12 Nov 2025 16:35:17 +0100 Subject: [PATCH 1/3] feat: share links and passwords in embed mode --- .../src/components/CreateLinkModal.vue | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/web-pkg/src/components/CreateLinkModal.vue b/packages/web-pkg/src/components/CreateLinkModal.vue index 6c01302f0a1..e94de6f52e6 100644 --- a/packages/web-pkg/src/components/CreateLinkModal.vue +++ b/packages/web-pkg/src/components/CreateLinkModal.vue @@ -106,7 +106,7 @@ isFolder }) " - >{{ $gettext('Copy link and password') }} + >{{ confirmPasswordButtonText }} @@ -193,6 +193,13 @@ export default defineComponent({ return $gettext('Copy link') }) + const confirmPasswordButtonText = computed(() => { + if (unref(isEmbedEnabled)) { + return $gettext('Share link(s) and password(s)') + } + return $gettext('Copy link and password') + }) + const passwordInputKey = ref(uuidV4()) const roleRefs = ref>({}) @@ -265,12 +272,21 @@ export default defineComponent({ const result = await createLinks() const succeeded = result.filter(({ status }) => status === 'fulfilled') + // **DEPRECATED**: Always emit the share url for backwards compatibility if (succeeded.length && unref(isEmbedEnabled)) { postMessage( 'owncloud-embed:share', (succeeded as PromiseFulfilledResult[]).map(({ value }) => value.webUrl) ) } + // Always emit new event with objects, include password only when copyPassword is enabled + postMessage>( + 'owncloud-embed:share-links', + (succeeded as PromiseFulfilledResult[]).map(({ value }) => ({ + url: value.webUrl, + ...(options.copyPassword && { password: password.value }) + })) + ) const userFacingErrors: Error[] = [] const failed = result.filter(({ status }) => status === 'rejected') @@ -350,6 +366,7 @@ export default defineComponent({ updatePassword, getLinkRoleByType, confirmButtonText, + confirmPasswordButtonText, isAdvancedMode, setAdvancedMode, onExpiryDateChanged, From a2033a5e4c473e010aabcddd2df9872bce35e138 Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Fri, 30 Jan 2026 11:01:34 +0100 Subject: [PATCH 2/3] feat: add singin popup callback --- packages/web-runtime/src/pages/oidcCallback.vue | 2 ++ packages/web-runtime/src/router/index.ts | 6 ++++++ .../web-runtime/src/services/auth/authService.ts | 16 ++++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/packages/web-runtime/src/pages/oidcCallback.vue b/packages/web-runtime/src/pages/oidcCallback.vue index b6ecc5d0b89..7cf18c940bc 100644 --- a/packages/web-runtime/src/pages/oidcCallback.vue +++ b/packages/web-runtime/src/pages/oidcCallback.vue @@ -72,6 +72,8 @@ export default defineComponent({ if (unref(route).path === '/web-oidc-silent-redirect') { authService.signInSilentCallback() + } else if (unref(route).path === '/web-oidc-popup-callback') { + authService.signInPopupCallback() } else { authService.signInCallback() } diff --git a/packages/web-runtime/src/router/index.ts b/packages/web-runtime/src/router/index.ts index 46c66ef63c1..4e6a2bb4a72 100644 --- a/packages/web-runtime/src/router/index.ts +++ b/packages/web-runtime/src/router/index.ts @@ -52,6 +52,12 @@ const routes = [ component: OidcCallbackPage, meta: { title: $gettext('Oidc redirect'), authContext: 'anonymous' } }, + { + path: '/web-oidc-popup-callback', + name: 'oidcPopupCallback', + component: OidcCallbackPage, + meta: { title: $gettext('Oidc popup callback'), authContext: 'anonymous' } + }, { path: '/f/:fileId', name: 'resolvePrivateLink', diff --git a/packages/web-runtime/src/services/auth/authService.ts b/packages/web-runtime/src/services/auth/authService.ts index 7d9ea9342a8..2109b9b54c6 100644 --- a/packages/web-runtime/src/services/auth/authService.ts +++ b/packages/web-runtime/src/services/auth/authService.ts @@ -7,7 +7,8 @@ import { CapabilityStore, ConfigStore, useTokenTimerWorker, - AuthServiceInterface + AuthServiceInterface, + useEmbedMode } from '@ownclouders/web-pkg' import { RouteLocation, Router } from 'vue-router' import { @@ -18,7 +19,7 @@ import { isUserContextRequired } from '../../router' import { unref } from 'vue' -import { Ability } from '@ownclouders/web-client' +import { Ability, urlJoin } from '@ownclouders/web-client' import { Language } from 'vue3-gettext' import { PublicLinkType } from '@ownclouders/web-client' import { WebWorkersStore } from '@ownclouders/web-pkg' @@ -235,6 +236,13 @@ export class AuthService implements AuthServiceInterface { } public loginUser(redirectUrl?: string) { + const { isEnabled: isEmbedModeEnable } = useEmbedMode() + // if embed mode is enabled, use popup login instead of a redirect + if (unref(isEmbedModeEnable)) { + return this.userManager.signinPopup({ + redirect_uri: urlJoin(unref(this.configStore.serverUrl), 'web-oidc-popup-callback') + }) + } this.userManager.setPostLoginRedirectUrl(redirectUrl) return this.userManager.signinRedirect() } @@ -285,6 +293,10 @@ export class AuthService implements AuthServiceInterface { await this.userManager.signinSilentCallback(this.buildSignInCallbackUrl()) } + public async signInPopupCallback() { + await this.userManager.signinPopupCallback(this.buildSignInCallbackUrl()) + } + /** * craft a url that the parser in oidc-client-ts can handle… */ From 02ac7120c41c6411fd5f59c853c33253903f111a Mon Sep 17 00:00:00 2001 From: Rodrigo Date: Mon, 2 Feb 2026 10:22:52 +0100 Subject: [PATCH 3/3] feat: embed messages origin configurable via URI --- packages/web-pkg/src/composables/embedMode/useEmbedMode.ts | 4 +++- packages/web-runtime/src/container/bootstrap.ts | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/web-pkg/src/composables/embedMode/useEmbedMode.ts b/packages/web-pkg/src/composables/embedMode/useEmbedMode.ts index f7c5ce2ceda..fc631d0f384 100644 --- a/packages/web-pkg/src/composables/embedMode/useEmbedMode.ts +++ b/packages/web-pkg/src/composables/embedMode/useEmbedMode.ts @@ -39,7 +39,9 @@ export const useEmbedMode = () => { return configStore.options.embed?.fileTypes }) - const messagesTargetOrigin = computed(() => configStore.options.embed?.messagesOrigin) + const messagesTargetOrigin = computed(() => { + return configStore.options.embed?.messagesOrigin + }) const isDelegatingAuthentication = computed( () => unref(isEnabled) && configStore.options.embed?.delegateAuthentication diff --git a/packages/web-runtime/src/container/bootstrap.ts b/packages/web-runtime/src/container/bootstrap.ts index 7514ed345c3..2715247c645 100644 --- a/packages/web-runtime/src/container/bootstrap.ts +++ b/packages/web-runtime/src/container/bootstrap.ts @@ -125,6 +125,12 @@ const getEmbedConfigFromQuery = ( config.delegateAuthenticationOrigin = delegateAuthenticationOrigin } + const messagesOrigin = getQueryParam('embed-messages-origin') + + if (messagesOrigin) { + config.messagesOrigin = messagesOrigin + } + return config }