fix(search): fallback to search API key when tenant token fails; use direct HTTP for server-side search with master key
This commit is contained in:
parent
607e379dee
commit
dfdadcdf77
1 changed files with 37 additions and 33 deletions
|
|
@ -40,29 +40,30 @@ router.post('/token', async (req, res) => {
|
||||||
const organizationIds = orgs.map(org => org.organization_id);
|
const organizationIds = orgs.map(org => org.organization_id);
|
||||||
|
|
||||||
if (organizationIds.length === 0) {
|
if (organizationIds.length === 0) {
|
||||||
return res.status(403).json({
|
return res.status(403).json({ error: 'No organizations found for user' });
|
||||||
error: 'No organizations found for user'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate tenant token with user and organization filters
|
|
||||||
const token = await generateTenantToken(userId, organizationIds, tokenExpiry);
|
|
||||||
const expiresAt = new Date(Date.now() + tokenExpiry * 1000);
|
const expiresAt = new Date(Date.now() + tokenExpiry * 1000);
|
||||||
|
const searchUrl = process.env.MEILISEARCH_HOST || 'http://127.0.0.1:7700';
|
||||||
|
|
||||||
res.json({
|
// Preferred: tenant token
|
||||||
token,
|
try {
|
||||||
expiresAt: expiresAt.toISOString(),
|
const token = await generateTenantToken(userId, organizationIds, tokenExpiry);
|
||||||
expiresIn: tokenExpiry,
|
return res.json({ token, expiresAt: expiresAt.toISOString(), expiresIn: tokenExpiry, indexName: INDEX_NAME, searchUrl, mode: 'tenant' });
|
||||||
indexName: INDEX_NAME,
|
} catch (err) {
|
||||||
searchUrl: process.env.MEILISEARCH_HOST || 'http://127.0.0.1:7700'
|
console.warn('Tenant token generation failed, falling back to search API key:', err?.message || err);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
// Fallback: use default search API key
|
||||||
|
const client = getMeilisearchClient();
|
||||||
|
const keys = await client.getKeys();
|
||||||
|
const searchKey = keys.results?.find(k => k.actions?.includes('search') && (k.indexes?.includes('*') || k.indexes?.includes(INDEX_NAME)));
|
||||||
|
if (!searchKey?.key) throw new Error('No search API key available for fallback');
|
||||||
|
return res.json({ token: searchKey.key, expiresAt: null, expiresIn: null, indexName: INDEX_NAME, searchUrl, mode: 'search-key' });
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Token generation error:', error);
|
console.error('Token generation error:', error);
|
||||||
res.status(500).json({
|
res.status(500).json({ error: 'Failed to generate search token', message: error.message });
|
||||||
error: 'Failed to generate search token',
|
|
||||||
message: error.message
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -124,24 +125,27 @@ router.post('/', async (req, res) => {
|
||||||
|
|
||||||
const filterString = filterParts.join(' AND ');
|
const filterString = filterParts.join(' AND ');
|
||||||
|
|
||||||
// Get Meilisearch client and search
|
// Use direct HTTP call with master key to avoid client cache issues
|
||||||
const client = getMeilisearchClient();
|
const host = process.env.MEILISEARCH_HOST || 'http://127.0.0.1:7700';
|
||||||
const index = client.index(INDEX_NAME);
|
const apiKey = process.env.MEILISEARCH_MASTER_KEY;
|
||||||
|
const resp = await fetch(`${host}/indexes/${INDEX_NAME}/search`, {
|
||||||
const searchResults = await index.search(q, {
|
method: 'POST',
|
||||||
filter: filterString,
|
headers: {
|
||||||
limit: parseInt(limit),
|
'Content-Type': 'application/json',
|
||||||
offset: parseInt(offset),
|
...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {})
|
||||||
attributesToHighlight: ['text'],
|
},
|
||||||
attributesToCrop: ['text'],
|
body: JSON.stringify({ q, filter: filterString, limit: parseInt(limit), offset: parseInt(offset), attributesToHighlight: ['text'], attributesToCrop: ['text'], cropLength: 200 })
|
||||||
cropLength: 200
|
|
||||||
});
|
});
|
||||||
|
if (!resp.ok) {
|
||||||
res.json({
|
const txt = await resp.text();
|
||||||
hits: searchResults.hits,
|
throw new Error(`Meilisearch HTTP ${resp.status}: ${txt}`);
|
||||||
estimatedTotalHits: searchResults.estimatedTotalHits,
|
}
|
||||||
query: searchResults.query,
|
const searchResults = await resp.json();
|
||||||
processingTimeMs: searchResults.processingTimeMs,
|
return res.json({
|
||||||
|
hits: searchResults.hits || [],
|
||||||
|
estimatedTotalHits: searchResults.estimatedTotalHits || 0,
|
||||||
|
query: searchResults.query || q,
|
||||||
|
processingTimeMs: searchResults.processingTimeMs || 0,
|
||||||
limit: parseInt(limit),
|
limit: parseInt(limit),
|
||||||
offset: parseInt(offset)
|
offset: parseInt(offset)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue