fix: use Hermes session endpoint for login token validation (#227)

Co-authored-by: Han <hanzckernel@users.noreply.github.com>
This commit is contained in:
Zhicheng Han
2026-04-26 04:41:43 +02:00
committed by GitHub
parent 1e0dc69840
commit 2053da1c10
2 changed files with 76 additions and 1 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ async function handleTokenLogin() {
errorMsg.value = "";
try {
const res = await fetch("/api/sessions", {
const res = await fetch("/api/hermes/sessions", {
headers: { Authorization: `Bearer ${key}` },
});
+75
View File
@@ -0,0 +1,75 @@
// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
const mockReplace = vi.hoisted(() => vi.fn())
const mockFetchAuthStatus = vi.hoisted(() => vi.fn())
const mockLoginWithPassword = vi.hoisted(() => vi.fn())
const mockSetApiKey = vi.hoisted(() => vi.fn())
const mockHasApiKey = vi.hoisted(() => vi.fn())
vi.mock('vue-router', () => ({
useRouter: () => ({
replace: mockReplace,
}),
}))
vi.mock('vue-i18n', () => ({
useI18n: () => ({
t: (key: string) => key,
}),
}))
vi.mock('@/api/client', () => ({
setApiKey: mockSetApiKey,
hasApiKey: mockHasApiKey,
}))
vi.mock('@/api/auth', () => ({
fetchAuthStatus: mockFetchAuthStatus,
loginWithPassword: mockLoginWithPassword,
}))
import LoginView from '@/views/LoginView.vue'
const mockFetch = vi.fn()
vi.stubGlobal('fetch', mockFetch)
describe('LoginView token login', () => {
beforeEach(() => {
delete (window as any).__LOGIN_TOKEN__
vi.clearAllMocks()
mockHasApiKey.mockReturnValue(false)
mockFetchAuthStatus.mockResolvedValue({ hasPasswordLogin: false })
mockFetch.mockResolvedValue({ ok: true, status: 200 })
})
it('validates token login against the Hermes sessions endpoint', async () => {
const wrapper = mount(LoginView)
await wrapper.find('input.login-input').setValue('secret-token')
await wrapper.find('form.login-form').trigger('submit')
expect(mockFetch).toHaveBeenCalledOnce()
expect(mockFetch).toHaveBeenCalledWith('/api/hermes/sessions', {
headers: { Authorization: 'Bearer secret-token' },
})
expect(mockSetApiKey).toHaveBeenCalledWith('secret-token')
expect(mockReplace).toHaveBeenCalledWith('/hermes/chat')
})
it('keeps the existing invalid-token behavior on 401', async () => {
mockFetch.mockResolvedValue({ ok: false, status: 401 })
const wrapper = mount(LoginView)
await wrapper.find('input.login-input').setValue('bad-token')
await wrapper.find('form.login-form').trigger('submit')
expect(mockFetch).toHaveBeenCalledWith('/api/hermes/sessions', {
headers: { Authorization: 'Bearer bad-token' },
})
expect(wrapper.find('.login-error').text()).toBe('login.invalidToken')
expect(mockSetApiKey).not.toHaveBeenCalled()
expect(mockReplace).not.toHaveBeenCalled()
})
})