fix: TTLock — correct OAuth server (api.sciener.com) and API servers (euapi/cnapi)

- OAuth token: always https://api.sciener.com/oauth2/token (was euopen.ttlock.com = wrong)
- EU API: https://euapi.ttlock.com/v3/... (was euopen.ttlock.com)
- CN API: https://cnapi.ttlock.com/v3/... (was open.ttlock.com)
- Migration 054: update existing DB records with old server URLs
- UI: update radio button values to correct server names

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-02 11:21:37 +03:00
parent ee7e515f61
commit 84ead2af99
3 changed files with 21 additions and 9 deletions

View File

@@ -0,0 +1,12 @@
-- Исправляем старые значения api_server: euopen.ttlock.com → euapi.ttlock.com
-- (euopen — это веб-портал разработчиков, а не API-сервер)
UPDATE hotel_ttlock_config
SET api_server = 'https://euapi.ttlock.com'
WHERE api_server = 'https://euopen.ttlock.com';
UPDATE hotel_ttlock_config
SET api_server = 'https://cnapi.ttlock.com'
WHERE api_server = 'https://open.ttlock.com';
ALTER TABLE hotel_ttlock_config
ALTER COLUMN api_server SET DEFAULT 'https://euapi.ttlock.com';

View File

@@ -51,14 +51,14 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
[hotelId], [hotelId],
) )
if (!rows[0]) { if (!rows[0]) {
return { isEnabled: false, clientId: '', cardSectors: '1,2,3,4,5,6,7,8,9,10', apiServer: 'https://euopen.ttlock.com' } return { isEnabled: false, clientId: '', cardSectors: '1,2,3,4,5,6,7,8,9,10', apiServer: 'https://euapi.ttlock.com' }
} }
const r = rows[0] const r = rows[0]
return { return {
isEnabled: r.is_enabled, isEnabled: r.is_enabled,
clientId: r.client_id, clientId: r.client_id,
cardSectors: r.card_sectors, cardSectors: r.card_sectors,
apiServer: r.api_server ?? 'https://euopen.ttlock.com', apiServer: r.api_server ?? 'https://euapi.ttlock.com',
} }
}) })
@@ -187,7 +187,7 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
type: 'ttlock:test_api', type: 'ttlock:test_api',
clientId: cfg.client_id, clientId: cfg.client_id,
clientSecret: cfg.client_secret, clientSecret: cfg.client_secret,
apiServer: cfg.api_server ?? 'https://euopen.ttlock.com', apiServer: cfg.api_server ?? 'https://euapi.ttlock.com',
}, 15_000) as { ok?: boolean; lockCount?: number; error?: string } }, 15_000) as { ok?: boolean; lockCount?: number; error?: string }
if (!result.ok) return reply.code(502).send({ error: result.error ?? 'Ошибка API' }) if (!result.ok) return reply.code(502).send({ error: result.error ?? 'Ошибка API' })
@@ -394,7 +394,7 @@ const ttlockRoutes: FastifyPluginAsync = async (fastify) => {
cardSectors: cfg.card_sectors, cardSectors: cfg.card_sectors,
clientId: cfg.client_id, clientId: cfg.client_id,
clientSecret: cfg.client_secret, clientSecret: cfg.client_secret,
apiServer: cfg.api_server ?? 'https://euopen.ttlock.com', apiServer: cfg.api_server ?? 'https://euapi.ttlock.com',
startDate: checkIn, startDate: checkIn,
endDate: checkOut, endDate: checkOut,
}, 30_000) }, 30_000)

View File

@@ -143,7 +143,7 @@ export function TTLockPage() {
const [clientId, setClientId] = useState('') const [clientId, setClientId] = useState('')
const [clientSecret, setClientSecret] = useState('') const [clientSecret, setClientSecret] = useState('')
const [cardSectors, setCardSectors] = useState('1,2,3,4,5,6,7,8,9,10') const [cardSectors, setCardSectors] = useState('1,2,3,4,5,6,7,8,9,10')
const [apiServer, setApiServer] = useState('https://euopen.ttlock.com') const [apiServer, setApiServer] = useState('https://euapi.ttlock.com')
// Per-workstation COM port state // Per-workstation COM port state
const [wsComPorts, setWsComPorts] = useState<Record<string, string>>({}) const [wsComPorts, setWsComPorts] = useState<Record<string, string>>({})
@@ -243,7 +243,7 @@ export function TTLockPage() {
setIsEnabled(cfg.isEnabled) setIsEnabled(cfg.isEnabled)
setClientId(cfg.clientId) setClientId(cfg.clientId)
setCardSectors(cfg.cardSectors || '1,2,3,4,5,6,7,8,9,10') setCardSectors(cfg.cardSectors || '1,2,3,4,5,6,7,8,9,10')
setApiServer(cfg.apiServer || 'https://euopen.ttlock.com') setApiServer(cfg.apiServer || 'https://euapi.ttlock.com')
setMappings(maps) setMappings(maps)
setRooms(roomList) setRooms(roomList)
setWorkstations(wsList) setWorkstations(wsList)
@@ -415,8 +415,8 @@ export function TTLockPage() {
<label className="form-label">Сервер TTLock API</label> <label className="form-label">Сервер TTLock API</label>
<div className="flex gap-3 mt-1"> <div className="flex gap-3 mt-1">
{[ {[
{ value: 'https://euopen.ttlock.com', label: 'EU', hint: 'euopen.ttlock.com' }, { value: 'https://euapi.ttlock.com', label: 'EU', hint: 'euapi.ttlock.com' },
{ value: 'https://open.ttlock.com', label: 'China', hint: 'open.ttlock.com' }, { value: 'https://cnapi.ttlock.com', label: 'China', hint: 'cnapi.ttlock.com' },
].map(opt => ( ].map(opt => (
<label <label
key={opt.value} key={opt.value}
@@ -441,7 +441,7 @@ export function TTLockPage() {
))} ))}
</div> </div>
<p className="text-xs text-slate-400 mt-1.5"> <p className="text-xs text-slate-400 mt-1.5">
Если получаете ошибку 404 при выдаче карты попробуйте другой сервер. OAuth авторизация всегда через api.sciener.com. Выберите регион для /v3/ API.
</p> </p>
</div> </div>