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;
|
try_cache?: boolean;
|
||||||
log_lvl?: number;
|
log_lvl?: number;
|
||||||
}): Promise<ae_User[]> {
|
}): 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
|
// SCENARIO A: Text Search
|
||||||
const use_search = qry_str || (for_obj_id && include_global) || (!for_obj_id && include_global);
|
if (qry_str) {
|
||||||
|
const search_query: any = { q: qry_str, and: [] };
|
||||||
if (use_search) {
|
|
||||||
const search_query: any = { and: [] };
|
|
||||||
|
|
||||||
if (qry_str) {
|
|
||||||
search_query.q = qry_str;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle Account Scoping in Search Query
|
|
||||||
if (for_obj_id && include_global) {
|
if (for_obj_id && include_global) {
|
||||||
// Case: (Account == current OR Account == null)
|
|
||||||
search_query.and.push({
|
search_query.and.push({
|
||||||
or: [
|
or: [
|
||||||
{
|
{ field: `account_id_random`, op: 'eq', value: for_obj_id },
|
||||||
field: `account_id_random`,
|
{ field: `account_id_random`, op: 'eq', value: null }
|
||||||
op: 'eq',
|
|
||||||
value: for_obj_id
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: `account_id_random`,
|
|
||||||
op: 'eq', // Use 'eq' with null, as 'is' was unsupported
|
|
||||||
value: null
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
} else if (for_obj_id) {
|
} 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) {
|
} else if (include_global) {
|
||||||
// Case: Global Only (No Account)
|
search_query.and.push({ field: `account_id_random`, op: 'eq', value: null });
|
||||||
search_query.and.push({
|
|
||||||
field: `account_id_random`,
|
|
||||||
op: 'eq', // Use 'eq' with null
|
|
||||||
value: null
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enabled === 'enabled') {
|
return await api.search_ae_obj_v3({
|
||||||
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({
|
|
||||||
api_cfg,
|
api_cfg,
|
||||||
obj_type: 'user',
|
obj_type: 'user',
|
||||||
search_query,
|
search_query,
|
||||||
@@ -165,49 +124,58 @@ export async function load_ae_obj_li__user({
|
|||||||
offset,
|
offset,
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
} else {
|
}
|
||||||
// Simple case: Standard List API (Account Only or No Filter)
|
|
||||||
if (log_lvl) {
|
// SCENARIO B: Multi-Scope (Account + Global) with no search string
|
||||||
console.log(`load_ae_obj_li__user() - Using List API (for_obj_id=${for_obj_id})`);
|
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,
|
api_cfg,
|
||||||
obj_type: 'user',
|
obj_type: 'user',
|
||||||
for_obj_type: for_obj_id ? for_obj_type : undefined,
|
search_query,
|
||||||
for_obj_id: for_obj_id || undefined,
|
|
||||||
enabled,
|
enabled,
|
||||||
hidden,
|
hidden,
|
||||||
view,
|
view,
|
||||||
|
order_by_li,
|
||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
order_by_li,
|
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ae_promises.load__user_obj_li = await promise.then(async function (result_li) {
|
// SCENARIO D: Account Only or Everything (confirmed working List API)
|
||||||
if (result_li) {
|
if (log_lvl) console.log(`Strategy: Standard List API (for_obj_id=${for_obj_id})`);
|
||||||
if (try_cache) {
|
return await api.get_ae_obj_li_v3({
|
||||||
const processed_obj_li = await process_ae_obj__user_props({
|
api_cfg,
|
||||||
obj_li: result_li,
|
obj_type: 'user',
|
||||||
log_lvl
|
for_obj_type: for_obj_id ? for_obj_type : undefined,
|
||||||
});
|
for_obj_id: for_obj_id || undefined,
|
||||||
await db_save_ae_obj_li__ae_obj({
|
enabled,
|
||||||
db_instance: db_core,
|
hidden,
|
||||||
table_name: 'user',
|
view,
|
||||||
obj_li: processed_obj_li,
|
limit,
|
||||||
properties_to_save: properties_to_save,
|
offset,
|
||||||
log_lvl
|
order_by_li,
|
||||||
});
|
log_lvl
|
||||||
}
|
|
||||||
return result_li;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return ae_promises.load__user_obj_li;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updated 2026-01-06
|
// Updated 2026-01-06
|
||||||
@@ -733,4 +701,4 @@ export async function process_ae_obj__user_props({
|
|||||||
obj_type: 'user',
|
obj_type: 'user',
|
||||||
log_lvl
|
log_lvl
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user