From a3871e75d3d098c7204cd29f35d21845c206465c Mon Sep 17 00:00:00 2001
From: Hu Gang <18768366022@163.com>
Date: Thu, 14 Nov 2024 19:46:11 +0800
Subject: [PATCH] Add field validation when submitting the form

---
 oauth2_web/src/views/ApplicationConf.vue | 51 ++++++++++++++++++++++--
 oauth2_web/src/views/NewApplication.vue  | 39 ++++++++++++------
 2 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/oauth2_web/src/views/ApplicationConf.vue b/oauth2_web/src/views/ApplicationConf.vue
index cf87919..c7377f2 100644
--- a/oauth2_web/src/views/ApplicationConf.vue
+++ b/oauth2_web/src/views/ApplicationConf.vue
@@ -41,11 +41,55 @@ const originForm = reactive<Form>({
 })
 
 const rules = reactive<FormRules<keyof Form>>({
-  clientName: [{ required: true, message: '请输入应用名称', trigger: 'blur' }],
-  clientUri: [{ required: true, message: '请输入应用地址', trigger: 'blur' }],
-  redirectUris: [{ required: true, message: '请输入应用回调地址', trigger: 'blur' }],
+  clientName: [{ validator: validateClientName, trigger: 'blur' }],
+  clientUri: [{ validator: validateClientUri, trigger: 'blur' }],
+  redirectUris: [{ validator: validateRedirectUris, trigger: 'blur' }],
+  registerCallbackUris: [{ validator: validateCallbackUris, trigger: 'blur' }],
+  logoutCallbackUris: [{ required: false }, { validator: validateCallbackUris, trigger: 'blur' }],
 })
 
+const URL_REGEX =
+  /^(((ht|f)tps?):\/\/)([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+([a-z]{2,6})?\/?/
+
+function validateClientName(_rule: any, value: any, callback: any): void {
+  const regex = /^.{5,20}$/i
+  if (!regex.test(value)) {
+    callback(new Error('应用名称长度必须在5-20之间!'))
+  }
+  callback()
+}
+
+function validateClientUri(_rule: any, value: any, callback: any): void {
+  if (!URL_REGEX.test(value)) {
+    callback(new Error('请输入正确的url!'))
+  }
+  callback()
+}
+
+function validateCallbackUris(_rule: any, value: any, callback: any): void {
+  if (value === '') {
+    callback()
+    return
+  }
+  const urlList = value.split(',')
+  const isRegex = urlList.some((url) => !URL_REGEX.test(url))
+  if (isRegex) {
+    callback(new Error('请输入正确的url!'))
+    return
+  }
+  callback()
+}
+
+function validateRedirectUris(_rule: any, value: any, callback: any): void {
+  const urlList = value.split(',')
+  const isRegex = urlList.some((url) => !URL_REGEX.test(url))
+  if (isRegex) {
+    callback(new Error('请输入正确的url!'))
+    return
+  }
+  callback()
+}
+
 const clientSecret = computed(() => {
   if (!props.application) return ''
   return isHideClientSecret.value
@@ -258,3 +302,4 @@ watch(
   }
 }
 </style>
+
diff --git a/oauth2_web/src/views/NewApplication.vue b/oauth2_web/src/views/NewApplication.vue
index 9d40464..a89a6db 100644
--- a/oauth2_web/src/views/NewApplication.vue
+++ b/oauth2_web/src/views/NewApplication.vue
@@ -49,14 +49,32 @@ const form = reactive<Form>({
 })
 
 const rules = reactive<FormRules<keyof Form>>({
-  clientName: [{ required: true, message: '请输入应用名称', trigger: 'blur' }],
-  clientUri: [{ required: true, message: '请输入应用地址', trigger: 'blur' }],
-  redirectUris: [{ required: true, message: '请输入应用回调地址', trigger: 'blur' }],
+  clientName: [{ validator: validateClientName, trigger: 'blur' }],
+  clientUri: [{ validator: validateRedirectUris, trigger: 'blur' }],
+  redirectUris: [{ validator: validateRedirectUris, trigger: 'blur' }],
 })
 
-const isSubmiting = ref(false)
+function validateClientName(_rule: any, value: any, callback: any): void {
+  const regex = /^.{5,20}$/i
+  if (!regex.test(value)) {
+    callback(new Error('应用名称长度必须在5-20之间!'))
+  }
+  callback()
+}
+
+function validateRedirectUris(_rule: any, value: any, callback: any): void {
+  const regex =
+    /^(((ht|f)tps?):\/\/)([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+([a-z]{2,6})?\/?/
+  console.log(regex.test(value))
+  if (!regex.test(value)) {
+    callback(new Error('请输入正确的url!'))
+  }
+  callback()
+}
+
+const isSubmitting = ref(false)
 async function generateApplication() {
-  isSubmiting.value = true
+  isSubmitting.value = true
   const {
     clientName,
     clientUri,
@@ -86,7 +104,7 @@ async function generateApplication() {
     emits('success')
     emits('update:visible', false)
   }
-  isSubmiting.value = false
+  isSubmitting.value = false
 }
 
 async function handleSubmit() {
@@ -119,11 +137,7 @@ function handleClose() {
         <el-input v-model:model-value="form.clientUri" placeholder="应用主页" />
       </el-form-item>
       <el-form-item label="应用回调地址" prop="redirectUris">
-        <el-input
-          v-model:model-value="form.redirectUris"
-          type="textarea"
-          placeholder="应用回调地址"
-        />
+        <el-input v-model:model-value="form.redirectUris" placeholder="应用回调地址" />
       </el-form-item>
       <el-form-item label="用户知情同意页面" prop="shipAuthorization">
         <el-switch v-model:model-value="form.skipAuthorization" />
@@ -132,9 +146,10 @@ function handleClose() {
     <template #footer>
       <div class="dialog-footer">
         <el-button @click="emits('update:visible', false)">取消</el-button>
-        <el-button :loading="isSubmiting" @click="handleSubmit" type="primary"> 创建 </el-button>
+        <el-button :loading="isSubmitting" @click="handleSubmit" type="primary"> 创建 </el-button>
       </div>
     </template>
   </el-dialog>
 </template>
 <style scoped></style>
+
-- 
2.33.0

