refactor(ui): Update auth and profile pages to use $mod context

- Replace $env.$vbase with $mod.$vbase in callback.html OAuth handlers
    - Update login.html to use $mod.$vbase for login/register API calls
    - Update profile.html to use $mod.$vbase for user data and logout
    - Fix OAuth providers page to reference $mod.$vbase correctly
master
veypi 4 weeks ago
parent 6552ebf832
commit aabea8ef4a

@ -492,7 +492,7 @@
return; return;
} }
const data = await $env.$vbase.oauthCallback(provider, code, state); const data = await $mod.$vbase.oauthCallback(provider, code, state);
if (data.access_token || data.token) { if (data.access_token || data.token) {
// Already bound, login success (token set by vbase) // Already bound, login success (token set by vbase)
@ -527,7 +527,7 @@
submitting = true; submitting = true;
try { try {
const data = await $env.$vbase.bindAccount(tempToken, bindForm.username, bindForm.password); const data = await $mod.$vbase.bindAccount(tempToken, bindForm.username, bindForm.password);
$message.success($t('auth.bind_success') || 'Binding successful'); $message.success($t('auth.bind_success') || 'Binding successful');
setTimeout(() => $router.push('/'), 1000); setTimeout(() => $router.push('/'), 1000);
@ -546,7 +546,7 @@
submitting = true; submitting = true;
try { try {
const data = await $env.$vbase.bindRegister(tempToken, regForm.username, regForm.email || undefined); const data = await $mod.$vbase.bindRegister(tempToken, regForm.username, regForm.email || undefined);
$message.success($t('auth.register_success') || 'Registration successful'); $message.success($t('auth.register_success') || 'Registration successful');
setTimeout(() => $router.push('/'), 1000); setTimeout(() => $router.push('/'), 1000);

@ -690,7 +690,7 @@
} }
try { try {
await $env.$vbase.request('POST', '/api/verification/send', { await $mod.$vbase.request('POST', '/api/verification/send', {
type: type, type: type,
target: signInForm.target, target: signInForm.target,
purpose: 'login' purpose: 'login'
@ -729,16 +729,16 @@
} }
const type = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(signInForm.target) ? 'email' : 'phone'; const type = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(signInForm.target) ? 'email' : 'phone';
const data = await $env.$vbase.request('POST', '/api/auth/login/code', { const data = await $mod.$vbase.request('POST', '/api/auth/login/code', {
type: type, type: type,
target: signInForm.target, target: signInForm.target,
code: signInForm.code code: signInForm.code
}); });
if (data && data.access_token) { if (data && data.access_token) {
$env.$vbase.token = data.access_token; $mod.$vbase.token = data.access_token;
if (data.refresh_token) $env.$vbase.refreshToken = data.refresh_token; if (data.refresh_token) $mod.$vbase.refreshToken = data.refresh_token;
if (data.user) $env.$vbase.user = data.user; if (data.user) $mod.$vbase.user = data.user;
$message.success($t('auth.login_success')); $message.success($t('auth.login_success'));
if (redirect === '/' || redirect.startsWith('http')) { if (redirect === '/' || redirect.startsWith('http')) {
@ -755,7 +755,7 @@
throw new Error($t('auth.fill_all_fields')); throw new Error($t('auth.fill_all_fields'));
} }
const success = await $env.$vbase.login(signInForm.username, signInForm.password); const success = await $mod.$vbase.login(signInForm.username, signInForm.password);
if (success) { if (success) {
$message.success($t('auth.login_success')); $message.success($t('auth.login_success'));
@ -803,7 +803,7 @@
try { try {
// Use vbase.request for consistent API handling // Use vbase.request for consistent API handling
const data = await $env.$vbase.request('POST', '/api/auth/register', { const data = await $mod.$vbase.request('POST', '/api/auth/register', {
username: signUpForm.username, username: signUpForm.username,
email: signUpForm.email || undefined, email: signUpForm.email || undefined,
phone: signUpForm.phone || undefined, phone: signUpForm.phone || undefined,
@ -812,12 +812,12 @@
if (data && data.access_token) { if (data && data.access_token) {
// Auto login after register using vbase setters // Auto login after register using vbase setters
$env.$vbase.token = data.access_token; $mod.$vbase.token = data.access_token;
if (data.refresh_token) { if (data.refresh_token) {
$env.$vbase.refreshToken = data.refresh_token; $mod.$vbase.refreshToken = data.refresh_token;
} }
if (data.user) { if (data.user) {
$env.$vbase.user = data.user; $mod.$vbase.user = data.user;
} }
$message.success($t('auth.register_success')); $message.success($t('auth.register_success'));

@ -46,7 +46,7 @@
gap: var(--spacing-md); gap: var(--spacing-md);
transition: all 0.2s; transition: all 0.2s;
} }
.card:hover { .card:hover {
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: var(--shadow-md); box-shadow: var(--shadow-md);
@ -200,7 +200,7 @@
loadProviders = async () => { loadProviders = async () => {
try { try {
const res = await $env.$vbase.request('GET', '/api/oauth/providers'); const res = await $vbase.request('GET', '/api/oauth/providers');
providers = res.items || []; providers = res.items || [];
} catch (e) { } catch (e) {
$message.error(e.message); $message.error(e.message);
@ -220,7 +220,7 @@
openCreateModal = () => { openCreateModal = () => {
isEdit = false; isEdit = false;
formData = { code: "", name: "", client_id: "", client_secret: "", enabled: true }; formData = {code: "", name: "", client_id: "", client_secret: "", enabled: true};
showModal = true; showModal = true;
}; };
@ -228,7 +228,7 @@
isEdit = true; isEdit = true;
try { try {
const detail = await $axios.get(`/api/oauth/providers/${p.code}`); const detail = await $axios.get(`/api/oauth/providers/${p.code}`);
formData = { ...detail, client_secret: "" }; formData = {...detail, client_secret: ""};
showModal = true; showModal = true;
} catch (e) { } catch (e) {
$message.error(e.message); $message.error(e.message);
@ -267,4 +267,4 @@
$data.loadProviders(); $data.loadProviders();
</script> </script>
</html> </html>

@ -62,7 +62,7 @@
font-weight: bold; font-weight: bold;
overflow: hidden; overflow: hidden;
} }
.avatar img { .avatar img {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -156,7 +156,8 @@
<div class="avatar-wrapper" @click="triggerAvatarUpload"> <div class="avatar-wrapper" @click="triggerAvatarUpload">
<div class="avatar"> <div class="avatar">
<img v-if="user.avatar" :src="user.avatar" alt="Avatar"> <img v-if="user.avatar" :src="user.avatar" alt="Avatar">
<span v-else>{{ user.nickname ? user.nickname.charAt(0).toUpperCase() : (user.username ? user.username.charAt(0).toUpperCase() : 'U') }}</span> <span v-else>{{ user.nickname ? user.nickname.charAt(0).toUpperCase() : (user.username ?
user.username.charAt(0).toUpperCase() : 'U') }}</span>
</div> </div>
<div class="avatar-overlay"> <div class="avatar-overlay">
<i class="fas fa-edit"></i> <i class="fas fa-edit"></i>
@ -167,7 +168,7 @@
<div style="color: var(--color-text-light); font-size: 0.9rem;">{{ $t('common.id') }}: {{ user.id }}</div> <div style="color: var(--color-text-light); font-size: 0.9rem;">{{ $t('common.id') }}: {{ user.id }}</div>
</div> </div>
</div> </div>
<form style="margin-top: var(--spacing-lg);" @submit.prevent="updateProfile"> <form style="margin-top: var(--spacing-lg);" @submit.prevent="updateProfile">
<div class="form-grid"> <div class="form-grid">
<v-input label="Username" :label="$t('user.username')" v:value="user.username" disabled></v-input> <v-input label="Username" :label="$t('user.username')" v:value="user.username" disabled></v-input>
@ -189,11 +190,14 @@
<div class="section-title">{{ $t('auth.security') || 'Security' }}</div> <div class="section-title">{{ $t('auth.security') || 'Security' }}</div>
<form @submit.prevent="changePassword"> <form @submit.prevent="changePassword">
<div class="form-grid"> <div class="form-grid">
<v-input class="form-full" :label="$t('auth.old_password')" type="password" v:value="passwordForm.old_password"></v-input> <v-input class="form-full" :label="$t('auth.old_password')" type="password"
<v-input class="form-full" :label="$t('auth.new_password')" type="password" v:value="passwordForm.new_password"></v-input> v:value="passwordForm.old_password"></v-input>
<v-input class="form-full" :label="$t('auth.new_password')" type="password"
v:value="passwordForm.new_password"></v-input>
</div> </div>
<div style="margin-top: var(--spacing-md); display: flex; justify-content: flex-end;"> <div style="margin-top: var(--spacing-md); display: flex; justify-content: flex-end;">
<v-btn type="submit" variant="outline" :loading="pwdLoading" :disabled="!passwordForm.new_password || !passwordForm.old_password"> <v-btn type="submit" variant="outline" :loading="pwdLoading"
:disabled="!passwordForm.new_password || !passwordForm.old_password">
{{ $t('auth.change_password') || 'Update Password' }} {{ $t('auth.change_password') || 'Update Password' }}
</v-btn> </v-btn>
</div> </div>
@ -220,7 +224,8 @@
</div> </div>
</div> </div>
<div> <div>
<v-btn v-if="isBound(provider.code)" size="sm" variant="outline" color="danger" :click="() => unbind(provider.code)"> <v-btn v-if="isBound(provider.code)" size="sm" variant="outline" color="danger"
:click="() => unbind(provider.code)">
{{ $t('common.unbind') }} {{ $t('common.unbind') }}
</v-btn> </v-btn>
<v-btn v-else size="sm" variant="outline" :click="() => bind(provider.code)"> <v-btn v-else size="sm" variant="outline" :click="() => bind(provider.code)">
@ -234,11 +239,11 @@
</div> </div>
</body> </body>
<script setup> <script setup>
user = $env.$vbase.user || {}; user = $mod.$vbase.user || {};
loading = false; loading = false;
pwdLoading = false; pwdLoading = false;
passwordForm = { old_password: '', new_password: '' }; passwordForm = {old_password: '', new_password: ''};
// Bindings // Bindings
providers = []; providers = [];
bindings = []; bindings = [];
@ -246,7 +251,7 @@
// Fetch fresh data // Fetch fresh data
loadUser = async () => { loadUser = async () => {
try { try {
user = await $env.$vbase.fetchUser(); user = await $mod.$vbase.fetchUser();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }
@ -260,7 +265,7 @@
code: p.type, code: p.type,
name: p.name name: p.name
})); }));
// Get current bindings // Get current bindings
bindings = await $axios.get('/api/auth/me/bindings'); bindings = await $axios.get('/api/auth/me/bindings');
} catch (e) { } catch (e) {
@ -305,19 +310,19 @@
}; };
handleLogout = async () => { handleLogout = async () => {
await $env.$vbase.logout('/login'); await $mod.$vbase.logout('/login');
}; };
// OAuth Helpers // OAuth Helpers
isBound = (code) => { isBound = (code) => {
return bindings.some(b => b.provider === code); return bindings.some(b => b.provider === code);
}; };
getBindInfo = (code) => { getBindInfo = (code) => {
const b = bindings.find(b => b.provider === code); const b = bindings.find(b => b.provider === code);
return b ? (b.provider_name || b.email || $t('auth.linked')) : ''; return b ? (b.provider_name || b.email || $t('auth.linked')) : '';
}; };
bind = async (provider) => { bind = async (provider) => {
try { try {
// Fetch authorization URL // Fetch authorization URL
@ -336,7 +341,7 @@
$message.error(e.message); $message.error(e.message);
} }
}; };
unbind = async (provider) => { unbind = async (provider) => {
try { try {
await $message.confirm($t('auth.unbind_confirm')); await $message.confirm($t('auth.unbind_confirm'));
@ -347,7 +352,7 @@
if (e !== 'cancel') $message.error(e.message); if (e !== 'cancel') $message.error(e.message);
} }
}; };
triggerAvatarUpload = async () => { triggerAvatarUpload = async () => {
try { try {
const url = await $message.prompt($t('user.avatar_url'), user.avatar || ''); const url = await $message.prompt($t('user.avatar_url'), user.avatar || '');
@ -365,4 +370,4 @@
$data.loadBindings(); $data.loadBindings();
</script> </script>
</html> </html>

Loading…
Cancel
Save