mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-15 08:30:46 +02:00
Refactor srv-web-7-7-inj-port-ui-desktop to use CDN-served JS file with inline initializer
- Added vars/main.yml to define iframe-handler.js file name and destination - Implemented 01_deploy.yml to deploy iframe-handler.js to CDN and set mtime-based version fact - Split original iframe logic into: • iframe-handler.js (full logic, served from CDN) • iframe-init_one_liner.js.j2 (small inline bootstrap, CSP-hashed) - Updated head_sub.j2 to load script from CDN instead of embedding full code - Added body_sub.j2 for inline init code - Updated iframe-handler.js.j2 with initIframeHandler() function and global exposure - Activated role earlier in inj-compose with public: true so vars are available for templates - Included 'port-ui-desktop' in body_snippets loop in location.lua.j2 - Disabled 'port-ui-desktop' feature in web-svc-cdn config by default https://chatgpt.com/share/689d03a8-4c28-800f-8b06-58ce2807b075
This commit is contained in:
parent
2fba32d384
commit
a40d48bb03
@ -15,6 +15,12 @@
|
|||||||
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
|
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
|
||||||
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"
|
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"
|
||||||
|
|
||||||
|
- name: "Activate Portfolio iFrame notifier for {{ domain }}"
|
||||||
|
include_role:
|
||||||
|
name: srv-web-7-7-inj-port-ui-desktop
|
||||||
|
public: true # Expose variables so that they can be used in template
|
||||||
|
when: inj_enabled.port_ui
|
||||||
|
|
||||||
- name: "Load CDN for {{domain}}"
|
- name: "Load CDN for {{domain}}"
|
||||||
include_role:
|
include_role:
|
||||||
name: web-svc-cdn
|
name: web-svc-cdn
|
||||||
@ -56,11 +62,6 @@
|
|||||||
name: srv-web-7-7-inj-matomo
|
name: srv-web-7-7-inj-matomo
|
||||||
when: inj_enabled.matomo
|
when: inj_enabled.matomo
|
||||||
|
|
||||||
- name: "Activate Portfolio iFrame notifier for {{ domain }}"
|
|
||||||
include_role:
|
|
||||||
name: srv-web-7-7-inj-port-ui-desktop
|
|
||||||
when: inj_enabled.port_ui
|
|
||||||
|
|
||||||
- name: "Activate Javascript for {{ domain }}"
|
- name: "Activate Javascript for {{ domain }}"
|
||||||
include_role:
|
include_role:
|
||||||
name: srv-web-7-7-inj-javascript
|
name: srv-web-7-7-inj-javascript
|
||||||
|
@ -58,7 +58,7 @@ body_filter_by_lua_block {
|
|||||||
-- build a list of body-injection snippets
|
-- build a list of body-injection snippets
|
||||||
local body_snippets = {}
|
local body_snippets = {}
|
||||||
|
|
||||||
{% for body_feature in ['matomo', 'logout' ] %}
|
{% for body_feature in ['matomo', 'logout', 'port-ui-desktop'] %}
|
||||||
{% if applications | get_app_conf(application_id, 'features.' ~ body_feature, false) | bool %}
|
{% if applications | get_app_conf(application_id, 'features.' ~ body_feature, false) | bool %}
|
||||||
body_snippets[#body_snippets + 1] = [=[
|
body_snippets[#body_snippets + 1] = [=[
|
||||||
{%- include "roles/srv-web-7-7-inj-" ~ body_feature ~ "/templates/body_sub.j2" -%}
|
{%- include "roles/srv-web-7-7-inj-" ~ body_feature ~ "/templates/body_sub.j2" -%}
|
||||||
|
16
roles/srv-web-7-7-inj-port-ui-desktop/tasks/01_deploy.yml
Normal file
16
roles/srv-web-7-7-inj-port-ui-desktop/tasks/01_deploy.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
- name: Deploy iframe-handler.js
|
||||||
|
template:
|
||||||
|
src: iframe-handler.js.j2
|
||||||
|
dest: "{{ inj_port_ui_js_destination }}"
|
||||||
|
owner: "{{ nginx.user }}"
|
||||||
|
group: "{{ nginx.user }}"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Get stat for iframe-handler.js
|
||||||
|
stat:
|
||||||
|
path: "{{ inj_port_ui_js_destination }}"
|
||||||
|
register: inj_port_ui_js_stat
|
||||||
|
|
||||||
|
- name: Set inj_port_ui_js_version
|
||||||
|
set_fact:
|
||||||
|
inj_port_ui_js_version: "{{ inj_port_ui_js_stat.stat.mtime }}"
|
@ -3,18 +3,20 @@
|
|||||||
include_role:
|
include_role:
|
||||||
name: srv-web-7-4-core
|
name: srv-web-7-4-core
|
||||||
when: run_once_srv_web_7_4_core is not defined
|
when: run_once_srv_web_7_4_core is not defined
|
||||||
|
- include_tasks: 01_deploy.yml
|
||||||
- include_tasks: utils/run_once.yml
|
- include_tasks: utils/run_once.yml
|
||||||
when: run_once_srv_web_7_7_inj_port_ui_desktop is not defined
|
when: run_once_srv_web_7_7_inj_port_ui_desktop is not defined
|
||||||
|
|
||||||
- name: "Load iFrame handler JS template for '{{ application_id }}'"
|
# --- Build tiny inline initializer (CSP-hashed) ---
|
||||||
|
- name: "Load iFrame init code for '{{ application_id }}'"
|
||||||
set_fact:
|
set_fact:
|
||||||
iframe_code: "{{ lookup('template','iframe-handler.js.j2') }}"
|
iframe_init_code: "{{ lookup('template','iframe-init_one_liner.js.j2') }}"
|
||||||
|
|
||||||
- name: "Collapse iFrame code into one-liner for '{{ application_id }}'"
|
- name: "Collapse iFrame init code into one-liner for '{{ application_id }}'"
|
||||||
set_fact:
|
set_fact:
|
||||||
iframe_code_one_liner: "{{ iframe_code | to_one_liner }}"
|
iframe_init_code_one_liner: "{{ iframe_init_code | to_one_liner }}"
|
||||||
|
|
||||||
- name: "Append iFrame CSP hash for '{{ application_id }}'"
|
- name: "Append iFrame init CSP hash for '{{ application_id }}'"
|
||||||
set_fact:
|
set_fact:
|
||||||
applications: "{{ applications | append_csp_hash(application_id, iframe_code_one_liner) }}"
|
applications: "{{ applications | append_csp_hash(application_id, iframe_init_code_one_liner) }}"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<script>{{ iframe_init_code_one_liner }}</script>
|
@ -1 +1 @@
|
|||||||
<script>{{ iframe_code_one_liner }}</script>
|
<script src="{{ domains | get_url('web-svc-cdn', WEB_PROTOCOL) }}/{{ inj_port_ui_file_name }}?{{ inj_port_ui_js_version }}"></script>
|
@ -1,48 +1,57 @@
|
|||||||
(function() {
|
(function (global) {
|
||||||
var primary = "{{ PRIMARY_DOMAIN }}";
|
/**
|
||||||
var allowedOrigin = "https://{{ domains | get_domain('web-app-port-ui') }}";
|
* Initializes the iframe sync & external link forcing logic.
|
||||||
|
* @param {string} primary_domain
|
||||||
function notifyParent() {
|
* @param {string} current_domain
|
||||||
if (window.self !== window.top) {
|
* @param {string} allowedOrigin - Parent origin for postMessage
|
||||||
try {
|
*/
|
||||||
window.parent.postMessage({
|
function initIframeHandler(primary_domain, current_domain, allowedOrigin) {
|
||||||
type: "iframeLocationChange",
|
function notifyParent() {
|
||||||
href: window.location.href
|
if (window.self !== window.top) {
|
||||||
}, allowedOrigin);
|
try {
|
||||||
} catch (e) {}
|
window.parent.postMessage(
|
||||||
|
{ type: "iframeLocationChange", href: window.location.href },
|
||||||
|
allowedOrigin
|
||||||
|
);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function forceExternalLinks() {
|
function forceExternalLinks() {
|
||||||
Array.prototype.forEach.call(document.querySelectorAll("a[href]"), function(a) {
|
Array.prototype.forEach.call(document.querySelectorAll("a[href]"), function (a) {
|
||||||
try {
|
try {
|
||||||
var url = new URL(a.href, location);
|
var url = new URL(a.href, location);
|
||||||
if (!url.hostname.endsWith(primary)) {
|
// open new tab if link goes outside our primary OR current domain
|
||||||
a.target = "_blank";
|
if (!(url.hostname.endsWith(primary_domain) || url.hostname.endsWith(current_domain))) {
|
||||||
a.rel = "noopener";
|
a.target = "_blank";
|
||||||
}
|
a.rel = "noopener";
|
||||||
} catch (e) {}
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("load", function () {
|
||||||
|
notifyParent();
|
||||||
|
forceExternalLinks();
|
||||||
});
|
});
|
||||||
|
window.addEventListener("popstate", function () {
|
||||||
|
notifyParent();
|
||||||
|
forceExternalLinks();
|
||||||
|
});
|
||||||
|
|
||||||
|
// SPA support
|
||||||
|
var _pushState = history.pushState;
|
||||||
|
history.pushState = function () {
|
||||||
|
_pushState.apply(history, arguments);
|
||||||
|
notifyParent();
|
||||||
|
forceExternalLinks();
|
||||||
|
};
|
||||||
|
|
||||||
|
{% if MODE_DEBUG | bool %}
|
||||||
|
try { console.log("[iframe-sync] initIframeHandler installed."); } catch (e) {}
|
||||||
|
{% endif %}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", function() {
|
// expose for inline bootstrap
|
||||||
notifyParent();
|
global.initIframeHandler = initIframeHandler;
|
||||||
forceExternalLinks();
|
})(window);
|
||||||
});
|
|
||||||
window.addEventListener("popstate", function() {
|
|
||||||
notifyParent();
|
|
||||||
forceExternalLinks();
|
|
||||||
});
|
|
||||||
|
|
||||||
// SPA support
|
|
||||||
var _pushState = history.pushState;
|
|
||||||
history.pushState = function() {
|
|
||||||
_pushState.apply(history, arguments);
|
|
||||||
notifyParent();
|
|
||||||
forceExternalLinks();
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
{% if MODE_DEBUG | bool %}
|
|
||||||
console.log("[iframe-sync] Sender for iframe messages is active.");
|
|
||||||
{% endif %}
|
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
initIframeHandler(
|
||||||
|
'{{ PRIMARY_DOMAIN }}',
|
||||||
|
'{{ domain }}',
|
||||||
|
'{{ domains | get_url("web-app-port-ui", WEB_PROTOCOL) }}'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
{% if MODE_DEBUG | bool %}
|
||||||
|
try { console.log("[iframe-sync] Sender for iframe messages is active."); } catch(e) {}
|
||||||
|
{% endif %}
|
2
roles/srv-web-7-7-inj-port-ui-desktop/vars/main.yml
Normal file
2
roles/srv-web-7-7-inj-port-ui-desktop/vars/main.yml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
inj_port_ui_file_name: "iframe-handler.js"
|
||||||
|
inj_port_ui_js_destination: "{{ [ nginx.directories.data.cdn, inj_port_ui_file_name ] | path_join }}"
|
@ -1,7 +1,7 @@
|
|||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: true
|
css: true
|
||||||
port-ui-desktop: true
|
port-ui-desktop: false
|
||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user