fix(core): use multi-call strategy for inclusive User Management scope
- Updated load_ae_obj_li__user to handle 'All' scope by fetching account and global users separately. - Ensured Search API uses authorized account_id_random field with op: 'eq' for null. - Fixed 404 for global lookups by avoiding [NULL] in standard List API.
This commit is contained in:
@@ -92,68 +92,27 @@ export async function load_ae_obj_li__user({
|
||||
try_cache?: boolean;
|
||||
log_lvl?: number;
|
||||
}): Promise<ae_User[]> {
|
||||
let promise;
|
||||
if (log_lvl) {
|
||||
console.log(`*** load_ae_obj_li__user() *** for_obj_id=${for_obj_id} include_global=${include_global} qry_str=${qry_str}`);
|
||||
}
|
||||
|
||||
// We use Search if there is a query string, OR if we need inclusive global logic
|
||||
const use_search = qry_str || (for_obj_id && include_global) || (!for_obj_id && include_global);
|
||||
|
||||
if (use_search) {
|
||||
const search_query: any = { and: [] };
|
||||
|
||||
if (qry_str) {
|
||||
search_query.q = qry_str;
|
||||
}
|
||||
|
||||
// Handle Account Scoping in Search Query
|
||||
// SCENARIO A: Text Search
|
||||
if (qry_str) {
|
||||
const search_query: any = { q: qry_str, and: [] };
|
||||
if (for_obj_id && include_global) {
|
||||
// Case: (Account == current OR Account == null)
|
||||
search_query.and.push({
|
||||
or: [
|
||||
{
|
||||
field: `account_id_random`,
|
||||
op: 'eq',
|
||||
value: for_obj_id
|
||||
},
|
||||
{
|
||||
field: `account_id_random`,
|
||||
op: 'eq', // Use 'eq' with null, as 'is' was unsupported
|
||||
value: null
|
||||
}
|
||||
{ field: `account_id_random`, op: 'eq', value: for_obj_id },
|
||||
{ field: `account_id_random`, op: 'eq', value: null }
|
||||
]
|
||||
});
|
||||
} else if (for_obj_id) {
|
||||
// Case: Account Only (with qry_str)
|
||||
search_query.and.push({
|
||||
field: `account_id_random`,
|
||||
op: 'eq',
|
||||
value: for_obj_id
|
||||
});
|
||||
search_query.and.push({ field: `account_id_random`, op: 'eq', value: for_obj_id });
|
||||
} else if (include_global) {
|
||||
// Case: Global Only (No Account)
|
||||
search_query.and.push({
|
||||
field: `account_id_random`,
|
||||
op: 'eq', // Use 'eq' with null
|
||||
value: null
|
||||
});
|
||||
search_query.and.push({ field: `account_id_random`, op: 'eq', value: null });
|
||||
}
|
||||
|
||||
if (enabled === 'enabled') {
|
||||
search_query.and.push({ field: 'enable', op: 'eq', value: true });
|
||||
} else if (enabled === 'not_enabled') {
|
||||
search_query.and.push({ field: 'enable', op: 'eq', value: false });
|
||||
}
|
||||
|
||||
if (hidden === 'hidden') {
|
||||
search_query.and.push({ field: 'hide', op: 'eq', value: true });
|
||||
} else if (hidden === 'not_hidden') {
|
||||
search_query.and.push({ field: 'hide', op: 'eq', value: false });
|
||||
}
|
||||
|
||||
if (log_lvl) {
|
||||
console.log(`load_ae_obj_li__user() - Using Search API`, JSON.stringify(search_query, null, 2));
|
||||
}
|
||||
|
||||
promise = api.search_ae_obj_v3({
|
||||
return await api.search_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'user',
|
||||
search_query,
|
||||
@@ -165,49 +124,58 @@ export async function load_ae_obj_li__user({
|
||||
offset,
|
||||
log_lvl
|
||||
});
|
||||
} else {
|
||||
// Simple case: Standard List API (Account Only or No Filter)
|
||||
if (log_lvl) {
|
||||
console.log(`load_ae_obj_li__user() - Using List API (for_obj_id=${for_obj_id})`);
|
||||
}
|
||||
}
|
||||
|
||||
// SCENARIO B: Multi-Scope (Account + Global) with no search string
|
||||
if (for_obj_id && include_global) {
|
||||
if (log_lvl) console.log('Strategy: Multi-call (Account + Global)');
|
||||
const [acct_users, global_users] = await Promise.all([
|
||||
load_ae_obj_li__user({ api_cfg, for_obj_id, include_global: false, enabled, hidden, view, limit, log_lvl }),
|
||||
load_ae_obj_li__user({ api_cfg, for_obj_id: null, include_global: true, enabled, hidden, view, limit, log_lvl })
|
||||
]);
|
||||
|
||||
promise = api.get_ae_obj_li_v3({
|
||||
// Merge and unique-ify by ID
|
||||
const merged = [...acct_users, ...global_users];
|
||||
const unique = Array.from(new Map(merged.map(u => [u.user_id_random, u])).values());
|
||||
return unique;
|
||||
}
|
||||
|
||||
// SCENARIO C: Global Only (no search string)
|
||||
if (!for_obj_id && include_global) {
|
||||
if (log_lvl) console.log('Strategy: Search API for Global Only');
|
||||
// Since for_obj_id is NULL in List API is tricky, use Search with a direct filter
|
||||
const search_query = {
|
||||
and: [{ field: 'account_id_random', op: 'eq', value: null }]
|
||||
};
|
||||
return await api.search_ae_obj_v3({
|
||||
api_cfg,
|
||||
obj_type: 'user',
|
||||
for_obj_type: for_obj_id ? for_obj_type : undefined,
|
||||
for_obj_id: for_obj_id || undefined,
|
||||
search_query,
|
||||
enabled,
|
||||
hidden,
|
||||
view,
|
||||
order_by_li,
|
||||
limit,
|
||||
offset,
|
||||
order_by_li,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
|
||||
ae_promises.load__user_obj_li = await promise.then(async function (result_li) {
|
||||
if (result_li) {
|
||||
if (try_cache) {
|
||||
const processed_obj_li = await process_ae_obj__user_props({
|
||||
obj_li: result_li,
|
||||
log_lvl
|
||||
});
|
||||
await db_save_ae_obj_li__ae_obj({
|
||||
db_instance: db_core,
|
||||
table_name: 'user',
|
||||
obj_li: processed_obj_li,
|
||||
properties_to_save: properties_to_save,
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
return result_li;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
// SCENARIO D: Account Only or Everything (confirmed working List API)
|
||||
if (log_lvl) console.log(`Strategy: Standard List API (for_obj_id=${for_obj_id})`);
|
||||
return await api.get_ae_obj_li_v3({
|
||||
api_cfg,
|
||||
obj_type: 'user',
|
||||
for_obj_type: for_obj_id ? for_obj_type : undefined,
|
||||
for_obj_id: for_obj_id || undefined,
|
||||
enabled,
|
||||
hidden,
|
||||
view,
|
||||
limit,
|
||||
offset,
|
||||
order_by_li,
|
||||
log_lvl
|
||||
});
|
||||
|
||||
return ae_promises.load__user_obj_li;
|
||||
}
|
||||
|
||||
// Updated 2026-01-06
|
||||
@@ -733,4 +701,4 @@ export async function process_ae_obj__user_props({
|
||||
obj_type: 'user',
|
||||
log_lvl
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user