From fb2dffa5769f20c3f72d87af17d414867b406551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9B=BE=E6=B3=BD=E6=A2=93?= <3038736583@qq.com> Date: Mon, 5 Oct 2026 01:16:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=BD=AF=E4=BB=B6=E7=94=B3?= =?UTF-8?q?=E8=AF=B7=E8=A1=A8=E6=BA=90=E7=A0=81=E4=BB=93=E5=BA=93=E5=9C=B0?= =?UTF-8?q?=E5=9D=80=E7=9A=84=E4=B8=BB=E6=9C=BA=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 曾泽梓 <3038736583@qq.com> --- apps/web/src/modules/oh/utils/form.test.ts | 42 ++++++++++++++++++++++ apps/web/src/modules/oh/utils/form.ts | 11 ++++-- 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 apps/web/src/modules/oh/utils/form.test.ts diff --git a/apps/web/src/modules/oh/utils/form.test.ts b/apps/web/src/modules/oh/utils/form.test.ts new file mode 100644 index 0000000000..1bcdf91652 --- /dev/null +++ b/apps/web/src/modules/oh/utils/form.test.ts @@ -0,0 +1,42 @@ +import { validateCoderUrl, validateCommitSHA } from './form'; + +describe('source repository URL validation', () => { + it.each([ + 'https://github.com/owner/repo', + 'https://gitee.com/owner/repo.git', + 'https://gitcode.com/owner/repo/', + 'http://github.com/owner/repo', + 'https://GITHUB.COM/owner/repo', + ])('accepts a repository on a supported host: %s', async (value) => { + await expect(validateCoderUrl(null, value)).resolves.toBeUndefined(); + }); + + it.each([ + 'https://github.com.example.org/owner/repo', + 'https://example.org/github.com/owner/repo', + 'https://example.org/?repo=https://gitee.com/owner/repo', + 'https://github.com@example.org/owner/repo', + 'https://notgithub.com/owner/repo', + 'ftp://github.com/owner/repo', + 'github.com/owner/repo', + 'https://github.com', + 'https://github.com/owner', + '', + undefined, + ])( + 'rejects a value that is not a supported repository URL: %s', + async (value) => { + await expect(validateCoderUrl(null, value)).rejects.toThrow( + '请输入正确的Github、Gitee、Gitcode仓库' + ); + } + ); + + it('retains the independent optional commit SHA validation', async () => { + await expect( + validateCommitSHA(null, 'a'.repeat(40)) + ).resolves.toBeUndefined(); + await expect(validateCommitSHA(null, '')).resolves.toBeUndefined(); + await expect(validateCommitSHA(null, 'invalid')).rejects.toThrow(); + }); +}); diff --git a/apps/web/src/modules/oh/utils/form.ts b/apps/web/src/modules/oh/utils/form.ts index b1631b6fd9..e31d68f5be 100644 --- a/apps/web/src/modules/oh/utils/form.ts +++ b/apps/web/src/modules/oh/utils/form.ts @@ -7,10 +7,17 @@ export const validateCommitSHA = (_, value) => { }; export const validateCoderUrl = (_, value) => { const validHosts = ['github.com', 'gitee.com', 'gitcode.com']; - for (let host of validHosts) { - if (value?.includes(host)) { + try { + const url = new URL(value); + if ( + ['http:', 'https:'].includes(url.protocol) && + validHosts.includes(url.hostname) && + url.pathname.split('/').filter(Boolean).length >= 2 + ) { return Promise.resolve(); } + } catch { + // Malformed or relative URLs cannot identify a supported source repository. } return Promise.reject(new Error('请输入正确的Github、Gitee、Gitcode仓库')); };