Compare commits

...

6 Commits

Author SHA1 Message Date
Dillard Blom 209520165e Merge pull request #5: Release 0.9.1-beta.2
CI / unit (8.2) (push) Has been cancelled
CI / unit (8.3) (push) Has been cancelled
CI / unit (8.4) (push) Has been cancelled
CI / psalm (push) Has been cancelled
CI / integration (mariadb, 32) (push) Has been cancelled
CI / integration (mariadb, 33) (push) Has been cancelled
CI / integration (mariadb, 34) (push) Has been cancelled
CI / integration (mariadb, 35) (push) Has been cancelled
CI / integration (pgsql, 32) (push) Has been cancelled
CI / integration (pgsql, 33) (push) Has been cancelled
CI / integration (pgsql, 34) (push) Has been cancelled
CI / integration (pgsql, 35) (push) Has been cancelled
CI / integration (sqlite, 32) (push) Has been cancelled
CI / integration (sqlite, 33) (push) Has been cancelled
CI / integration (sqlite, 34) (push) Has been cancelled
CI / integration (sqlite, 35) (push) Has been cancelled
CI / integration-targets (push) Has been cancelled
CI / integration-user (32) (push) Has been cancelled
CI / integration-user (33) (push) Has been cancelled
CI / integration-user (34) (push) Has been cancelled
CI / integration-user (35) (push) Has been cancelled
CI / integration-full-restore (push) Has been cancelled
2026-10-07 18:09:23 +02:00
dillard 9554e774e5 CHANGELOG: correct why info.xml carries no -beta suffix 2026-10-07 18:01:20 +02:00
dillard 8b2dca28e3 Release 0.9.1-beta.2 2026-10-07 17:47:40 +02:00
dillard 5742f77253 App store listing: screenshots, links and UI fixes
Add three screenshots (backups, restore, settings) taken on a demo
instance, plus website, repository and the HOWTO as admin documentation
in info.xml.

Fixes found while taking them:
- the "new folder" restore option lost "<date>" (l10n sanitizes it as
  a tag); show the folder name pattern via a placeholder instead
- the restore-point dropdown cut off the time
- passphrase actions stacked vertically in the slot table
- HOWTO: SFTP example used "sftp::password", the auth mechanism is
  "password::password"
2026-10-07 17:43:41 +02:00
Dillard Blom 550249570b Merge pull request #4: README key rotation note
CI / unit (8.2) (push) Has been cancelled
CI / unit (8.3) (push) Has been cancelled
CI / unit (8.4) (push) Has been cancelled
CI / psalm (push) Has been cancelled
CI / integration (mariadb, 32) (push) Has been cancelled
CI / integration (mariadb, 33) (push) Has been cancelled
CI / integration (mariadb, 34) (push) Has been cancelled
CI / integration (mariadb, 35) (push) Has been cancelled
CI / integration (pgsql, 32) (push) Has been cancelled
CI / integration (pgsql, 33) (push) Has been cancelled
CI / integration (pgsql, 34) (push) Has been cancelled
CI / integration (pgsql, 35) (push) Has been cancelled
CI / integration (sqlite, 32) (push) Has been cancelled
CI / integration (sqlite, 33) (push) Has been cancelled
CI / integration (sqlite, 34) (push) Has been cancelled
CI / integration (sqlite, 35) (push) Has been cancelled
CI / integration-targets (push) Has been cancelled
CI / integration-user (32) (push) Has been cancelled
CI / integration-user (33) (push) Has been cancelled
CI / integration-user (34) (push) Has been cancelled
CI / integration-user (35) (push) Has been cancelled
CI / integration-full-restore (push) Has been cancelled
README: key rotation for revoking old kits is on the backlog
2026-10-07 02:26:19 +02:00
dillard 0eb23f56e7 README: note that key rotation for revoking old kits is on the backlog 2026-10-07 02:18:45 +02:00
9 changed files with 37 additions and 10 deletions
+19 -3
View File
@@ -2,9 +2,24 @@
All notable changes to NG Backup are documented here. The format follows All notable changes to NG Backup are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows the stages in [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows the stages in
`PLAN.md` section 9. The `<version>` in `appinfo/info.xml` is plain SemVer-numeric (Nextcloud's `PLAN.md` section 9. The `<version>` in `appinfo/info.xml` is plain SemVer-numeric on purpose:
own `info.xsd` doesn't allow a `-alpha`/`-beta`/`-rc` suffix there); the stability stage is instead the app store accepts a `-beta` suffix, but Nextcloud servers then only offer the release on the
carried by the git tag, the release, and this file. beta/daily update channel, which would hide the app from most admins. The stability stage is
instead carried by the app description, the git tag, the release, and this file.
## [0.9.1-beta.2] - 2026-10-07
Second beta, the first release in the Nextcloud app store (signed).
### Added
- App store listing: screenshots, website, repository and documentation link in `appinfo/info.xml`.
### Fixed
- Restore: the "new folder" option showed `"Restored "` without the date pattern.
- Restore: the restore-point dropdown cut off the time.
- Settings: the passphrase actions are on one line instead of stacked.
- `docs/HOWTO.md`: the SFTP example used a non-existent auth mechanism (`sftp::password`
instead of `password::password`).
## [0.9.0-beta.1] - 2026-10-07 ## [0.9.0-beta.1] - 2026-10-07
@@ -88,5 +103,6 @@ and not implemented yet.
- See the "Storage backend experiences" section of the README for provider-specific quirks found - See the "Storage backend experiences" section of the README for provider-specific quirks found
so far (e.g. Hetzner Storage Box sub-accounts). so far (e.g. Hetzner Storage Box sub-accounts).
[0.9.1-beta.2]: https://github.com/dillardblom/ng_backup/releases/tag/v0.9.1-beta.2
[0.9.0-beta.1]: https://github.com/dillardblom/ng_backup/releases/tag/v0.9.0-beta.1 [0.9.0-beta.1]: https://github.com/dillardblom/ng_backup/releases/tag/v0.9.0-beta.1
[0.1.0-alpha.1]: https://github.com/dillardblom/ng_backup/releases/tag/v0.1.0-alpha.1 [0.1.0-alpha.1]: https://github.com/dillardblom/ng_backup/releases/tag/v0.1.0-alpha.1
+3 -2
View File
@@ -7,7 +7,7 @@ installations and hosted Nextcloud. (Choosing SMB as a storage backend is the on
see "Storage backend experiences" below — that requirement comes from files_external, not from see "Storage backend experiences" below — that requirement comes from files_external, not from
ng_backup, and applies to any Nextcloud app that writes to an SMB share.) ng_backup, and applies to any Nextcloud app that writes to an SMB share.)
**Status: beta (0.9.0).** Tested thoroughly, usable alongside your current backup, but not yet a **Status: beta (0.9.1).** Tested thoroughly, usable alongside your current backup, but not yet a
drop-in replacement for it. See "Known limitations" below, `PLAN.md` for the design and drop-in replacement for it. See "Known limitations" below, `PLAN.md` for the design and
`docs/HOWTO.md` for a step-by-step guide from setup to a tested restore. `docs/HOWTO.md` for a step-by-step guide from setup to a tested restore.
@@ -63,7 +63,8 @@ All backups of an installation are encrypted with one master key.
a single slot is possible, but then that one passphrase is a single point of failure. a single slot is possible, but then that one passphrase is a single point of failure.
- When a holder leaves, give their slot a new passphrase (`occ backup:key:slot:replace`), download - When a holder leaves, give their slot a new passphrase (`occ backup:key:slot:replace`), download
the new kit and confirm it. Note: an old kit together with the old passphrase still opens the the new kit and confirm it. Note: an old kit together with the old passphrase still opens the
same master key; to revoke it completely, start new locations with a new key. same master key; to revoke it completely, start new locations with a new key. This is noted on
the backlog and will be addressed in a future version (key rotation).
- Downloading the kit, and every change to the slots, requires the administrator's password, is - Downloading the kit, and every change to the slots, requires the administrator's password, is
written to the audit log and is announced to all administrators. written to the audit log and is announced to all administrators.
+9 -1
View File
@@ -9,12 +9,20 @@ directory to S3, SFTP, WebDAV, FTP, SMB or a local path, with restore of files a
single users (via user_migration) and of the whole server onto a fresh installation. Tested single users (via user_migration) and of the whole server onto a fresh installation. Tested
thoroughly and usable alongside your current backup, but not yet a drop-in replacement for it. thoroughly and usable alongside your current backup, but not yet a drop-in replacement for it.
See the README for known limitations and the recovery kit before relying on it.]]></description> See the README for known limitations and the recovery kit before relying on it.]]></description>
<version>0.9.0</version> <version>0.9.1</version>
<licence>agpl</licence> <licence>agpl</licence>
<author>Dillard Blom</author> <author>Dillard Blom</author>
<namespace>NgBackup</namespace> <namespace>NgBackup</namespace>
<documentation>
<admin>https://github.com/dillardblom/ng_backup/blob/main/docs/HOWTO.md</admin>
</documentation>
<category>tools</category> <category>tools</category>
<website>https://apps.nextcloud.com/apps/ng_backup</website>
<bugs>https://github.com/dillardblom/ng_backup/issues</bugs> <bugs>https://github.com/dillardblom/ng_backup/issues</bugs>
<repository type="git">https://github.com/dillardblom/ng_backup</repository>
<screenshot>https://raw.githubusercontent.com/dillardblom/ng_backup/main/screenshots/1-backups.png</screenshot>
<screenshot>https://raw.githubusercontent.com/dillardblom/ng_backup/main/screenshots/2-restore.png</screenshot>
<screenshot>https://raw.githubusercontent.com/dillardblom/ng_backup/main/screenshots/3-settings.png</screenshot>
<dependencies> <dependencies>
<php min-version="8.1"/> <php min-version="8.1"/>
<lib>sodium</lib> <lib>sodium</lib>
+1 -1
View File
@@ -32,7 +32,7 @@ Examples:
``` ```
occ backup:target:add offsite amazons3 -a amazons3::accesskey -o bucket=<bucket> -o key=<key> -o secret=<secret> occ backup:target:add offsite amazons3 -a amazons3::accesskey -o bucket=<bucket> -o key=<key> -o secret=<secret>
occ backup:target:add nas sftp -a sftp::password -o host=<host> -o user=<user> -o password=<pw> -o root=home occ backup:target:add nas sftp -a password::password -o host=<host> -o user=<user> -o password=<pw> -o root=home
occ backup:target:add local local -a null::null -o datadir=/mnt/backup occ backup:target:add local local -a null::null -o datadir=/mnt/backup
``` ```
Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

+2 -1
View File
@@ -36,7 +36,7 @@
<td>{{ t('ng_backup', 'Slot {n}', { n: slot.slot }) }}</td> <td>{{ t('ng_backup', 'Slot {n}', { n: slot.slot }) }}</td>
<td><strong>{{ slot.label }}</strong></td> <td><strong>{{ slot.label }}</strong></td>
<td class="ngb-muted">{{ slot.created ? new Date(slot.created * 1000).toLocaleDateString() : '' }}</td> <td class="ngb-muted">{{ slot.created ? new Date(slot.created * 1000).toLocaleDateString() : '' }}</td>
<td> <td class="ngb-actions">
<NcButton variant="tertiary" @click="openSlotForm(slot)">{{ t('ng_backup', 'New passphrase') }}</NcButton> <NcButton variant="tertiary" @click="openSlotForm(slot)">{{ t('ng_backup', 'New passphrase') }}</NcButton>
<NcButton v-if="status.key.slots.length > 1" variant="tertiary" @click="removeSlot(slot)">{{ t('ng_backup', 'Remove') }}</NcButton> <NcButton v-if="status.key.slots.length > 1" variant="tertiary" @click="removeSlot(slot)">{{ t('ng_backup', 'Remove') }}</NcButton>
</td> </td>
@@ -162,5 +162,6 @@ const confirm = () => guarded(async () => {
.ngb-form, .ngb-confirm { display: flex; flex-direction: column; gap: 12px; max-width: 600px; margin: 8px 0; } .ngb-form, .ngb-confirm { display: flex; flex-direction: column; gap: 12px; max-width: 600px; margin: 8px 0; }
.ngb-row { display: flex; gap: 8px; } .ngb-row { display: flex; gap: 8px; }
.ngb-table td { padding: 2px 12px 2px 0; } .ngb-table td { padding: 2px 12px 2px 0; }
.ngb-actions { display: flex; gap: 4px; }
h3 { margin-top: 16px; font-weight: bold; } h3 { margin-top: 16px; font-weight: bold; }
</style> </style>
+3 -2
View File
@@ -7,7 +7,7 @@
:description="t('ng_backup', 'Pick a restore point and a user folder or file. Restores run in the background and go through Nextcloud, so overwritten files keep their old content as a version and removed files go to the trash.')"> :description="t('ng_backup', 'Pick a restore point and a user folder or file. Restores run in the background and go through Nextcloud, so overwritten files keep their old content as a version and removed files go to the trash.')">
<div class="ngb-row"> <div class="ngb-row">
<NcSelect v-model="target" :options="status.targets" label="name" :input-label="t('ng_backup', 'Location')" :clearable="false" /> <NcSelect v-model="target" :options="status.targets" label="name" :input-label="t('ng_backup', 'Location')" :clearable="false" />
<NcSelect v-if="target" v-model="snapshot" :options="snapshots" label="displayLabel" :input-label="t('ng_backup', 'Restore point')" :clearable="false" /> <NcSelect v-if="target" v-model="snapshot" :options="snapshots" label="displayLabel" class="ngb-snapshot" :input-label="t('ng_backup', 'Restore point')" :clearable="false" />
</div> </div>
<template v-if="snapshot"> <template v-if="snapshot">
@@ -69,7 +69,7 @@ const busy = ref(false)
const error = ref('') const error = ref('')
const message = ref('') const message = ref('')
const modes = [ const modes = [
{ id: 'new-folder', label: t('ng_backup', 'Into a new folder "Restored <date>" (nothing existing is changed)') }, { id: 'new-folder', label: t('ng_backup', 'Into a new folder "Restored {date}" (nothing existing is changed)', { date: 'YYYY-MM-DD HH.MM' }) },
{ id: 'merge', label: t('ng_backup', 'Into the original place, overwrite (old content kept as a version)') }, { id: 'merge', label: t('ng_backup', 'Into the original place, overwrite (old content kept as a version)') },
{ id: 'replace', label: t('ng_backup', 'Into the original place, overwrite and move files that are not in the backup to the trash') }, { id: 'replace', label: t('ng_backup', 'Into the original place, overwrite and move files that are not in the backup to the trash') },
] ]
@@ -124,6 +124,7 @@ async function restore() {
<style scoped> <style scoped>
.ngb-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; } .ngb-row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.ngb-row :deep(.ngb-snapshot) { min-width: min(360px, 100%); }
.ngb-crumbs { display: flex; align-items: center; flex-wrap: wrap; } .ngb-crumbs { display: flex; align-items: center; flex-wrap: wrap; }
.ngb-entries li { display: flex; align-items: center; gap: 12px; min-height: 36px; } .ngb-entries li { display: flex; align-items: center; gap: 12px; min-height: 36px; }
.ngb-entries li.selected { background: var(--color-primary-element-light); border-radius: var(--border-radius); } .ngb-entries li.selected { background: var(--color-primary-element-light); border-radius: var(--border-radius); }