⏪️ 重现旧 UI #4
							
								
								
									
										16
									
								
								.idea/workspace.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										16
									
								
								.idea/workspace.xml
									
									
									
										generated
									
									
									
								
							| @@ -4,12 +4,14 @@ | ||||
|     <option name="autoReloadType" value="ALL" /> | ||||
|   </component> | ||||
|   <component name="ChangeListManager"> | ||||
|     <list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":recycle: OAuth authenticate"> | ||||
|       <change afterPath="$PROJECT_DIR$/web/src/components/GoUseSolian.vue" afterDir="false" /> | ||||
|     <list default="true" id="3fefb2c4-b6f9-466b-a523-53352e8d6f95" name="更改" comment=":sparkles: Recommend app component"> | ||||
|       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/web/src/components/navigation/AppBar.vue" beforeDir="false" afterPath="$PROJECT_DIR$/web/src/components/navigation/AppBar.vue" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/web/src/layouts/user-center.vue" beforeDir="false" afterPath="$PROJECT_DIR$/web/src/layouts/user-center.vue" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/web/src/views/personalize.vue" beforeDir="false" afterPath="$PROJECT_DIR$/web/src/views/personalize.vue" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/pkg/internal/services/ticket.go" beforeDir="false" afterPath="$PROJECT_DIR$/pkg/internal/services/ticket.go" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/settings.toml" beforeDir="false" afterPath="$PROJECT_DIR$/settings.toml" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/web/src/components/UserMenu.vue" beforeDir="false" afterPath="$PROJECT_DIR$/web/src/components/UserMenu.vue" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/web/src/components/auth/FactorPicker.vue" beforeDir="false" afterPath="$PROJECT_DIR$/web/src/components/auth/FactorPicker.vue" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/web/src/router/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/web/src/router/index.ts" afterDir="false" /> | ||||
|       <change beforePath="$PROJECT_DIR$/web/src/stores/userinfo.ts" beforeDir="false" afterPath="$PROJECT_DIR$/web/src/stores/userinfo.ts" afterDir="false" /> | ||||
|     </list> | ||||
|     <option name="SHOW_DIALOG" value="false" /> | ||||
|     <option name="HIGHLIGHT_CONFLICTS" value="true" /> | ||||
| @@ -147,7 +149,6 @@ | ||||
|     </option> | ||||
|   </component> | ||||
|   <component name="VcsManagerConfiguration"> | ||||
|     <MESSAGE value=":bug: Bug fixes in update avatar" /> | ||||
|     <MESSAGE value=":sparkles: Firebase is back" /> | ||||
|     <MESSAGE value=":sparkles: Apple push notification services" /> | ||||
|     <MESSAGE value=":bug: Bug fixes" /> | ||||
| @@ -172,7 +173,8 @@ | ||||
|     <MESSAGE value=":recycle: Update the sign in web page to the latest API" /> | ||||
|     <MESSAGE value=":wastebasket: Remove the personal page" /> | ||||
|     <MESSAGE value=":recycle: OAuth authenticate" /> | ||||
|     <option name="LAST_COMMIT_MESSAGE" value=":recycle: OAuth authenticate" /> | ||||
|     <MESSAGE value=":sparkles: Recommend app component" /> | ||||
|     <option name="LAST_COMMIT_MESSAGE" value=":sparkles: Recommend app component" /> | ||||
|   </component> | ||||
|   <component name="VgoProject"> | ||||
|     <settings-migrated>true</settings-migrated> | ||||
|   | ||||
| @@ -12,22 +12,13 @@ import ( | ||||
| ) | ||||
|  | ||||
| func DetectRisk(user models.Account, ip, ua string) bool { | ||||
| 	var availableFactor int64 | ||||
| 	if err := database.C. | ||||
| 		Where(models.AuthFactor{AccountID: user.ID}). | ||||
| 		Where("type != ?", models.PasswordAuthFactor). | ||||
| 		Model(models.AuthFactor{}). | ||||
| 		Where(&availableFactor); err != nil || availableFactor <= 0 { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	var secureFactor int64 | ||||
| 	var clue int64 | ||||
| 	if err := database.C. | ||||
| 		Where(models.AuthTicket{AccountID: user.ID, IpAddress: ip}). | ||||
| 		Where("available_at IS NOT NULL"). | ||||
| 		Model(models.AuthTicket{}). | ||||
| 		Count(&secureFactor).Error; err == nil { | ||||
| 		if secureFactor >= 1 { | ||||
| 		Count(&clue).Error; err == nil { | ||||
| 		if clue >= 1 { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| id = "passport01" | ||||
| name = "Solarpass" | ||||
|  | ||||
| frontend_app = "web/dist" | ||||
|  | ||||
|   | ||||
| @@ -15,14 +15,16 @@ | ||||
|  | ||||
|       <v-divider class="border-opacity-50 my-2" /> | ||||
|  | ||||
|       <v-list-item title="User Center" prepend-icon="mdi-account-supervisor" exact :to="{ name: 'dashboard' }" /> | ||||
|       <v-list-item title="Dashboard" prepend-icon="mdi-account-supervisor" exact :to="{ name: 'dashboard' }" /> | ||||
|       <v-list-item title="Sign out" prepend-icon="mdi-logout" @click="signout"></v-list-item> | ||||
|     </v-list> | ||||
|   </v-menu> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { useUserinfo } from "@/stores/userinfo" | ||||
| import { defaultUserinfo, useUserinfo } from "@/stores/userinfo" | ||||
| import { computed } from "vue" | ||||
| import Cookie from "universal-cookie" | ||||
|  | ||||
| const id = useUserinfo() | ||||
|  | ||||
| @@ -30,7 +32,7 @@ const username = computed(() => { | ||||
|   if (id.userinfo.isLoggedIn) { | ||||
|     return "@" + id.userinfo.data?.name | ||||
|   } else { | ||||
|     return "@vistor" | ||||
|     return "@visitor" | ||||
|   } | ||||
| }) | ||||
| const nickname = computed(() => { | ||||
| @@ -40,4 +42,12 @@ const nickname = computed(() => { | ||||
|     return "Anonymous" | ||||
|   } | ||||
| }) | ||||
|  | ||||
| function signout() { | ||||
|   const ck = new Cookie(); | ||||
|   ck.remove("__hydrogen_atk"); | ||||
|   ck.remove("__hydrogen_rtk") | ||||
|   id.userinfo = defaultUserinfo | ||||
|   window.location.reload() | ||||
| } | ||||
| </script> | ||||
|   | ||||
| @@ -44,11 +44,11 @@ const emits = defineEmits(["swap", "update:loading", "update:currentFactor"]) | ||||
|  | ||||
| async function load() { | ||||
|   emits("update:loading", true) | ||||
|   const res = await request(`/api/auth/factors?ticketId=${props.ticket.ticketId}`) | ||||
|   const res = await request(`/api/auth/factors?ticketId=${props.ticket.id}`) | ||||
|   if (res.status !== 200) { | ||||
|     error.value = await res.text() | ||||
|   } else { | ||||
|     factors.value = await res.json() | ||||
|     factors.value = (await res.json()).filter((e: any) => e.type != 0) | ||||
|   } | ||||
|   emits("update:loading", false) | ||||
| } | ||||
|   | ||||
| @@ -8,6 +8,7 @@ const router = createRouter({ | ||||
|     { | ||||
|       path: "/", | ||||
|       redirect: { name: "dashboard" }, | ||||
|       meta: { public: true }, | ||||
|     }, | ||||
|     { | ||||
|       path: "/users", | ||||
|   | ||||
| @@ -9,7 +9,7 @@ export interface Userinfo { | ||||
|   data: any | ||||
| } | ||||
|  | ||||
| const defaultUserinfo: Userinfo = { | ||||
| export const defaultUserinfo: Userinfo = { | ||||
|   isLoggedIn: false, | ||||
|   displayName: "Citizen", | ||||
|   data: null, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user