diff --git a/backend/tasks/workers/purge-uploads.ts b/backend/tasks/workers/purge-uploads.ts deleted file mode 100644 index 173d6d1a6..000000000 --- a/backend/tasks/workers/purge-uploads.ts +++ /dev/null @@ -1,28 +0,0 @@ -import path from 'node:path' -import fse from 'fs-extra' - -export async function task(): Promise { - WIKI.logger.info('Purging orphaned upload files...') - - try { - const uplTempPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'uploads') - await fse.ensureDir(uplTempPath) - const ls = await fse.readdir(uplTempPath) - const fifteenAgo = Temporal.Now.instant().subtract({ minutes: 15 }) - - for (const f of ls) { - const stat = await fse.stat(path.join(uplTempPath, f)) - // -> Compared as epoch millis. Temporal deliberately has no `valueOf`, so relational - // operators on its types throw — comparisons must be explicit. - if (stat.isFile() && stat.ctime.getTime() < fifteenAgo.epochMilliseconds) { - await fse.unlink(path.join(uplTempPath, f)) - } - } - - WIKI.logger.info('Purging orphaned upload files: [ COMPLETED ]') - } catch (err: any) { - WIKI.logger.error('Purging orphaned upload files: [ FAILED ]') - WIKI.logger.error(err.message) - throw err - } -} diff --git a/frontend/src/components/shared/WInput.vue b/frontend/src/components/shared/WInput.vue index 581a45944..8a8f45f28 100644 --- a/frontend/src/components/shared/WInput.vue +++ b/frontend/src/components/shared/WInput.vue @@ -353,15 +353,21 @@ const hasError = computed(() => Boolean(errorMessage.value)) /* The opt-out attributes, as one object bound in a single `v-bind`. - `autocomplete="off"` is the standards half and the only one any browser reads; the four `data-` + `autocomplete` is the standards half and the only one any browser reads; the four `data-` attributes are what the password managers that ignore it read instead -- 1Password, LastPass, Bitwarden and Dashlane respectively, each having settled on its own spelling. They are inert everywhere else, so they cost a field that nobody's extension looks at nothing. + + `new-password` rather than `off` on a password field, and that difference is the whole point on + the fields that matter most: Chrome deliberately disregards `off` there -- too many banks had used + it to stop people pasting -- and offers the saved credential anyway. `new-password` is the one + value it does honour, because a field being filled with an EXISTING password is exactly what it + says this is not. Every other type reads `off`, which they all honour. */ const autofillAttrs = computed(() => props.noAutofill ? { - autocomplete: 'off', + autocomplete: props.type === 'password' ? 'new-password' : 'off', 'data-1p-ignore': 'true', 'data-lpignore': 'true', 'data-bwignore': 'true', diff --git a/frontend/src/components/shared/WPagination.vue b/frontend/src/components/shared/WPagination.vue index 3fee5322d..63018f039 100644 --- a/frontend/src/components/shared/WPagination.vue +++ b/frontend/src/components/shared/WPagination.vue @@ -3,10 +3,16 @@ v-if="max > 1" class="w-pagination flex flex-nowrap items-center gap-1" :aria-label="ariaLabel"> +