fix: pass public source through signup navigation

master
weizong song 4 months ago
parent f29b0143de
commit b3e7c2a318

@ -15,15 +15,21 @@ import './admin/routeMeta'
const MainLayout = () => import('../layouts/MainLayout.vue')
function participantRootRedirect() {
function sourceQueryFrom(to: { query?: Record<string, unknown> }): { src: string } | undefined {
const src = typeof to.query?.src === 'string' ? to.query.src.trim() : ''
return /^[A-Za-z0-9_-]{2,64}$/.test(src) ? { src } : undefined
}
function participantRootRedirect(to?: { query?: Record<string, unknown> }) {
const t = localStorage.getItem(TOKEN_KEY)
const s = localStorage.getItem(PARTICIPANT_COMPETITION_SLUG_KEY)
const query = to ? sourceQueryFrom(to) : undefined
if (s) {
return t
? { name: 'participant-apply', params: { slug: s }, replace: true as const }
: { name: 'participant-login', params: { slug: s }, replace: true as const }
? { name: 'participant-apply', params: { slug: s }, query, replace: true as const }
: { name: 'participant-login', params: { slug: s }, query, replace: true as const }
}
return { path: '/c', replace: true as const }
return { path: '/c', query, replace: true as const }
}
const router = createRouter({
@ -173,9 +179,13 @@ router.beforeEach(async (to) => {
if (to.matched.some((r) => r.meta.requiresAuth) && !participantToken) {
const slug = to.params.slug != null ? String(to.params.slug) : ''
if (slug) {
return { name: 'participant-login', params: { slug }, query: { redirect: to.fullPath } }
return {
name: 'participant-login',
params: { slug },
query: { redirect: to.fullPath, ...sourceQueryFrom(to) },
}
}
return { path: '/c', query: { redirect: to.fullPath } }
return { path: '/c', query: { redirect: to.fullPath, ...sourceQueryFrom(to) } }
}
if (to.meta.guestOnly && participantToken) {

@ -11,6 +11,11 @@ interface ResolveResponse {
source_name?: string
}
function normalizeSourceCode(value: unknown): string | null {
const sourceCode = typeof value === 'string' ? value.trim() : ''
return /^[A-Za-z0-9_-]{2,64}$/.test(sourceCode) ? sourceCode : null
}
function nowMs(): number {
return Date.now()
}
@ -39,6 +44,14 @@ function writePublicSourceCache(sourceCode: string): void {
}
export function readPublicSourceCodeForAttribution(): string | null {
const currentUrlSourceCode =
typeof window !== 'undefined'
? normalizeSourceCode(new URLSearchParams(window.location.search).get('src'))
: null
if (currentUrlSourceCode) {
return currentUrlSourceCode
}
if (!storageAvailable()) return null
const sourceCode = window.localStorage.getItem(SOURCE_CODE_KEY)?.trim() ?? ''
const checkedAtRaw = window.localStorage.getItem(SOURCE_CHECKED_AT_KEY)?.trim() ?? ''
@ -56,7 +69,7 @@ export function readPublicSourceCodeForAttribution(): string | null {
async function resolvePublicSource(sourceCode: string): Promise<string | null> {
const trimmed = sourceCode.trim()
if (!/^[A-Za-z0-9_-]{2,64}$/.test(trimmed)) return null
if (!normalizeSourceCode(trimmed)) return null
const qs = new URLSearchParams({ source_code: trimmed })
const res = await fetch(`${getApiBase()}/api/v1/public/source-channels/resolve?${qs.toString()}`, {

@ -1,8 +1,9 @@
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { useRoute, useRouter } from 'vue-router'
import 'bootstrap/dist/css/bootstrap.min.css'
const route = useRoute()
const router = useRouter()
const slugInput = ref('')
const error = ref('')
@ -14,7 +15,12 @@ function navigate() {
error.value = '请填写访问地址'
return
}
void router.push({ name: 'participant-login', params: { slug: s } })
const src = typeof route.query.src === 'string' ? route.query.src.trim() : ''
void router.push({
name: 'participant-login',
params: { slug: s },
query: /^[A-Za-z0-9_-]{2,64}$/.test(src) ? { src } : undefined,
})
}
</script>

Loading…
Cancel
Save