fix(tinode): send login_type on basic-scheme login (Zentao bug #33)
server/user.go's validateLoginTenant now hard-requires a login_type
field (0 enterprise / 1 personal) on every {login scheme:"basic"}
message, rejecting the rest with a 422 LOGIN_TYPE_REQUIRED policy
violation -- confirmed live by reading the currently-deployed
server/session.go call site and server/user.go's validation logic.
The vendored tinode-sdk has no API surface for this custom field (its
login()/loginBasic() packet builders are private class fields that
only ever write scheme/secret/cred), so every basic-scheme web login
was failing.
Extends the existing installTenantHiPatch wire-level interception
(same technique already used for {hi}.tenant) to also inject
login_type into outgoing {login} packets, derived from the resolved
tenant's code. tenant_code is deliberately left unset: the backend
falls back to the session's own tenant (already established via the
{hi} patch) when the {login} message omits it, for both the personal
and enterprise branches. token-scheme logins (session restore/
reconnect re-auth) are untouched.
Verified live: captured the actual outgoing WS frame now carrying
login_type, and confirmed the resulting error changed from what would
be a 422 policy violation to a normal credential-mismatch error.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
ed029c59ef
commit
1127680425
@@ -136,13 +136,21 @@ export function clearKickedInfo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The server extends the stock {hi} packet with a `tenant` field the vendored JS SDK has no API for
|
||||
* (resolved via POST /v1/im/tenants/resolve; see server/datamodel.go). The packet builder is private,
|
||||
* so the only usable hook is wrapping the connection's raw sendText and injecting the field into the
|
||||
* already-serialized JSON. Ported as-is from the old app's tnSetup/installTenantHiPatch -- this is a
|
||||
* real backend protocol extension, not an old-codebase-specific workaround.
|
||||
* Two backend protocol extensions the vendored JS SDK has no API for -- both fields the packet
|
||||
* builders (#initPacket/login(), both private) never write, so the only usable hook for either is
|
||||
* wrapping the connection's raw sendText and injecting the field into the already-serialized JSON:
|
||||
* - {hi}.tenant (resolved via POST /v1/im/tenants/resolve; see server/datamodel.go). Ported as-is
|
||||
* from the old app's tnSetup/installTenantHiPatch.
|
||||
* - {login}.login_type: confirmed live (server/user.go validateLoginTenant, called from every
|
||||
* session.login()) that scheme:"basic" logins now hard-require this field -- 0 enterprise /
|
||||
* 1 personal -- and fail with a 422 LOGIN_TYPE_REQUIRED without it (Zentao bug #33). tenant_code
|
||||
* is deliberately left unset: validateLoginTenant falls back to the session's own tenant (already
|
||||
* established by the {hi} patch above) when {login} omits it, for both the personal and
|
||||
* enterprise branches, so login_type is the only field this client needs to add. token-scheme
|
||||
* logins (restoreSession/reconnect re-auth) are untouched -- validateLoginTenant only requires
|
||||
* login_type when scheme is "basic".
|
||||
*/
|
||||
function installTenantHiPatch(t: Tinode) {
|
||||
function installOutgoingPacketPatches(t: Tinode) {
|
||||
const conn = t._connection;
|
||||
if (!conn || conn.__tenantPatched) return;
|
||||
const original = conn.sendText.bind(conn);
|
||||
@@ -160,6 +168,17 @@ function installTenantHiPatch(t: Tinode) {
|
||||
} catch {
|
||||
// Not valid JSON -- send as is.
|
||||
}
|
||||
} else if (typeof msg === 'string' && msg.indexOf('"login":') >= 0) {
|
||||
try {
|
||||
const parsed = JSON.parse(msg);
|
||||
if (parsed.login && parsed.login.scheme === 'basic') {
|
||||
const tenantCode = useSessionStore.getState().tenant?.code || 'default';
|
||||
parsed.login.login_type = tenantCode.toLowerCase() === 'default' ? 1 : 0;
|
||||
msg = JSON.stringify(parsed);
|
||||
}
|
||||
} catch {
|
||||
// Not valid JSON -- send as is.
|
||||
}
|
||||
}
|
||||
return original(msg as string);
|
||||
};
|
||||
@@ -173,7 +192,7 @@ function createTinode(): Tinode {
|
||||
const t = new Tinode({ appName: APP_NAME, host, apiKey: API_KEY, transport: 'ws', secure, persist: false });
|
||||
t.setHumanLanguage('zh');
|
||||
t.enableLogging(LOGGING_ENABLED, true);
|
||||
installTenantHiPatch(t);
|
||||
installOutgoingPacketPatches(t);
|
||||
|
||||
t.onConnect = () => {
|
||||
const wasReconnecting = reconnectState.retryInSeconds > 0 || reconnectState.attemptInFlight;
|
||||
|
||||
Reference in New Issue
Block a user