From bfee082c0162ff12c359ff28f8fdee84b217543f Mon Sep 17 00:00:00 2001 From: zokki Date: Wed, 1 Oct 2025 12:07:30 +0200 Subject: [PATCH] fix(ui): make "Token name"-input a real required-field (#8877) ## Checklist The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org). ### Tests - I added test coverage for Go changes... - [ ] in their respective `*_test.go` for unit tests. - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server. - I added test coverage for JavaScript changes... - [ ] in `web_src/js/*.test.js` if it can be unit tested. - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)). ### Documentation - [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change. - [ ] I did not document these changes and I do not expect someone else to do it. ### Release notes - [ ] I do not want this change to show in the release notes. - [x] I want the title to show in the release notes with a link to this pull request. - [ ] I want the content of the `release-notes/.md` to be be used for the release notes instead of the title. Before: ![image](/attachments/f957bab5-7a8f-4642-8528-6b82f38dd329) After: ![image](/attachments/80620a95-3828-479a-8ae3-61e34e0d8c40) Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8877 Reviewed-by: Gusted Reviewed-by: Otto Reviewed-by: Beowulf Co-authored-by: zokki Co-committed-by: zokki --- templates/user/settings/applications.tmpl | 2 +- tests/e2e/user-settings.test.e2e.ts | 21 +++++++++++++++++++ .../components/ScopedAccessTokenSelector.vue | 9 +++++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl index a5912c9e0f..602c538f97 100644 --- a/templates/user/settings/applications.tmpl +++ b/templates/user/settings/applications.tmpl @@ -59,7 +59,7 @@
{{.CsrfTokenHtml}} -
+
diff --git a/tests/e2e/user-settings.test.e2e.ts b/tests/e2e/user-settings.test.e2e.ts index 21f9da9469..5abe6878e3 100644 --- a/tests/e2e/user-settings.test.e2e.ts +++ b/tests/e2e/user-settings.test.e2e.ts @@ -123,3 +123,24 @@ test('User: Canceling adding GPG key clears input', async ({browser}, workerInfo await expect(gpgKeyContent).toHaveValue(''); }); + +test('User: Add access token', async ({browser}, workerInfo) => { + const page = await login({browser}, workerInfo); + await page.goto('/user/settings/applications'); + + await page.locator('#scoped-access-submit').click(); + await page.locator('#name:invalid').isVisible(); + + await page.locator('details.optional.field').click(); + await page.selectOption('#access-token-scope-activitypub', 'read:activitypub'); + await page.locator('#scoped-access-submit').click(); + + await page.locator('#name:invalid').isVisible(); + await expect(page.locator('#access-token-scope-activitypub')).toHaveValue('read:activitypub'); + + const tokenName = globalThis.crypto.randomUUID(); + await page.locator('#name').fill(tokenName); + await page.locator('#scoped-access-submit').click(); + + await page.getByText(tokenName).isVisible(); +}); diff --git a/web_src/js/components/ScopedAccessTokenSelector.vue b/web_src/js/components/ScopedAccessTokenSelector.vue index 91356d8bf5..fe79032aa9 100644 --- a/web_src/js/components/ScopedAccessTokenSelector.vue +++ b/web_src/js/components/ScopedAccessTokenSelector.vue @@ -51,6 +51,13 @@ export default { methods: { onClickSubmit(e) { + const form = document.getElementById('scoped-access-form'); + if (!form.checkValidity()) { + // some required inputs are not filled + return; + } + + // prevent after validity-check to get native-required-popup e.preventDefault(); const warningEl = document.getElementById('scoped-access-warning'); @@ -60,7 +67,7 @@ export default { // Hide the error if it was visible from previous attempt. hideElem(warningEl); // Submit the form. - document.getElementById('scoped-access-form').submit(); + form.submit(); // Don't show the warning. return; }