Files
openclaw/extensions/msteams/src/graph-users.ts
Josh Avant fbd330b7aa fix(channels): honor configured read target policies (#99905)
* fix(channels): enforce configured read targets

* test(channels): align policy checks with boundaries

* fix: bind channel reads to trusted turn context

* test: satisfy gateway lint

* fix: narrow message action channel imports

* fix(feishu): authorize message reads before provider access

* fix(slack): await reaction clear authorization

* fix(channels): align provider action contracts

* fix(matrix): read direct-room account data before sync

* fix(channels): reject unsupported attachment actions early

* fix: restore trusted operator conversation reads

* fix(matrix): authorize pin actions before provider reads

* fix: preserve trusted channel read workflows

* fix(discord): resolve current channel ids consistently

* fix(agents): preserve message action turn capability

* fix(plugins): enforce host-owned read provenance

* fix(channels): harden Teams and Discord read policy

* fix(channels): preserve exact-current action compatibility

* fix(imessage): authorize trusted current chat aliases

* fix(channels): preserve normalized current aliases

* fix(channels): preserve external current target aliases

* fix: reconcile channel policy with current main

* fix(discord): isolate DM read policy

* fix(channels): enforce provider read gates

* fix(gateway): await serialized message action identity tokens

* fix(ci): refresh channel protocol contracts
2026-07-10 22:29:37 -05:00

56 lines
1.8 KiB
TypeScript

// Msteams plugin module implements graph users behavior.
import {
escapeOData,
fetchAllGraphPages,
fetchGraphJson,
type GraphResponse,
type GraphUser,
type PaginatedResult,
} from "./graph.js";
export async function searchGraphUsers(params: {
token: string;
query: string;
top?: number;
}): Promise<GraphUser[]> {
const query = params.query.trim();
if (!query) {
return [];
}
if (query.includes("@")) {
const escaped = escapeOData(query);
const filter = `(mail eq '${escaped}' or userPrincipalName eq '${escaped}')`;
const path = `/users?$filter=${encodeURIComponent(filter)}&$select=id,displayName,mail,userPrincipalName`;
const res = await fetchGraphJson<GraphResponse<GraphUser>>({ token: params.token, path });
return res.value ?? [];
}
const top = typeof params.top === "number" && params.top > 0 ? params.top : 10;
const path = `/users?$search=${encodeURIComponent(`"displayName:${query}"`)}&$select=id,displayName,mail,userPrincipalName&$top=${top}`;
const res = await fetchGraphJson<GraphResponse<GraphUser>>({
token: params.token,
path,
headers: { ConsistencyLevel: "eventual" },
});
return res.value ?? [];
}
export async function findGraphUsersByExactIdentity(params: {
token: string;
query: string;
}): Promise<PaginatedResult<GraphUser>> {
const query = params.query.trim();
if (!query) {
return { items: [], truncated: false };
}
const escaped = escapeOData(query);
const filter =
`(displayName eq '${escaped}' or mail eq '${escaped}' or ` +
`userPrincipalName eq '${escaped}')`;
const path =
`/users?$filter=${encodeURIComponent(filter)}` +
"&$select=id,displayName,mail,userPrincipalName";
return await fetchAllGraphPages<GraphUser>({ token: params.token, path });
}