mirror of
https://github.com/nextcloud/all-in-one.git
synced 2026-05-21 10:50:10 +00:00
aio-interface: improve headers (#7690)
Signed-off-by: Zoey <zoey@z0ey.de> Signed-off-by: Simon L. <szaimen@e.mail.de> Signed-off-by: Pablo Zmdl <pablo@nextcloud.com> Co-authored-by: Simon L. <szaimen@e.mail.de> Co-authored-by: Pablo Zmdl <pablo@nextcloud.com>
This commit is contained in:
4
.github/workflows/playwright-on-push.yml
vendored
4
.github/workflows/playwright-on-push.yml
vendored
@@ -68,6 +68,8 @@ jobs:
|
|||||||
--publish 8080:8080 \
|
--publish 8080:8080 \
|
||||||
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
|
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
|
||||||
--volume ./php:/var/www/docker-aio/php \
|
--volume ./php:/var/www/docker-aio/php \
|
||||||
|
--volume ./Containers/mastercontainer/internal.Caddyfile:/internal.Caddyfile \
|
||||||
|
--volume ./Containers/mastercontainer/headers.Caddyfile:/headers.Caddyfile \
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
|
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
|
||||||
--env SKIP_DOMAIN_VALIDATION=true \
|
--env SKIP_DOMAIN_VALIDATION=true \
|
||||||
--env APACHE_PORT=11000 \
|
--env APACHE_PORT=11000 \
|
||||||
@@ -97,6 +99,8 @@ jobs:
|
|||||||
--publish 8080:8080 \
|
--publish 8080:8080 \
|
||||||
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
|
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
|
||||||
--volume ./php:/var/www/docker-aio/php \
|
--volume ./php:/var/www/docker-aio/php \
|
||||||
|
--volume ./Containers/mastercontainer/internal.Caddyfile:/internal.Caddyfile \
|
||||||
|
--volume ./Containers/mastercontainer/headers.Caddyfile:/headers.Caddyfile \
|
||||||
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
|
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
|
||||||
--env SKIP_DOMAIN_VALIDATION=false \
|
--env SKIP_DOMAIN_VALIDATION=false \
|
||||||
--env APACHE_PORT=11000 \
|
--env APACHE_PORT=11000 \
|
||||||
|
|||||||
@@ -17,8 +17,11 @@
|
|||||||
https://{$ADDITIONAL_TRUSTED_DOMAIN}:443,
|
https://{$ADDITIONAL_TRUSTED_DOMAIN}:443,
|
||||||
http://{$APACHE_HOST}.nextcloud-aio:23973, # For Collabora callback and WOPI requests, see containers.json
|
http://{$APACHE_HOST}.nextcloud-aio:23973, # For Collabora callback and WOPI requests, see containers.json
|
||||||
{$PROTOCOL}://{$NC_DOMAIN}:{$APACHE_PORT} {
|
{$PROTOCOL}://{$NC_DOMAIN}:{$APACHE_PORT} {
|
||||||
header -Server
|
header {
|
||||||
header -X-Powered-By
|
-Server
|
||||||
|
-X-Powered-By
|
||||||
|
-Via
|
||||||
|
}
|
||||||
|
|
||||||
# Collabora
|
# Collabora
|
||||||
route /browser/* {
|
route /browser/* {
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ http://:80 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
https://:8443 {
|
https://:8443 {
|
||||||
|
import headers.Caddyfile
|
||||||
|
|
||||||
@denied {
|
@denied {
|
||||||
path /api/auth/login /api/auth/getlogin
|
path /api/auth/login /api/auth/getlogin
|
||||||
remote_host nextcloud-aio-nextcloud
|
remote_host nextcloud-aio-nextcloud
|
||||||
|
|||||||
27
Containers/mastercontainer/headers.Caddyfile
Normal file
27
Containers/mastercontainer/headers.Caddyfile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
header {
|
||||||
|
# CSP limits which features can be used. By default we allow nothing and only allow required options. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy
|
||||||
|
# default-src 'none'; Allow nothing by default
|
||||||
|
# script-src-elem/style-src-elem 'self'; Only allow loading css/js files from same origin (AIO itself) while blocking all inline css/js
|
||||||
|
# img-src 'self'; Only allow loading images from same origin (from AIO itself)
|
||||||
|
# connect-src 'self'; Allow fetch to only connect same origin (to AIO itself)
|
||||||
|
# frame-src 'self'; Allow AIO to only embed itself "what can be embedded"
|
||||||
|
# base-uri 'none'; This does not fallback to default-src, AIO does not use the html base tag
|
||||||
|
# form-action 'self'; Html forms are only allowed to submit to AIO and not cross origin
|
||||||
|
# frame-ancestors 'self'; Only allow AIO itself to embed it self "who can embed"
|
||||||
|
# upgrade-insecure-requests; Upgrade all http embedings to https
|
||||||
|
# require-trusted-types-for 'script'; trusted-types 'none'; Blocks DOM changes via js
|
||||||
|
Content-Security-Policy "default-src 'none'; script-src-elem 'self'; style-src-elem 'self'; img-src 'self'; connect-src 'self'; frame-src 'self'; base-uri 'none'; form-action 'self'; frame-ancestors 'self'; upgrade-insecure-requests; require-trusted-types-for 'script'; trusted-types 'none';"
|
||||||
|
X-Content-Type-Options "nosniff" # This forces the browser to use the MIME type of the Content-Type header. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options
|
||||||
|
X-Frame-Options "SAMEORIGIN" # Only allow AIO itself to embed itself, this is also enforced as part of the CSP frame-ancestors. See https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/X-Frame-Options
|
||||||
|
X-Permitted-Cross-Domain-Policies "none" # We block all cross origin request, including ones from Adobe Acrobat or Microsoft Silverlight and Adobe Flash Player. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Permitted-Cross-Domain-Policies
|
||||||
|
X-DNS-Prefetch-Control "off" # Tells the browser to not pre-fetch the DNS of linked pages. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-DNS-Prefetch-Control
|
||||||
|
Referrer-Policy "no-referrer" # Tells the browser to never sent a Referer header. See https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/Referrer-Policy
|
||||||
|
X-Robots-Tag "noindex, nofollow" # Tells web crawlers to not index this page. See https://developer.mozilla.org/de/docs/Web/HTTP/Reference/Headers/X-Robots-Tag
|
||||||
|
Cross-Origin-Opener-Policy "same-origin"; # AIO does not use any popup, still we can isolate its BCG if it is opened as a pop up by another page. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cross-Origin-Opener-Policy
|
||||||
|
Cross-Origin-Embedder-Policy "require-corp"; # Harder rules for cross origin embeds. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cross-Origin-Embedder-Policy
|
||||||
|
Cross-Origin-Resource-Policy "same-origin"; # Only allow the same origin to load resources. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cross-Origin_Resource_Policy
|
||||||
|
|
||||||
|
-Server
|
||||||
|
-X-Powered-By
|
||||||
|
-Via
|
||||||
|
}
|
||||||
@@ -24,6 +24,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
https://:8080 {
|
https://:8080 {
|
||||||
|
import headers.Caddyfile
|
||||||
|
|
||||||
@denied {
|
@denied {
|
||||||
path /api/auth/login /api/auth/getlogin
|
path /api/auth/login /api/auth/getlogin
|
||||||
remote_host nextcloud-aio-nextcloud
|
remote_host nextcloud-aio-nextcloud
|
||||||
|
|||||||
27
php/public/click-handlers.js
Normal file
27
php/public/click-handlers.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
document.querySelectorAll('input[data-confirm]').forEach((element) => {
|
||||||
|
element.addEventListener('click', (event) => {
|
||||||
|
if (!confirm(element.dataset.confirm)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
document.querySelectorAll('input[data-input-show-password]').forEach((element) => {
|
||||||
|
element.addEventListener('input', (element) => {
|
||||||
|
let passwordField = element
|
||||||
|
if (passwordField.type === "password" && passwordField.value !== "") {
|
||||||
|
passwordField.type = "text";
|
||||||
|
} else if (passwordField.type === "text" && passwordField.value === "") {
|
||||||
|
passwordField.type = "password";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('[data-stop-event-propagation="true"]').forEach((element) => {
|
||||||
|
element.addEventListener('click', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,14 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function showPassword(id) {
|
|
||||||
let passwordField = document.getElementById(id);
|
|
||||||
if (passwordField.type === "password" && passwordField.value !== "") {
|
|
||||||
passwordField.type = "text";
|
|
||||||
} else if (passwordField.type === "text" && passwordField.value === "") {
|
|
||||||
passwordField.type = "password";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(function (){
|
(function (){
|
||||||
let lastError;
|
let lastError;
|
||||||
|
|
||||||
|
|||||||
3
php/public/img/collabora.svg
Normal file
3
php/public/img/collabora.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-left: 4px;">
|
||||||
|
<path d="M6 12L10 8L6 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 270 B |
3
php/public/img/office-none.svg
Normal file
3
php/public/img/office-none.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-right: 6px;">
|
||||||
|
<path d="M2 2L14 14M2 14L14 2" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 253 B |
3
php/public/img/onlyoffice.svg
Normal file
3
php/public/img/onlyoffice.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-left: 4px;">
|
||||||
|
<path d="M6 12L10 8L6 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 270 B |
49
php/public/logs.css
Normal file
49
php/public/logs.css
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
margin: 0;
|
||||||
|
padding: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
#floating-box {
|
||||||
|
position: fixed;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
max-width: calc(100vw - 2rem);
|
||||||
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
justify-content: end;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#autoloading-box {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: large;
|
||||||
|
border: solid thin gray;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
width: 10rem;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
margin: 0 0 0 1rem;
|
||||||
|
}
|
||||||
|
.loader {
|
||||||
|
opacity: 1;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
align-self: inherit;
|
||||||
|
}
|
||||||
|
@starting-style {
|
||||||
|
.loader {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.loader.hidden {
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 1s, display 1s allow-discrete;
|
||||||
|
}
|
||||||
9
php/public/scroll-into-view.js
Normal file
9
php/public/scroll-into-view.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
const observer = new MutationObserver((records) => {
|
||||||
|
const node = records[0]?.addedNodes[0];
|
||||||
|
// Text nodes also appear here but can't be scrolled to, so we have to check for the
|
||||||
|
// function being present.
|
||||||
|
if (node && typeof(node.scrollIntoView) === 'function') {
|
||||||
|
node.scrollIntoView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(document, {childList: true, subtree: true});
|
||||||
@@ -32,4 +32,7 @@ function setThemeIcon(theme) {
|
|||||||
setThemeToDOM(getSavedTheme());
|
setThemeToDOM(getSavedTheme());
|
||||||
|
|
||||||
// Apply theme when the page loads
|
// Apply theme when the page loads
|
||||||
document.addEventListener('DOMContentLoaded', () => setThemeIcon(getSavedTheme()));
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
setThemeIcon(getSavedTheme())
|
||||||
|
document.querySelector('button#theme-toggle')?.addEventListener('click', () => toggleTheme());
|
||||||
|
});
|
||||||
|
|||||||
@@ -381,17 +381,7 @@ readonly class DockerController {
|
|||||||
<html lang="en" class="overlay-iframe">
|
<html lang="en" class="overlay-iframe">
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="../../style.css?v8" media="all" />
|
<link rel="stylesheet" href="../../style.css?v8" media="all" />
|
||||||
<script>
|
<script type="text/javascript" src="../../scroll-into-view.js"></script>
|
||||||
const observer = new MutationObserver((records) => {
|
|
||||||
const node = records[0]?.addedNodes[0];
|
|
||||||
// Text nodes also appear here but can't be scrolled to, so we have to check for the
|
|
||||||
// function being present.
|
|
||||||
if (node && typeof(node.scrollIntoView) === 'function') {
|
|
||||||
node.scrollIntoView();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
observer.observe(document, {childList: true, subtree: true});
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@
|
|||||||
<form method="POST" action="api/docker/backup-check-repair" target="overlay-log">
|
<form method="POST" action="api/docker/backup-check-repair" target="overlay-log">
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" value="Check and repair backup integrity" onclick="return confirm('Check and repair backup integrity? Are you sure that you want to check and repair the backup integrity? This should only be done after reading the mentioned documentation.')"/>
|
<input type="submit" value="Check and repair backup integrity" data-confirm='Check and repair backup integrity? Are you sure that you want to check and repair the backup integrity? This should only be done after reading the mentioned documentation.'/>
|
||||||
</form>
|
</form>
|
||||||
</details>
|
</details>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -178,7 +178,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select><br>
|
</select><br>
|
||||||
<input type="checkbox" id="restore-exclude-previews" name="restore-exclude-previews"><label for="restore-exclude-previews">Exclude previews from restore which will speed up the restore process but will trigger a scan of the preview folder as soon as the Nextcloud container starts the next time</label><br>
|
<input type="checkbox" id="restore-exclude-previews" name="restore-exclude-previews"><label for="restore-exclude-previews">Exclude previews from restore which will speed up the restore process but will trigger a scan of the preview folder as soon as the Nextcloud container starts the next time</label><br>
|
||||||
<input type="submit" value="Restore selected backup" onclick="return confirm('⚠️ Important: If the backup that you want to restore contained any community container, you need to restore the same backup a second time after this attempt so that the community container data is also correctly restored.')"/>
|
<input type="submit" value="Restore selected backup" data-confirm='⚠️ Important: If the backup that you want to restore contained any community container, you need to restore the same backup a second time after this attempt so that the community container data is also correctly restored.'/>
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elseif borg_backup_mode == 'restore' %}
|
{% elseif borg_backup_mode == 'restore' %}
|
||||||
@@ -366,7 +366,7 @@
|
|||||||
{% if bypass_container_update == true %}
|
{% if bypass_container_update == true %}
|
||||||
<input type="hidden" name="bypass_container_update" value="true">
|
<input type="hidden" name="bypass_container_update" value="true">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<input class="button " type="submit" value="Start and update containers" onclick="return confirm('Start and update containers? You should consider creating a backup first.')" />
|
<input class="button " type="submit" value="Start and update containers" data-confirm='Start and update containers? You should consider creating a backup first.' />
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -413,7 +413,7 @@
|
|||||||
<form method="POST" action="api/docker/backup-check-repair" target="overlay-log">
|
<form method="POST" action="api/docker/backup-check-repair" target="overlay-log">
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" value="Check and repair backup integrity" onclick="return confirm('Check and repair backup integrity? Are you sure that you want to check and repair the backup integrity? This should only be done after reading the mentioned documentation.')"/>
|
<input type="submit" value="Check and repair backup integrity" data-confirm='Check and repair backup integrity? Are you sure that you want to check and repair the backup integrity? This should only be done after reading the mentioned documentation.'/>
|
||||||
</form>
|
</form>
|
||||||
</details>
|
</details>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -478,7 +478,7 @@
|
|||||||
<form method="POST" action="api/docker/backup" target="overlay-log">
|
<form method="POST" action="api/docker/backup" target="overlay-log">
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" value="Create backup" onclick="return confirm('Create backup? Are you sure that you want to create a backup? This will stop all running containers and create the backup.')" />
|
<input type="submit" value="Create backup" data-confirm='Create backup? Are you sure that you want to create a backup? This will stop all running containers and create the backup.' />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% if has_backup_run_once == true %}
|
{% if has_backup_run_once == true %}
|
||||||
@@ -490,7 +490,7 @@
|
|||||||
<form method="POST" action="api/docker/backup-check" target="overlay-log">
|
<form method="POST" action="api/docker/backup-check" target="overlay-log">
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" value="Check backup integrity" onclick="return confirm('Check backup integrity? Are you sure that you want to check the backup? This can take a long time depending on the size of your backup.')" />
|
<input type="submit" value="Check backup integrity" data-confirm='Check backup integrity? Are you sure that you want to check the backup? This can take a long time depending on the size of your backup.' />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h3>Backup restore</h3>
|
<h3>Backup restore</h3>
|
||||||
@@ -503,7 +503,7 @@
|
|||||||
<option value="{{ restore_time }}">{{ restore_time }} UTC</option>
|
<option value="{{ restore_time }}">{{ restore_time }} UTC</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
<input type="submit" value="Restore selected backup" onclick="return confirm('Restore the selected backup? Are you sure that you want to restore the selected backup? This will stop all running containers and restore the selected backup. It is recommended to create a backup first. You might also want to check the backup integrity.')" />
|
<input type="submit" value="Restore selected backup" data-confirm='Restore the selected backup? Are you sure that you want to restore the selected backup? This will stop all running containers and restore the selected backup. It is recommended to create a backup first. You might also want to check the backup integrity.' />
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h3>Update backup list</h3>
|
<h3>Update backup list</h3>
|
||||||
@@ -570,7 +570,7 @@
|
|||||||
<input type="hidden" name="delete_borg_backup_location_vars" value="yes"/>
|
<input type="hidden" name="delete_borg_backup_location_vars" value="yes"/>
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" value="Reset backup location" onclick="return confirm('Are you sure that you want to reset the backup location?')" />
|
<input type="submit" value="Reset backup location" data-confirm='Are you sure that you want to reset the backup location?' />
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if has_backup_run_once == true %}
|
{% if has_backup_run_once == true %}
|
||||||
@@ -587,8 +587,8 @@
|
|||||||
<summary>Click here to change your AIO passphrase</summary>
|
<summary>Click here to change your AIO passphrase</summary>
|
||||||
<p>You can change your AIO passphrase below:</p>
|
<p>You can change your AIO passphrase below:</p>
|
||||||
<form method="POST" action="api/configuration" class="xhr">
|
<form method="POST" action="api/configuration" class="xhr">
|
||||||
<input type="password" autocomplete="current-password" name="current-master-password" placeholder="Your current AIO passphrase" id="current-master-password" oninput="showPassword('current-master-password')">
|
<input type="password" autocomplete="current-password" name="current-master-password" placeholder="Your current AIO passphrase" id="current-master-password" data-input-show-password="showPassword('current-master-password')">
|
||||||
<input type="password" autocomplete="new-password" name="new-master-password" placeholder="Your new AIO passphrase" id="new-master-password" oninput="showPassword('new-master-password')">
|
<input type="password" autocomplete="new-password" name="new-master-password" placeholder="Your new AIO passphrase" id="new-master-password" data-input-show-password="showPassword('new-master-password')">
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" value="Submit passphrase change" />
|
<input type="submit" value="Submit passphrase change" />
|
||||||
@@ -616,7 +616,7 @@
|
|||||||
<input type="text" id="timezone" name="timezone" placeholder="Europe/Berlin" />
|
<input type="text" id="timezone" name="timezone" placeholder="Europe/Berlin" />
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" value="Submit timezone" onclick="return confirm('Are you sure that this is a valid timezone? Please double check by following the wikipedia article and checking the correct column. If the timezone is not valid, it will break the startup since the database will not be correctly initialized and you will end up in a startup loop.')" />
|
<input type="submit" value="Submit timezone" data-confirm='Are you sure that this is a valid timezone? Please double check by following the wikipedia article and checking the correct column. If the timezone is not valid, it will break the startup since the database will not be correctly initialized and you will end up in a startup loop.' />
|
||||||
</form>
|
</form>
|
||||||
<p>You need to make sure that the timezone that you enter is valid. An example is <strong>Europe/Berlin</strong>. You can get valid values by looking at the 'TZ identifier' column of this list: <a target="_blank" href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List"><strong>click here</strong></a>. The default is <strong>Etc/UTC</strong> if nothing is entered.</p>
|
<p>You need to make sure that the timezone that you enter is valid. An example is <strong>Europe/Berlin</strong>. You can get valid values by looking at the 'TZ identifier' column of this list: <a target="_blank" href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List"><strong>click here</strong></a>. The default is <strong>Etc/UTC</strong> if nothing is entered.</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -37,6 +37,6 @@
|
|||||||
</p>
|
</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
<input id="community-form-submit" type="submit" value="Save changes" onclick="return confirm('Are you sure that you read the documentation of all community containers that you enabled? If no, please do not continue as this might break your instance!')" />
|
<input id="community-form-submit" type="submit" value="Save changes" data-confirm='Are you sure that you read the documentation of all community containers that you enabled? If no, please do not continue as this might break your instance!' />
|
||||||
</form>
|
</form>
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -41,11 +41,9 @@
|
|||||||
<li>Best support for legacy files</li>
|
<li>Best support for legacy files</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% if isAnyRunning == false %}
|
{% if isAnyRunning == false %}
|
||||||
<a href="https://www.collaboraoffice.com/code/" target="_blank" class="office-learn-more" onclick="event.stopPropagation();">
|
<a href="https://www.collaboraoffice.com/code/" target="_blank" class="office-learn-more" data-stop-event-propagation="true">
|
||||||
Learn more
|
Learn more
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-left: 4px;">
|
<img src="img/collabora.svg" alt="Collabora Logo" />
|
||||||
<path d="M6 12L10 8L6 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</label>
|
</label>
|
||||||
@@ -76,11 +74,9 @@
|
|||||||
<li>Limited ODF compatibility</li>
|
<li>Limited ODF compatibility</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% if isAnyRunning == false %}
|
{% if isAnyRunning == false %}
|
||||||
<a href="https://www.onlyoffice.com/" target="_blank" class="office-learn-more" onclick="event.stopPropagation();">
|
<a href="https://www.onlyoffice.com/" target="_blank" class="office-learn-more" data-stop-event-propagation="true">
|
||||||
Learn more
|
Learn more
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-left: 4px;">
|
<img src="img/onlyoffice.svg" alt="Onlyoffice Logo" />
|
||||||
<path d="M6 12L10 8L6 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
||||||
</svg>
|
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</label>
|
</label>
|
||||||
@@ -99,9 +95,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
>
|
>
|
||||||
<label class="office-none-label" for="office-none">
|
<label class="office-none-label" for="office-none">
|
||||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" style="vertical-align: middle; margin-right: 6px;">
|
<img src="img/office-none.svg" alt="Disable Office icon" />
|
||||||
<path d="M2 2L14 14M2 14L14 2" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
||||||
</svg>
|
|
||||||
Disable office suite
|
Disable office suite
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
<html>
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>AIO</title>
|
<title>AIO</title>
|
||||||
<link rel="stylesheet" href="style.css?v9" media="all" />
|
<link rel="stylesheet" href="style.css?v9" media="all" />
|
||||||
<link rel="icon" href="img/favicon.png">
|
<link rel="icon" href="img/favicon.png">
|
||||||
<script type="text/javascript" src="forms.js?v2"></script>
|
<script type="text/javascript" src="forms.js?v2"></script>
|
||||||
<script type="text/javascript" src="toggle-dark-mode.js?v1"></script>
|
<script type="text/javascript" src="toggle-dark-mode.js?v1"></script>
|
||||||
|
<script type="text/javascript" src="click-handlers.js?v1"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -15,7 +17,7 @@
|
|||||||
<div class="loader"></div>
|
<div class="loader"></div>
|
||||||
<iframe name="overlay-log" id="overlay-log"></iframe>
|
<iframe name="overlay-log" id="overlay-log"></iframe>
|
||||||
</div>
|
</div>
|
||||||
<button id="theme-toggle" onclick="toggleTheme()">
|
<button id="theme-toggle">
|
||||||
<span id="theme-icon"></span>
|
<span id="theme-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -2,57 +2,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
<style>
|
<link rel="stylesheet" href="logs.css">
|
||||||
html, body {
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
pre {
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
margin: 0;
|
|
||||||
padding: 1rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
#floating-box {
|
|
||||||
position: fixed;
|
|
||||||
top: 1rem;
|
|
||||||
right: 1rem;
|
|
||||||
max-width: calc(100vw - 2rem);
|
|
||||||
z-index: 10;
|
|
||||||
display: flex;
|
|
||||||
justify-content: end;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
#autoloading-box {
|
|
||||||
display: grid;
|
|
||||||
gap: 0.5rem;
|
|
||||||
font-size: large;
|
|
||||||
border: solid thin gray;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
width: 10rem;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
margin: 0 0 0 1rem;
|
|
||||||
}
|
|
||||||
.loader {
|
|
||||||
opacity: 1;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
align-self: inherit;
|
|
||||||
}
|
|
||||||
@starting-style {
|
|
||||||
.loader {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.loader.hidden {
|
|
||||||
display: none;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 1s, display 1s allow-discrete;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script src="log-view.js?v1"></script>
|
<script src="log-view.js?v1"></script>
|
||||||
</head>
|
</head>
|
||||||
<body data-container-id="{{ id }}">
|
<body data-container-id="{{ id }}">
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
{% if is_login_allowed == true %}
|
{% if is_login_allowed == true %}
|
||||||
<p>Log in using your Nextcloud AIO passphrase:</p>
|
<p>Log in using your Nextcloud AIO passphrase:</p>
|
||||||
<form method="POST" action="api/auth/login" class="xhr">
|
<form method="POST" action="api/auth/login" class="xhr">
|
||||||
<input type="password" autocomplete="current-password" name="password" placeholder="Password" id="master-password" oninput="showPassword('master-password')">
|
<input type="password" autocomplete="current-password" name="password" placeholder="Password" id="master-password" data-input-show-password="showPassword('master-password')">
|
||||||
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
<input type="hidden" name="{{csrf.keys.name}}" value="{{csrf.name}}">
|
||||||
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
<input type="hidden" name="{{csrf.keys.value}}" value="{{csrf.value}}">
|
||||||
<input type="submit" class="button" value="Log in" />
|
<input type="submit" class="button" value="Log in" />
|
||||||
|
|||||||
Reference in New Issue
Block a user