Skip to content

Commit 5089915

Browse files
committed
Refactoring Microsoft Teams code to reliably check for external users and label them without Global Admin permissions.
1 parent 8775f9c commit 5089915

File tree

1 file changed

+52
-68
lines changed

1 file changed

+52
-68
lines changed

components/microsoft_teams/microsoft_teams.app.mjs

Lines changed: 52 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -58,76 +58,76 @@ export default {
5858
chat: {
5959
type: "string",
6060
label: "Chat",
61-
description: "Team Chat (internal and external contacts)",
62-
async options({ prevContext }) {
63-
const response = prevContext.nextLink
61+
description: "Select a chat (type to search by participant names)",
62+
async options({ prevContext, searchTerm }) {
63+
let path = "/chats?$expand=members";
64+
path += "&$top=20";
65+
66+
if (searchTerm) {
67+
path += `&$search="${searchTerm}"`;
68+
}
69+
70+
const response = prevContext?.nextLink
6471
? await this.makeRequest({
6572
path: prevContext.nextLink,
6673
})
67-
: await this.listChats();
68-
69-
const myTenantId = await this.getAuthenticatedUserTenant();
70-
const options = [];
71-
74+
: await this.makeRequest({
75+
path,
76+
});
77+
7278
this._userCache = this._userCache || new Map();
73-
79+
const options = [];
80+
7481
for (const chat of response.value) {
75-
const messages = await this.makeRequest({
76-
path: `/chats/${chat.id}/messages?$top=50`,
77-
});
78-
79-
const members = await Promise.all(chat.members.map(async (member) => {
80-
const cacheKey = `user_${member.userId}`;
81-
let displayName = member.displayName || this._userCache.get(cacheKey);
82-
83-
if (!displayName) {
84-
try {
85-
if (messages?.value?.length > 0) {
86-
const userMessage = messages.value.find((msg) =>
87-
msg.from?.user?.id === member.userId);
88-
if (userMessage?.from?.user?.displayName) {
89-
displayName = userMessage.from.user.displayName;
90-
}
91-
}
92-
93-
if (!displayName) {
94-
const userDetails = await this.makeRequest({
95-
path: `/users/${member.userId}`,
96-
});
97-
displayName = userDetails.displayName;
98-
}
99-
100-
this._userCache.set(cacheKey, displayName);
101-
} catch (err) {
102-
if (err.statusCode === 404) {
103-
displayName = "User Not Found";
104-
} else if (err.statusCode === 403) {
105-
displayName = "Access Denied";
106-
} else {
107-
displayName = "Unknown User";
82+
let members = chat.members.map(member => ({
83+
displayName: member.displayName,
84+
wasNull: !member.displayName,
85+
userId: member.userId,
86+
email: member.email
87+
}));
88+
89+
if (members.some(member => !member.displayName)) {
90+
try {
91+
const messages = await this.makeRequest({
92+
path: `/chats/${chat.id}/messages?$top=10&$orderby=createdDateTime desc`,
93+
});
94+
95+
const nameMap = new Map();
96+
messages.value.forEach(msg => {
97+
if (msg.from?.user?.id && msg.from?.user?.displayName) {
98+
nameMap.set(msg.from.user.id, msg.from.user.displayName);
10899
}
109-
console.error(`Failed to fetch user details for ${member.userId}:`, err);
110-
}
100+
});
101+
102+
members = members.map(member => ({
103+
...member,
104+
displayName: member.displayName || nameMap.get(member.userId) || member.email || "Unknown User",
105+
}));
106+
} catch (err) {
107+
console.error(`Failed to fetch messages for chat ${chat.id}:`, err);
111108
}
112-
113-
const isExternal = member.tenantId !== myTenantId || !member.tenantId;
114-
return isExternal
115-
? `${displayName} (External)`
116-
: displayName;
117-
}));
118-
109+
}
110+
111+
const memberNames = members.map(member =>
112+
member.wasNull
113+
? `${member.displayName} (External)`
114+
: member.displayName
115+
);
116+
119117
options.push({
120-
label: members.join(", "),
118+
label: memberNames.join(", "),
121119
value: chat.id,
122120
});
123121
}
122+
124123
return {
125124
options,
126125
context: {
127126
nextLink: response["@odata.nextLink"],
128127
},
129128
};
130129
},
130+
useQuery: true,
131131
},
132132
channelDisplayName: {
133133
type: "string",
@@ -192,22 +192,6 @@ export default {
192192
: reduction;
193193
}, api);
194194
},
195-
async getAuthenticatedUserTenant() {
196-
try {
197-
const { value } = await this.client()
198-
.api("/organization")
199-
.get();
200-
201-
if (!value || value.length === 0) {
202-
throw new Error("No organization found");
203-
}
204-
205-
return value[0].id;
206-
} catch (error) {
207-
console.error("Failed to fetch tenant ID:", error);
208-
throw new Error("Unable to determine tenant ID");
209-
}
210-
},
211195
async authenticatedUserId() {
212196
const { id } = await this.client()
213197
.api("/me")

0 commit comments

Comments
 (0)