Skip to content

Commit

Permalink
BDE-237 dynamic host permissions granting
Browse files Browse the repository at this point in the history
  • Loading branch information
nxmatic committed Jul 5, 2024
1 parent c9e953b commit 4a4616c
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 192 deletions.
14 changes: 4 additions & 10 deletions src/main/cookie-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,12 @@ class CookieManager extends ServiceWorkerComponent {
});
}

enable() {
chrome.tabs.query({}, (tabs) => {
tabs.forEach((tab) => {
const urlObj = new URL(tab.url);
const domain = urlObj.hostname;
chrome.cookies.getAll({ domain }, (cookies) => {
this._domainCookies.set(domain, cookies);
});
});
});
enable(domain) {
chrome.cookies.onChanged.addListener(this.onChanged);
this._undoStack.push(() => chrome.cookies.onChanged.removeListener(this.onCookieChanged));
return chrome.cookies.getAll({ domain }).then((cookies) => {
this._domainCookies.set(domain, cookies);
});
}

disable() {
Expand Down
2 changes: 0 additions & 2 deletions src/main/manifest-chrome.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
"tabs"
],
"host_permissions": [
"http://*.internal:*/*",
"http://localhost:8080/*",
"https://nos-preprod-connect.nuxeocloud.com/*",
"https://connect.nuxeo.com/*"
],
Expand Down
168 changes: 119 additions & 49 deletions src/main/server-connector.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,28 @@ class ServerConnector extends ServiceWorkerComponent {
// Define properties
this.disconnect = () => {};
this.nuxeo = undefined;
this.serverUrl = undefined;
this.serverLocation = undefined;
this.project = undefined;

this.nuxeoUrlOf = (tabLocation) => {
// eslint-disable-next-line operator-linebreak
// Regular expression pattern
const nxPattern = new RegExp([
'(^https?:\\/\\/[A-Za-z_\\.0-9:-]+\\/[A-Za-z_\\.0-9-]+)', // Match the start of a URL
'(',
'\\/(?:',
'(?:nxdoc|nxpath|nxsearch|nxadmin|nxhome|nxdam|nxdamid|site\\/[A-Za-z_\\.0-9-]+)\\/[A-Za-z_\\.0-9-]+|',
'view_documents\\.faces|ui\\/|ui\\/#!\\/|view_domains\\.faces|home\\.html|view_home\\.faces',
'))'
].join(''));
// match and reject non matching URLs
const matchGroups = nxPattern.exec(tabLocation);
const isMatching = Boolean(matchGroups && matchGroups[2]);
const [, extractedLocation] = isMatching ? matchGroups : [];

return isMatching ? new URL(extractedLocation) : undefined;
};

// Bind methods
Object.getOwnPropertyNames(Object.getPrototypeOf(this))
.filter((prop) => typeof this[prop] === 'function' && prop !== 'constructor')
Expand All @@ -62,48 +81,54 @@ class ServerConnector extends ServiceWorkerComponent {
});
}

onNewLocation(serverUrl) {
return this.isConnected()
.then((isConnected) => {
if (isConnected) this.disconnect();
return false;
})
.then(() => (serverUrl ? this.connect(serverUrl) : Promise.resolve()));
onNewLocation(tabLocation) {
return this.asPromise()
.then((self) => (this.disconnect(), self))
.then((self) => {
const nuxeoUrl = self.nuxeoUrlOf(tabLocation);
if (nuxeoUrl === undefined) {
return undefined;
}
self.connect(nuxeoUrl);
return nuxeoUrl;
});
}

connect(serverUrl) {
const url = new URL(serverUrl);
const forbiddenDomains = ['connect.nuxeo.com', 'nos-preprod-connect.nuxeo.com'];
if (forbiddenDomains.includes(url.host)) {
const error = new Error(`Connection to ${url.host} is forbidden`);
error.isForbidden = true;
throw error;
if (forbiddenDomains.includes(serverUrl.host)) {
return Promise.reject(new Error(`Connection to ${serverUrl.host} is forbidden`));
}
this.nuxeo = new Nuxeo({ baseURL: serverUrl });
this.serverUrl = serverUrl;
return this.nuxeo
.login()
// eslint-disable-next-line no-return-assign
return chrome.permissions.contains({
origins: [`${serverUrl.origin}/*`],
permissions: ['cookies', 'webRequest']
})
.then((granted) => {
if (!granted) {
throw new Error(`Permission to connect to ${serverUrl} is not granted`);
}
return this.worker.cookieManager.enable(serverUrl.host);
})
.then(() => this.nuxeo.login())
.then(() => {
chrome.omnibox.onInputChanged.addListener(this.onInputChanged = this.suggestDocument);
})
.then(() => () => {
this.disconnect = undefined;
this.nuxeo = undefined;
this.serverUrl = undefined;
chrome.omnibox.onInputChanged.removeListener(this.suggestDocument);
})
.then((disconnect) => {
this.disconnect = disconnect.bind(this);
return this.disconnect;
// Define disconnect logic here or in a separate method
this.disconnect = () => {
this.nuxeo = undefined;
this.serverLocation = undefined;
this.worker.cookieManager.disable();
chrome.omnibox.onInputChanged.removeListener(this.suggestDocument);
};
})
.catch((cause) => {
if (cause.response) {
this.handleErrors(cause);
return () => {};
}
console.warn('Error connecting to Nuxeo', cause);
throw cause;
console.warn(`Cannot connect to : ${serverUrl}...`, cause);
this.worker.desktopNotifier.notify('error', {
title: `Cannot connect to : ${serverUrl}...`,
message: `Got errors while accessing nuxeo at ${serverUrl}. Error: ${cause.message}`,
iconUrl: '../images/access_denied.png',
});
return () => {};
// Handle or rethrow the error as needed
});
}

Expand All @@ -118,7 +143,7 @@ class ServerConnector extends ServiceWorkerComponent {
])
.then(([installedAddons, connectRegistration]) => ({
nuxeo: this.nuxeo,
serverUrl: this.serverUrl,
serverLocation: this.serverLocation,
installedAddons,
connectRegistration,
}));
Expand All @@ -131,7 +156,7 @@ class ServerConnector extends ServiceWorkerComponent {
asConnectRegistration() {
return this
.executeScript('connect-registration')
.then((result) => ({ ...result, serverUrl: this.serverUrl }));
.then((result) => ({ ...result, serverLocation: this.serverLocation }));
}

asInstalledAddons() {
Expand All @@ -155,15 +180,15 @@ class ServerConnector extends ServiceWorkerComponent {
isRegistered,
isDesignerLivePreviewEnabled,
developmentMode,
serverUrl: this.serverUrl
serverLocation: this.serverLocation
}))
.catch((error) => (
{
packageName,
isRegistered,
isDesignerLivePreviewEnabled: false,
developmentMode,
serverUrl: this.serverUrl,
serverLocation: this.serverLocation,
inError: {
message: error.message,
stack: error.stack,
Expand All @@ -178,12 +203,12 @@ class ServerConnector extends ServiceWorkerComponent {
.then(({ connectUrl, clid: { CLID: clid }, package: { name: packageName } }) => {
const previousKey = this.registrationKeyOf({
connectUrl,
nuxeoUrl: this.serverUrl,
nuxeoUrl: this.serverLocation,
projectName: packageName,
});
const nextKey = this.registrationKeyOf({
connectUrl,
nuxeoUrl: this.serverUrl,
nuxeoUrl: this.serverLocation,
projectName
});
return this.worker.browserStore.get({ [previousKey]: clid, [nextKey]: undefined })
Expand All @@ -199,13 +224,58 @@ class ServerConnector extends ServiceWorkerComponent {
}

asNuxeo() {
return new Promise((resolve, reject) => {
if (this.nuxeo) {
resolve(this.nuxeo);
} else {
reject(new Error('Not connected to Nuxeo'));
}
});
// if (this.nuxeo) {
// return Promise.resolve(this.nuxeo);
// }
return this.worker
.tabNavigationHandler.asTabInfo()
.then((tabInfo) => this.nuxeoUrlOf(tabInfo.url))
.then((nuxeoUrl) => {
if (nuxeoUrl === undefined) {
return undefined;
}
this.connect(nuxeoUrl);
if (this.nuxeo === undefined) {
return Promise.reject(new Error('Not connected to Nuxeo'));
}
return this.nuxeo;
});
}

asServerUrl(tabInfo) {
return this.asPromise()
.then((self) => self.nuxeoUrlOf(tabInfo))
.then((nuxeoUrl) => {
if (!nuxeoUrl) return undefined;
return fetch(`${nuxeoUrl}/site/automation`, {
method: 'GET',
credentials: 'include', // Include cookies in the request
})
.then((response) => {
if (response.ok || response.status !== 401) return response;
this.worker.desktopNotifier.notify('unauthenticated', {
title: `Not logged in page: ${tabInfo.url}...`,
message: 'You are not authenticated. Please log in and try again.',
iconUrl: '../images/access_denied.png',
});
return this.worker.tabNavigationHandler.reloadServerTab({ rootUrl: nuxeoUrl, tabInfo });
})
.then((response) => {
if (response.ok) return response;
response.text().then((errorText) => {
this.worker.desktopNotifier.notify('error', {
title: `Not a Nuxeo server tab : ${tabInfo.url}...`,
message: `Got errors while accessing automation status page at ${response.url}. Error: ${errorText}`,
iconUrl: '../images/access_denied.png',
});
});
throw new Error(`Not a nuxeo server tab : ${tabInfo.url}...`);
})
.then(() => {
this.worker.desktopNotifier.cancel('unauthenticated');
return nuxeoUrl;
});
});
}

serverErrorDesktopNotification = {
Expand Down Expand Up @@ -365,7 +435,7 @@ class ServerConnector extends ServiceWorkerComponent {
.then(() => this
.desktopNotify('reload', {
title: 'Restarting server...',
message: `Attempting to restart Nuxeo server (${this.serverUrl})`,
message: `Attempting to restart Nuxeo server (${this.serverLocation})`,
iconUrl: '../images/nuxeo-128.png',
}))
.then(() => this.worker.tabNavigationHandler
Expand All @@ -376,7 +446,7 @@ class ServerConnector extends ServiceWorkerComponent {
this
.desktopNotify('error', {
title: 'Something went wrong...',
message: `An error occurred (${this.serverUrl}) : ${cause.message}`,
message: `An error occurred (${this.serverLocation}) : ${cause.message}`,
iconUrl: '../images/access_denied.png',
});
const error = new Error(`Error restarting server '${cause.message}'`);
Expand Down
Loading

0 comments on commit 4a4616c

Please sign in to comment.