mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Don't embed docs and external sites in iframes, to allow the external sites to set X-FRAME-OPTIONS = DENY for security. Fxies #3985
This commit is contained in:
@@ -17,4 +17,5 @@ Bug fixes
|
|||||||
| `Bug #3873 <https://redmine.postgresql.org/issues/3873>`_ - Fix context sub-menu alignment on Safari.
|
| `Bug #3873 <https://redmine.postgresql.org/issues/3873>`_ - Fix context sub-menu alignment on Safari.
|
||||||
| `Bug #3942 <https://redmine.postgresql.org/issues/3942>`_ - Close connections gracefully when the user logs out of pgAdmin.
|
| `Bug #3942 <https://redmine.postgresql.org/issues/3942>`_ - Close connections gracefully when the user logs out of pgAdmin.
|
||||||
| `Bug #3963 <https://redmine.postgresql.org/issues/3963>`_ - Fix alignment of import/export toggle switch.
|
| `Bug #3963 <https://redmine.postgresql.org/issues/3963>`_ - Fix alignment of import/export toggle switch.
|
||||||
| `Bug #3981 <https://redmine.postgresql.org/issues/3981>`_ - Fix the query to set bytea_output so that read-only standbys don't consider it a write query.
|
| `Bug #3981 <https://redmine.postgresql.org/issues/3981>`_ - Fix the query to set bytea_output so that read-only standbys don't consider it a write query.
|
||||||
|
| `Bug #3985 <https://redmine.postgresql.org/issues/3985>`_ - Don't embed docs and external sites in iframes, to allow the external sites to set X-FRAME-OPTIONS = DENY for security.
|
||||||
@@ -270,7 +270,7 @@ define('pgadmin.node.tablespace', [
|
|||||||
if (e.button.element.name == 'dialog_help') {
|
if (e.button.element.name == 'dialog_help') {
|
||||||
e.cancel = true;
|
e.cancel = true;
|
||||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||||
null, null, e.button.element.getAttribute('label'));
|
null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.button.text === gettext('OK')) {
|
if (e.button.text === gettext('OK')) {
|
||||||
|
|||||||
@@ -644,18 +644,8 @@ define('pgadmin.browser', [
|
|||||||
obj.enable_disable_menus();
|
obj.enable_disable_menus();
|
||||||
},
|
},
|
||||||
// General function to handle callbacks for object or dialog help.
|
// General function to handle callbacks for object or dialog help.
|
||||||
showHelp: function(type, url, node, item, label) {
|
showHelp: function(type, url, node, item) {
|
||||||
var iframe, pnlProperties;
|
|
||||||
if (type == 'object_help') {
|
if (type == 'object_help') {
|
||||||
// See if we can find an existing panel, if not, create one
|
|
||||||
var pnlSqlHelp = this.docker.findPanels('pnl_sql_help')[0];
|
|
||||||
|
|
||||||
if (pnlSqlHelp == null) {
|
|
||||||
pnlProperties = this.docker.findPanels('properties')[0];
|
|
||||||
this.docker.addPanel('pnl_sql_help', wcDocker.DOCK.STACKED, pnlProperties);
|
|
||||||
pnlSqlHelp = this.docker.findPanels('pnl_sql_help')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the URL
|
// Construct the URL
|
||||||
var server = node.getTreeNodeHierarchy(item).server;
|
var server = node.getTreeNodeHierarchy(item).server;
|
||||||
var baseUrl = pgBrowser.utils.pg_help_path;
|
var baseUrl = pgBrowser.utils.pg_help_path;
|
||||||
@@ -670,35 +660,11 @@ define('pgadmin.browser', [
|
|||||||
if (!S(baseUrl).endsWith('/')) {
|
if (!S(baseUrl).endsWith('/')) {
|
||||||
baseUrl = baseUrl + '/';
|
baseUrl = baseUrl + '/';
|
||||||
}
|
}
|
||||||
var fullUrl = baseUrl+ url;
|
var fullUrl = baseUrl + url;
|
||||||
// Update the panel
|
|
||||||
iframe = $(pnlSqlHelp).data('embeddedFrame');
|
|
||||||
pnlSqlHelp.title('Help: '+ label);
|
|
||||||
|
|
||||||
pnlSqlHelp.focus();
|
window.open(fullUrl, 'postgres_help');
|
||||||
iframe.openURL(fullUrl);
|
|
||||||
} else if(type == 'dialog_help') {
|
} else if(type == 'dialog_help') {
|
||||||
if(this.docker) {
|
window.open(url, 'pgadmin_help');
|
||||||
// See if we can find an existing panel, if not, create one
|
|
||||||
var pnlDialogHelp = this.docker.findPanels('pnl_online_help')[0];
|
|
||||||
|
|
||||||
if (pnlDialogHelp == null) {
|
|
||||||
pnlProperties = this.docker.findPanels('properties')[0];
|
|
||||||
this.docker.addPanel('pnl_online_help', wcDocker.DOCK.STACKED, pnlProperties);
|
|
||||||
pnlDialogHelp = this.docker.findPanels('pnl_online_help')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the panel
|
|
||||||
iframe = $(pnlDialogHelp).data('embeddedFrame');
|
|
||||||
|
|
||||||
pnlDialogHelp.focus();
|
|
||||||
iframe.openURL(url);
|
|
||||||
} else {
|
|
||||||
// We have added new functionality of opening Query tool & debugger in new
|
|
||||||
// browser tab, In that case we will not have docker object available
|
|
||||||
// so we will open dialog help in new browser tab
|
|
||||||
window.open(url, '_blank');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_findTreeChildNode: function(_i, _d, _o) {
|
_findTreeChildNode: function(_i, _d, _o) {
|
||||||
|
|||||||
@@ -1201,15 +1201,6 @@ define('pgadmin.browser.node', [
|
|||||||
j.append(content);
|
j.append(content);
|
||||||
}.bind(panel),
|
}.bind(panel),
|
||||||
onSqlHelp = function() {
|
onSqlHelp = function() {
|
||||||
// See if we can find an existing panel, if not, create one
|
|
||||||
var pnlSqlHelp = pgBrowser.docker.findPanels('pnl_sql_help')[0];
|
|
||||||
|
|
||||||
if (pnlSqlHelp == null) {
|
|
||||||
var pnlProperties = pgBrowser.docker.findPanels('properties')[0];
|
|
||||||
pgBrowser.docker.addPanel('pnl_sql_help', wcDocker.DOCK.STACKED, pnlProperties);
|
|
||||||
pnlSqlHelp = pgBrowser.docker.findPanels('pnl_sql_help')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct the URL
|
// Construct the URL
|
||||||
var server = that.getTreeNodeHierarchy(item).server;
|
var server = that.getTreeNodeHierarchy(item).server;
|
||||||
|
|
||||||
@@ -1237,29 +1228,11 @@ define('pgadmin.browser.node', [
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the panel
|
window.open(url, 'postgres_help');
|
||||||
var iframe = $(pnlSqlHelp).data('embeddedFrame');
|
|
||||||
pnlSqlHelp.title('SQL: ' + that.label);
|
|
||||||
|
|
||||||
pnlSqlHelp.focus();
|
|
||||||
iframe.openURL(url);
|
|
||||||
}.bind(panel),
|
}.bind(panel),
|
||||||
|
|
||||||
onDialogHelp = function() {
|
onDialogHelp = function() {
|
||||||
// See if we can find an existing panel, if not, create one
|
window.open(that.dialogHelp, 'pgadmin_help');
|
||||||
var pnlDialogHelp = pgBrowser.docker.findPanels('pnl_online_help')[0];
|
|
||||||
|
|
||||||
if (pnlDialogHelp == null) {
|
|
||||||
var pnlProperties = pgBrowser.docker.findPanels('properties')[0];
|
|
||||||
pgBrowser.docker.addPanel('pnl_online_help', wcDocker.DOCK.STACKED, pnlProperties);
|
|
||||||
pnlDialogHelp = pgBrowser.docker.findPanels('pnl_online_help')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the panel
|
|
||||||
var iframe = $(pnlDialogHelp).data('embeddedFrame');
|
|
||||||
|
|
||||||
pnlDialogHelp.focus();
|
|
||||||
iframe.openURL(that.dialogHelp);
|
|
||||||
}.bind(panel),
|
}.bind(panel),
|
||||||
|
|
||||||
onSave = function(view, saveBtn) {
|
onSave = function(view, saveBtn) {
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ define([
|
|||||||
'sources/gettext', 'sources/utils',
|
'sources/gettext', 'sources/utils',
|
||||||
], function(_, $, Backbone, pgAdmin, pgBrowser, gettext, commonUtils) {
|
], function(_, $, Backbone, pgAdmin, pgBrowser, gettext, commonUtils) {
|
||||||
|
|
||||||
var wcDocker = window.wcDocker;
|
|
||||||
|
|
||||||
/* Wizard individual Page Model */
|
/* Wizard individual Page Model */
|
||||||
pgBrowser.WizardPage = Backbone.Model.extend({
|
pgBrowser.WizardPage = Backbone.Model.extend({
|
||||||
defaults: {
|
defaults: {
|
||||||
@@ -309,20 +307,7 @@ define([
|
|||||||
return (_.isFunction(func) ? func.apply(ctx, [self]) : func);
|
return (_.isFunction(func) ? func.apply(ctx, [self]) : func);
|
||||||
},
|
},
|
||||||
onDialogHelp: function() {
|
onDialogHelp: function() {
|
||||||
// See if we can find an existing panel, if not, create one
|
window.open(this.options.wizard_help, 'pgadmin_help');
|
||||||
var pnlDialogHelp = pgBrowser.docker.findPanels('pnl_online_help')[0];
|
|
||||||
|
|
||||||
if (pnlDialogHelp == null) {
|
|
||||||
var pnlProperties = pgBrowser.docker.findPanels('properties')[0];
|
|
||||||
pgBrowser.docker.addPanel('pnl_online_help', wcDocker.DOCK.STACKED, pnlProperties);
|
|
||||||
pnlDialogHelp = pgBrowser.docker.findPanels('pnl_online_help')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the panel
|
|
||||||
var iframe = $(pnlDialogHelp).data('embeddedFrame');
|
|
||||||
|
|
||||||
pnlDialogHelp.focus();
|
|
||||||
iframe.openURL(this.options.wizard_help);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -47,25 +47,25 @@
|
|||||||
<div class="card-body p-2">
|
<div class="card-body p-2">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-3 dashboard-link">
|
<div class="col-3 dashboard-link">
|
||||||
<a href="http://www.postgresql.org/docs" target="_blank">
|
<a href="http://www.postgresql.org/docs" target="postgres_help">
|
||||||
<span class="fa fa-4x dashboard-icon dashboard-pg-doc" aria-hidden="true"></span><br/>
|
<span class="fa fa-4x dashboard-icon dashboard-pg-doc" aria-hidden="true"></span><br/>
|
||||||
{{ _('PostgreSQL Documentation') }}
|
{{ _('PostgreSQL Documentation') }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 dashboard-link">
|
<div class="col-3 dashboard-link">
|
||||||
<a href="https://www.pgadmin.org" target="_blank">
|
<a href="https://www.pgadmin.org" target="pgadmin_website">
|
||||||
<span class="fa fa-4x dashboard-icon fa-globe" aria-hidden="true"></span><br/>
|
<span class="fa fa-4x dashboard-icon fa-globe" aria-hidden="true"></span><br/>
|
||||||
{{ _('pgAdmin Website') }}
|
{{ _('pgAdmin Website') }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 dashboard-link">
|
<div class="col-3 dashboard-link">
|
||||||
<a href="http://planet.postgresql.org" target="_blank">
|
<a href="http://planet.postgresql.org" target="planet_website">
|
||||||
<span class="fa fa-4x dashboard-icon fa-book" aria-hidden="true"></span><br/>
|
<span class="fa fa-4x dashboard-icon fa-book" aria-hidden="true"></span><br/>
|
||||||
{{ _('Planet PostgreSQL') }}
|
{{ _('Planet PostgreSQL') }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3 dashboard-link">
|
<div class="col-3 dashboard-link">
|
||||||
<a href="http://www.postgresql.org/community" target="_blank">
|
<a href="http://www.postgresql.org/community" target="postgres_website">
|
||||||
<span class="fa fa-4x dashboard-icon fa-users" aria-hidden="true"></span><br/>
|
<span class="fa fa-4x dashboard-icon fa-users" aria-hidden="true"></span><br/>
|
||||||
{{ _('Community Support') }}
|
{{ _('Community Support') }}
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -26,40 +26,24 @@ class HelpModule(PgAdminModule):
|
|||||||
MenuItem(name='mnu_online_help',
|
MenuItem(name='mnu_online_help',
|
||||||
label=gettext('Online Help'),
|
label=gettext('Online Help'),
|
||||||
priority=100,
|
priority=100,
|
||||||
target='_blank',
|
target='pgadmin_help',
|
||||||
icon='fa fa-question',
|
icon='fa fa-question',
|
||||||
url=url_for('help.static', filename='index.html')),
|
url=url_for('help.static', filename='index.html')),
|
||||||
|
|
||||||
MenuItem(name='mnu_pgadmin_website',
|
MenuItem(name='mnu_pgadmin_website',
|
||||||
label=gettext('pgAdmin Website'),
|
label=gettext('pgAdmin Website'),
|
||||||
priority=200,
|
priority=200,
|
||||||
target='_blank',
|
target='pgadmin_website',
|
||||||
icon='fa fa-external-link',
|
icon='fa fa-external-link',
|
||||||
url='https://www.pgadmin.org/'),
|
url='https://www.pgadmin.org/'),
|
||||||
|
|
||||||
MenuItem(name='mnu_postgresql_website',
|
MenuItem(name='mnu_postgresql_website',
|
||||||
label=gettext('PostgreSQL Website'),
|
label=gettext('PostgreSQL Website'),
|
||||||
priority=300,
|
priority=300,
|
||||||
target='_blank',
|
target='postgres_website',
|
||||||
icon='fa fa-external-link',
|
icon='fa fa-external-link',
|
||||||
url='https://www.postgresql.org/')]}
|
url='https://www.postgresql.org/')]}
|
||||||
|
|
||||||
def get_panels(self):
|
|
||||||
return [
|
|
||||||
Panel(
|
|
||||||
name='pnl_online_help',
|
|
||||||
priority=100,
|
|
||||||
isPrivate=True,
|
|
||||||
title=gettext('Online Help'),
|
|
||||||
icon='fa fa-question').__dict__,
|
|
||||||
|
|
||||||
Panel(
|
|
||||||
name='pnl_sql_help',
|
|
||||||
priority=200,
|
|
||||||
isPrivate=True,
|
|
||||||
icon='fa fa-info',
|
|
||||||
title=gettext('SQL Help')).__dict__]
|
|
||||||
|
|
||||||
def register_preferences(self):
|
def register_preferences(self):
|
||||||
"""
|
"""
|
||||||
register_preferences
|
register_preferences
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ define('pgadmin.preferences', [
|
|||||||
if (e.button.element.name == 'dialog_help') {
|
if (e.button.element.name == 'dialog_help') {
|
||||||
e.cancel = true;
|
e.cancel = true;
|
||||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||||
null, null, e.button.element.getAttribute('label'));
|
null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ let FilterDialog = {
|
|||||||
if (e.button.element.name == 'dialog_help') {
|
if (e.button.element.name == 'dialog_help') {
|
||||||
e.cancel = true;
|
e.cancel = true;
|
||||||
pgAdmin.Browser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
pgAdmin.Browser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||||
null, null, e.button.element.getAttribute('label'));
|
null, null);
|
||||||
return;
|
return;
|
||||||
} else if (e.button['data-btn-name'] === 'ok') {
|
} else if (e.button['data-btn-name'] === 'ok') {
|
||||||
e.cancel = true; // Do not close dialog
|
e.cancel = true; // Do not close dialog
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ export class BackupDialogWrapper extends DialogWrapper {
|
|||||||
event.button.element.name,
|
event.button.element.name,
|
||||||
event.button.element.getAttribute('url'),
|
event.button.element.getAttribute('url'),
|
||||||
node,
|
node,
|
||||||
selectedTreeNode.getHtmlIdentifier(),
|
selectedTreeNode.getHtmlIdentifier()
|
||||||
event.button.element.getAttribute('label')
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ define([
|
|||||||
if (e.button.element.name == 'dialog_help' || e.button.element.name == 'object_help') {
|
if (e.button.element.name == 'dialog_help' || e.button.element.name == 'object_help') {
|
||||||
e.cancel = true;
|
e.cancel = true;
|
||||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||||
node, i, e.button.element.getAttribute('label'));
|
node, i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ export class RestoreDialogWrapper extends DialogWrapper {
|
|||||||
event.button.element.name,
|
event.button.element.name,
|
||||||
event.button.element.getAttribute('url'),
|
event.button.element.getAttribute('url'),
|
||||||
node,
|
node,
|
||||||
selectedTreeNode.getHtmlIdentifier(),
|
selectedTreeNode.getHtmlIdentifier()
|
||||||
event.button.element.getAttribute('label')
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ define([
|
|||||||
if (e.button.element.name == 'dialog_help') {
|
if (e.button.element.name == 'dialog_help') {
|
||||||
e.cancel = true;
|
e.cancel = true;
|
||||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||||
null, null, e.button.element.getAttribute('label'));
|
null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -868,7 +868,7 @@ define([
|
|||||||
if (e.button.element.name == 'dialog_help') {
|
if (e.button.element.name == 'dialog_help') {
|
||||||
e.cancel = true;
|
e.cancel = true;
|
||||||
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
|
||||||
null, null, e.button.element.getAttribute('label'));
|
null, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.button.element.name == 'close') {
|
if (e.button.element.name == 'close') {
|
||||||
|
|||||||
@@ -245,8 +245,6 @@ describe('BackupDialogWrapper', () => {
|
|||||||
getAttribute: (attributeName) => {
|
getAttribute: (attributeName) => {
|
||||||
if (attributeName === 'url') {
|
if (attributeName === 'url') {
|
||||||
return 'http://someurl';
|
return 'http://someurl';
|
||||||
} else if (attributeName === 'label') {
|
|
||||||
return 'some label';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -260,8 +258,7 @@ describe('BackupDialogWrapper', () => {
|
|||||||
'dialog_help',
|
'dialog_help',
|
||||||
'http://someurl',
|
'http://someurl',
|
||||||
pgBrowser.Nodes['server'],
|
pgBrowser.Nodes['server'],
|
||||||
serverTreeNode.getHtmlIdentifier(),
|
serverTreeNode.getHtmlIdentifier()
|
||||||
'some label'
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -288,8 +285,6 @@ describe('BackupDialogWrapper', () => {
|
|||||||
getAttribute: (attributeName) => {
|
getAttribute: (attributeName) => {
|
||||||
if (attributeName === 'url') {
|
if (attributeName === 'url') {
|
||||||
return 'http://someurl';
|
return 'http://someurl';
|
||||||
} else if (attributeName === 'label') {
|
|
||||||
return 'some label';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -303,8 +298,7 @@ describe('BackupDialogWrapper', () => {
|
|||||||
'object_help',
|
'object_help',
|
||||||
'http://someurl',
|
'http://someurl',
|
||||||
pgBrowser.Nodes['server'],
|
pgBrowser.Nodes['server'],
|
||||||
serverTreeNode.getHtmlIdentifier(),
|
serverTreeNode.getHtmlIdentifier()
|
||||||
'some label'
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -252,8 +252,7 @@ describe('RestoreDialogWrapper', () => {
|
|||||||
'dialog_help',
|
'dialog_help',
|
||||||
'http://someurl',
|
'http://someurl',
|
||||||
pgBrowser.Nodes['server'],
|
pgBrowser.Nodes['server'],
|
||||||
serverTreeNode.getHtmlIdentifier(),
|
serverTreeNode.getHtmlIdentifier()
|
||||||
'some label'
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -294,8 +293,7 @@ describe('RestoreDialogWrapper', () => {
|
|||||||
'object_help',
|
'object_help',
|
||||||
'http://someurl',
|
'http://someurl',
|
||||||
pgBrowser.Nodes['server'],
|
pgBrowser.Nodes['server'],
|
||||||
serverTreeNode.getHtmlIdentifier(),
|
serverTreeNode.getHtmlIdentifier()
|
||||||
'some label'
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user