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