From e6e80c6a18b997c3d1dbc255c0158b245d47e4ef Mon Sep 17 00:00:00 2001 From: chenchen Date: Mon, 18 May 2026 17:24:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20route=20registration=20through=20?= =?UTF-8?q?=E5=A4=AA=E6=9E=81=20AI=20PAD=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registration now goes through the Agnet auth proxy (/api/heicode-auth/*) instead of the local Manager API. Email verification is always required (太极 mandates it). After successful registration, tokens are used directly to establish the Manager session without a redundant login call. Co-Authored-By: Claude Opus 4.6 --- heicode/web/default/src/features/auth/api.ts | 66 ++++++++++++++++--- .../auth/sign-up/components/sign-up-form.tsx | 20 ++++-- 2 files changed, 72 insertions(+), 14 deletions(-) diff --git a/heicode/web/default/src/features/auth/api.ts b/heicode/web/default/src/features/auth/api.ts index cd25ec5..c2b49a0 100644 --- a/heicode/web/default/src/features/auth/api.ts +++ b/heicode/web/default/src/features/auth/api.ts @@ -101,6 +101,19 @@ async function establishManagerSessionFromAgnet(): Promise<{ return { managerUserId: body.data?.id } } +export async function loginWithAgnetTokens( + accessToken: string, + refreshToken?: string +): Promise<{ managerUserId?: number }> { + writeTokens(accessToken, refreshToken) + try { + return await establishManagerSessionFromAgnet() + } catch (err) { + clearHeicodeTokens() + throw err + } +} + async function callHeicodeAuth( path: string, init: RequestInit = {}, @@ -317,23 +330,56 @@ export async function wechatLoginByCode(code: string): Promise { // Registration // ---------------------------------------------------------------------------- -// User registration -export async function register(payload: RegisterPayload): Promise { - const res = await api.post(`/api/user/register`, payload, { - params: { turnstile: payload.turnstile ?? '' }, +// User registration via Agnet (太极 AI PAD) +export async function register(payload: RegisterPayload): Promise { + const res = await callHeicodeAuth<{ + success: boolean + message?: string + detail?: string + data?: { + token?: string + refreshToken?: string + user?: { id?: string; name?: string; email?: string; role?: string; channelId?: string } + } + }>('/api/auth/register', { + method: 'POST', + body: JSON.stringify({ + username: payload.username, + email: payload.email, + password: payload.password, + verification_code: payload.verification_code, + full_name: payload.username, + }), }) - return res.data + return { + success: Boolean(res?.success), + message: res?.message || res?.detail || '', + data: res?.data, + } } -// Send email verification code +// Send email verification code via Agnet (太极 AI PAD) export async function sendEmailVerification( email: string, - turnstile?: string + _turnstile?: string ): Promise { - const res = await api.get('/api/verification', { - params: { email, turnstile }, + const res = await callHeicodeAuth<{ + success: boolean + message?: string + detail?: string + }>(`/api/auth/register/send-code?email=${encodeURIComponent(email)}`, { + method: 'POST', }) - return res.data + return { + success: Boolean(res?.success), + message: res?.message || res?.detail || '', + } } // Bind email to OAuth account diff --git a/heicode/web/default/src/features/auth/sign-up/components/sign-up-form.tsx b/heicode/web/default/src/features/auth/sign-up/components/sign-up-form.tsx index d71c80e..458c799 100644 --- a/heicode/web/default/src/features/auth/sign-up/components/sign-up-form.tsx +++ b/heicode/web/default/src/features/auth/sign-up/components/sign-up-form.tsx @@ -28,7 +28,7 @@ import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { PasswordInput } from '@/components/password-input' import { Turnstile } from '@/components/turnstile' -import { register, wechatLoginByCode } from '@/features/auth/api' +import { register, loginWithAgnetTokens, wechatLoginByCode } from '@/features/auth/api' import { LegalConsent } from '@/features/auth/components/legal-consent' import { OAuthProviders } from '@/features/auth/components/oauth-providers' import { registerFormSchema } from '@/features/auth/constants' @@ -80,7 +80,7 @@ export function SignUpForm({ }) const emailValue = form.watch('email') - const emailVerificationRequired = !!status?.email_verification + const emailVerificationRequired = true const hasUserAgreement = Boolean(status?.user_agreement_enabled) const hasPrivacyPolicy = Boolean(status?.privacy_policy_enabled) const requiresLegalConsent = hasUserAgreement || hasPrivacyPolicy @@ -142,8 +142,20 @@ export function SignUpForm({ }) if (res?.success) { - toast.success(t('Account created! Please sign in')) - redirectToLogin() + toast.success(t('Account created!')) + if (res.data?.token) { + const sessionRes = await loginWithAgnetTokens( + res.data.token, + res.data.refreshToken + ) + await handleLoginSuccess( + sessionRes.managerUserId + ? { id: sessionRes.managerUserId } + : null + ) + } else { + redirectToLogin() + } } } catch (_error) { // Errors are handled by global interceptor