You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ac...@apache.org on 2018/08/07 13:29:43 UTC

[couchdb-fauxton] branch master updated: Use relative pathname instead of static pathname for local replication (#1120)

This is an automated email from the ASF dual-hosted git repository.

acote pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb-fauxton.git


The following commit(s) were added to refs/heads/master by this push:
     new 0267a27  Use relative pathname instead of static pathname for local replication (#1120)
0267a27 is described below

commit 0267a27a7b14ed8c2238ea6bcf3bc1df17240583
Author: Alexis Côté <po...@users.noreply.github.com>
AuthorDate: Tue Aug 7 09:29:41 2018 -0400

    Use relative pathname instead of static pathname for local replication (#1120)
---
 app/addons/replication/__tests__/api.tests.js     | 31 +++++++++++++++++++++++
 app/addons/replication/__tests__/helpers.tests.js |  4 +--
 app/addons/replication/api.js                     | 12 ++++++---
 app/addons/replication/components/common-table.js | 19 +++++++++++---
 app/addons/replication/helpers.js                 |  3 ++-
 app/helpers.js                                    |  4 +++
 6 files changed, 62 insertions(+), 11 deletions(-)

diff --git a/app/addons/replication/__tests__/api.tests.js b/app/addons/replication/__tests__/api.tests.js
index 4b39507..92d1d9d 100644
--- a/app/addons/replication/__tests__/api.tests.js
+++ b/app/addons/replication/__tests__/api.tests.js
@@ -81,6 +81,22 @@ describe('Replication API', () => {
       assert.ok(/my%2Fdb/.test(source.url));
     });
 
+    it('returns local source with auth info and encoded when use relative url', () => {
+      const localSource = 'my/db';
+      const source = getSource({
+        replicationSource: Constants.REPLICATION_SOURCE.LOCAL,
+        localSource,
+        sourceAuth: {
+          username: 'the-user',
+          password: 'password'
+        },
+        sourceAuthType: Constants.REPLICATION_AUTH_METHOD.BASIC
+      }, {origin: 'http://dev:6767', pathname:'/db/_utils'});
+
+      assert.deepEqual(source.headers, {Authorization:"Basic dGhlLXVzZXI6cGFzc3dvcmQ="});
+      assert.ok(/\/db\/my%2Fdb/.test(source.url));
+    });
+
     it('returns remote source url and auth header', () => {
       const source = getSource({
         replicationSource: Constants.REPLICATION_SOURCE.REMOTE,
@@ -184,6 +200,21 @@ describe('Replication API', () => {
       assert.ok(/my-existing%2Fdb/.test(target.url));
     });
 
+    it('returns existing local database even with relative urls', () => {
+      const target = getTarget({
+        replicationTarget: Constants.REPLICATION_TARGET.EXISTING_LOCAL_DATABASE,
+        localTarget: 'my-existing/db',
+        targetAuth: {
+          username: 'the-user',
+          password: 'password'
+        },
+        targetAuthType: Constants.REPLICATION_AUTH_METHOD.BASIC
+      }, {origin:'http://dev:6767', pathname:'/db/_utils'});
+
+      assert.deepEqual(target.headers, {Authorization:"Basic dGhlLXVzZXI6cGFzc3dvcmQ="});
+      assert.ok(/my-existing%2Fdb/.test(target.url));
+    });
+
     it('returns new local database', () => {
       const target = getTarget({
         replicationTarget: Constants.REPLICATION_TARGET.NEW_LOCAL_DATABASE,
diff --git a/app/addons/replication/__tests__/helpers.tests.js b/app/addons/replication/__tests__/helpers.tests.js
index 0703f39..20b1715 100644
--- a/app/addons/replication/__tests__/helpers.tests.js
+++ b/app/addons/replication/__tests__/helpers.tests.js
@@ -15,11 +15,11 @@ import helpers from '../helpers';
 describe('Replication Helpers - getDatabaseLabel', () => {
 
   it('returns database name for string', () => {
-    const db = 'http://tester:testerpass@127.0.0.1/fancy/db/name';
+    const db = 'http://tester:testerpass@127.0.0.1/db/fancy%2Fdb%2Fname';
 
     const res = helpers.getDatabaseLabel(db);
 
-    expect(res).toBe('fancy/db/name');
+    expect(res).toBe('fancy%2Fdb%2Fname');
   });
 
   it('returns database name for object', () => {
diff --git a/app/addons/replication/api.js b/app/addons/replication/api.js
index 2ec00f8..b092e15 100644
--- a/app/addons/replication/api.js
+++ b/app/addons/replication/api.js
@@ -100,11 +100,14 @@ export const getSource = ({
   sourceAuthType,
   sourceAuth
 },
-{origin} = window.location) => {
+{origin, pathname} = window.location) => {
 
   const source = {};
   if (replicationSource === Constants.REPLICATION_SOURCE.LOCAL) {
-    source.url = encodeFullUrl(`${origin}/${localSource}`);
+    const encodedLocalTarget = encodeURIComponent(localSource);
+
+    const root = Helpers.getRootUrl({origin, pathname});
+    source.url = `${root}${encodedLocalTarget}`;
   } else {
     source.url = encodeFullUrl(removeCredentialsFromUrl(remoteSource));
   }
@@ -121,7 +124,7 @@ export const getTarget = ({
   targetAuth
 },
 //this allows us to mock out window.location for our tests
-{origin} = window.location) => {
+{origin, pathname} = window.location) => {
 
   const target = {};
   if (replicationTarget === Constants.REPLICATION_TARGET.NEW_REMOTE_DATABASE ||
@@ -129,7 +132,8 @@ export const getTarget = ({
     target.url = encodeFullUrl(removeCredentialsFromUrl(remoteTarget));
   } else {
     const encodedLocalTarget = encodeURIComponent(localTarget);
-    target.url = `${origin}/${encodedLocalTarget}`;
+    const root = Helpers.getRootUrl({origin, pathname});
+    target.url = `${root}${encodedLocalTarget}`;
   }
 
   setCredentials(target, targetAuthType, targetAuth);
diff --git a/app/addons/replication/components/common-table.js b/app/addons/replication/components/common-table.js
index 1365817..f12b382 100644
--- a/app/addons/replication/components/common-table.js
+++ b/app/addons/replication/components/common-table.js
@@ -16,22 +16,33 @@ import {Table, Tooltip, OverlayTrigger} from "react-bootstrap";
 import moment from 'moment';
 import {ErrorModal} from './modals';
 import {removeCredentialsFromUrl} from '../api';
+import Helpers from '../../../helpers';
+
+const getDbNameFromUrl = (urlObj, root) => {
+  try {
+    const urlWithoutDb = new URL(root);
+    const dbName = urlObj.pathname.substring(urlWithoutDb.pathname.length);
+    return encodeURIComponent(dbName);
+  } catch (e) {
+    return '';
+  }
+};
 
 export const formatUrl = (url) => {
   let urlObj;
   let encoded;
   try {
     urlObj = new URL(removeCredentialsFromUrl(url));
-    encoded = encodeURIComponent(urlObj.pathname.slice(1));
   } catch (e) {
     return '';
   }
-
+  const root = Helpers.getRootUrl();
+  encoded = getDbNameFromUrl(urlObj, root);
   if (url.indexOf(window.location.hostname) > -1) {
     return (
       <span>
-        {urlObj.origin + '/'}
-        <a href={`#/database/${encoded}/_all_docs`}>{urlObj.pathname.slice(1)}</a>
+        {root}
+        <a href={`#/database/${encoded}/_all_docs`}>{decodeURIComponent(encoded)}</a>
       </span>
     );
   }
diff --git a/app/addons/replication/helpers.js b/app/addons/replication/helpers.js
index 52472fa..c436e02 100644
--- a/app/addons/replication/helpers.js
+++ b/app/addons/replication/helpers.js
@@ -14,7 +14,8 @@ import _ from 'underscore';
 
 const getDatabaseLabel = db => {
   const dbString = (_.isString(db)) ? db.trim().replace(/\/$/, '') : db.url;
-  return (new URL(dbString)).pathname.slice(1);
+  const pathName = (new URL(dbString)).pathname.slice(1);
+  return pathName.split("/").pop();
 };
 
 export default {
diff --git a/app/helpers.js b/app/helpers.js
index ed25130..53bef2a 100644
--- a/app/helpers.js
+++ b/app/helpers.js
@@ -78,6 +78,10 @@ Helpers.getServerUrl = endpointRoute => {
   return app.host + endpointRoute;
 };
 
+Helpers.getRootUrl = ({origin, pathname} = window.location) => {
+  return url.resolve(origin + pathname, app.host);
+};
+
 Helpers.getUUID = function (count = 1) {
   const url = Helpers.getServerUrl(`/_uuids?count=${count}`);
   return get(url);