From 5092cfed529d665437fbc9826b3fc70cbcee655f Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Tue, 23 Jan 2024 12:17:45 +0100 Subject: [PATCH 1/2] feat(router): add method to get current base URL of instance Signed-off-by: Maksim Sukharev --- __tests__/webroot.spec.ts | 7 ++++++- lib/index.ts | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/__tests__/webroot.spec.ts b/__tests__/webroot.spec.ts index f08562c..36ca24b 100644 --- a/__tests__/webroot.spec.ts +++ b/__tests__/webroot.spec.ts @@ -21,7 +21,7 @@ */ import { describe, expect, test } from 'vitest' -import { getAppRootUrl, getRootUrl } from '../lib/index' +import { getAppRootUrl, getBaseUrl, getRootUrl } from '../lib/index' declare global { interface Window { @@ -34,23 +34,27 @@ describe('Web root handling', () => { test('empty web root', () => { window._oc_webroot = '' expect(getRootUrl()).toBe('') + expect(getBaseUrl()).toBe(window.location.origin) }) test('with given web root', () => { window._oc_webroot = '/nextcloud' expect(getRootUrl()).toBe('/nextcloud') + expect(getBaseUrl()).toBe(`${window.location.origin}/nextcloud`) }) test('without web root configured', () => { window._oc_webroot = undefined window.location.pathname = '/index.php/apps/files' expect(getRootUrl()).toBe('') + expect(getBaseUrl()).toBe(window.location.origin) }) test('with implicit web root', () => { window._oc_webroot = undefined window.location.pathname = '/nextcloud/index.php/apps/files' expect(getRootUrl()).toBe('/nextcloud') + expect(getBaseUrl()).toBe(`${window.location.origin}/nextcloud`) }) // TODO: This seems to be wrong, would expect `/nextcloud` @@ -58,6 +62,7 @@ describe('Web root handling', () => { window._oc_webroot = undefined window.location.pathname = '/nextcloud/apps/files' expect(getRootUrl()).toBe('/nextcloud/apps') + expect(getBaseUrl()).toBe(`${window.location.origin}/nextcloud/apps`) }) }) diff --git a/lib/index.ts b/lib/index.ts index a0bb172..da47220 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -36,14 +36,14 @@ export const linkTo = (app: string, file: string) => generateFilePath(app, '', f * @param {string} service id * @return {string} the url */ -const linkToRemoteBase = (service: string) => getRootUrl() + '/remote.php/' + service +const linkToRemoteBase = (service: string) => '/remote.php/' + service /** * Creates an absolute url for remote use * @param {string} service id * @return {string} the url */ -export const generateRemoteUrl = (service: string) => window.location.protocol + '//' + window.location.host + linkToRemoteBase(service) +export const generateRemoteUrl = (service: string) => getBaseUrl() + linkToRemoteBase(service) /** * Get the base path for the given OCS API service @@ -60,7 +60,7 @@ export const generateOcsUrl = (url: string, params?: object, options?: UrlOption const version = (allOptions.ocsVersion === 1) ? 1 : 2 - return window.location.protocol + '//' + window.location.host + getRootUrl() + '/ocs/v' + version + '.php' + _generateUrlPath(url, params, options) + return getBaseUrl() + '/ocs/v' + version + '.php' + _generateUrlPath(url, params, options) } /** @@ -189,6 +189,15 @@ export const generateFilePath = (app: string, type: string, file: string) => { return link } +/** + * Return the full base URL where this Nextcloud instance + * is accessible, with a web root included. + * For example "https://company.com/nextcloud". + * + * @return {string} base URL + */ +export const getBaseUrl = () => window.location.protocol + '//' + window.location.host + getRootUrl() + /** * Return the web root path where this Nextcloud instance * is accessible, with a leading slash. From bec5dd4c3f0221645a8217e75a0ff7dcf7103067 Mon Sep 17 00:00:00 2001 From: Maksim Sukharev Date: Tue, 23 Jan 2024 12:23:07 +0100 Subject: [PATCH 2/2] feat(router): allow to generate OCS URL for a given base (current instance by default) Signed-off-by: Maksim Sukharev --- __tests__/urls.spec.ts | 32 +++++++++++++++++++++++++++++--- lib/index.ts | 22 ++++++++++++++++++---- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/__tests__/urls.spec.ts b/__tests__/urls.spec.ts index a18a7b6..a8706a4 100644 --- a/__tests__/urls.spec.ts +++ b/__tests__/urls.spec.ts @@ -38,11 +38,27 @@ describe('URL generation', () => { } }) - test('generateRemoteUrl', () => { - window._oc_webroot = '/nextcloud' - expect(generateRemoteUrl('dav')).toBe(`${window.location.href}nextcloud/remote.php/dav`) + describe('generateRemoteUrl', () => { + beforeEach(() => { + window._oc_webroot = '' + }) + + it('uses base URL by default', () => { + expect(generateRemoteUrl('dav')).toBe(`${window.location.origin}/remote.php/dav`) + }) + + it('replaces base URL with given one', () => { + const baseURL = 'https://remote-url.com' + expect(generateRemoteUrl('dav', { baseURL })).toBe(`${baseURL}/remote.php/dav`) + }) + + it('includes webroot', () => { + window._oc_webroot = '/nextcloud' + expect(generateRemoteUrl('dav')).toBe(`${window.location.origin}/nextcloud/remote.php/dav`) + }) }) + describe('generateOcsUrl', () => { beforeEach(() => { window._oc_webroot = '' @@ -56,6 +72,11 @@ describe('URL generation', () => { expect(generateOcsUrl('/foo/bar', undefined, { ocsVersion: 1 })).toBe(`${window.location.href}ocs/v1.php/foo/bar`) }) + it('replaces base URL with given one', () => { + const baseURL = 'https://remote-url.com' + expect(generateOcsUrl('/foo/bar', undefined, { baseURL })).toBe(`${baseURL}/ocs/v2.php/foo/bar`) + }) + it('starts with webroot', () => { window._oc_webroot = '/nextcloud' expect(generateOcsUrl('/foo/bar')).toBe(`${window.location.href}nextcloud/ocs/v2.php/foo/bar`) @@ -83,6 +104,11 @@ describe('URL generation', () => { expect(generateUrl('foo')).toBe('/foo') }) + it('replaces base URL with given one', () => { + const baseURL = 'https://remote-url.com' + expect(generateUrl('/foo/bar', undefined, { baseURL })).toBe(`${baseURL}/index.php/foo/bar`) + }) + it('respects disabled mod-rewrite', () => { expect(generateUrl('/foo/bar')).toMatch(/index\.php/) }) diff --git a/lib/index.ts b/lib/index.ts index da47220..742e30e 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -19,6 +19,12 @@ export interface UrlOptions { * @default 2 */ ocsVersion?: number + + /** + * URL to use as a base (defaults to current instance) + * @default '' + */ + baseURL?: string } /** @@ -42,8 +48,12 @@ const linkToRemoteBase = (service: string) => '/remote.php/' + service * Creates an absolute url for remote use * @param {string} service id * @return {string} the url + * @param {UrlOptions} [options] options for the parameter replacement */ -export const generateRemoteUrl = (service: string) => getBaseUrl() + linkToRemoteBase(service) +export const generateRemoteUrl = (service: string, options?: UrlOptions) => { + const baseURL = options?.baseURL ?? getBaseUrl() + return baseURL + linkToRemoteBase(service) +} /** * Get the base path for the given OCS API service @@ -59,8 +69,9 @@ export const generateOcsUrl = (url: string, params?: object, options?: UrlOption }, options || {}) const version = (allOptions.ocsVersion === 1) ? 1 : 2 + const baseURL = options?.baseURL ?? getBaseUrl() - return getBaseUrl() + '/ocs/v' + version + '.php' + _generateUrlPath(url, params, options) + return baseURL + '/ocs/v' + version + '.php' + _generateUrlPath(url, params, options) } /** @@ -101,6 +112,7 @@ const _generateUrlPath = (url: string, params?: object, options?: UrlOptions) => /** * Generate the url with webroot for the given relative url, which can contain parameters + * If options.baseURL is provided, generate the absolute url pointing ro remote server * * Parameters will be URL encoded automatically * @@ -114,11 +126,13 @@ export const generateUrl = (url: string, params?: object, options?: UrlOptions) noRewrite: false, }, options || {}) + const baseOrRootURL = options?.baseURL ?? getRootUrl() + if (window?.OC?.config?.modRewriteWorking === true && !allOptions.noRewrite) { - return getRootUrl() + _generateUrlPath(url, params, options) + return baseOrRootURL + _generateUrlPath(url, params, options) } - return getRootUrl() + '/index.php' + _generateUrlPath(url, params, options) + return baseOrRootURL + '/index.php' + _generateUrlPath(url, params, options) } /**