@chat-adapter/teams 4.16.1 → 4.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +30 -10
- package/dist/index.js +128 -43
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -76,17 +76,37 @@ declare class TeamsFormatConverter extends BaseFormatConverter {
|
|
|
76
76
|
private tableToGfm;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
/** Certificate-based authentication config */
|
|
80
|
+
interface TeamsAuthCertificate {
|
|
81
|
+
/** PEM-encoded certificate private key */
|
|
82
|
+
certificatePrivateKey: string;
|
|
83
|
+
/** Hex-encoded certificate thumbprint (optional when x5c is provided) */
|
|
84
|
+
certificateThumbprint?: string;
|
|
85
|
+
/** Public certificate for subject-name validation (optional) */
|
|
86
|
+
x5c?: string;
|
|
87
|
+
}
|
|
88
|
+
/** Federated (workload identity) authentication config */
|
|
89
|
+
interface TeamsAuthFederated {
|
|
90
|
+
/** Audience for the federated credential (defaults to api://AzureADTokenExchange) */
|
|
91
|
+
clientAudience?: string;
|
|
92
|
+
/** Client ID for the managed identity assigned to the bot */
|
|
93
|
+
clientId: string;
|
|
94
|
+
}
|
|
79
95
|
interface TeamsAdapterConfig {
|
|
80
|
-
/** Microsoft App ID */
|
|
81
|
-
appId
|
|
82
|
-
/** Microsoft App Password */
|
|
83
|
-
appPassword
|
|
84
|
-
/** Microsoft App Tenant ID */
|
|
96
|
+
/** Microsoft App ID. Defaults to TEAMS_APP_ID env var. */
|
|
97
|
+
appId?: string;
|
|
98
|
+
/** Microsoft App Password. Defaults to TEAMS_APP_PASSWORD env var. */
|
|
99
|
+
appPassword?: string;
|
|
100
|
+
/** Microsoft App Tenant ID. Defaults to TEAMS_APP_TENANT_ID env var. */
|
|
85
101
|
appTenantId?: string;
|
|
86
102
|
/** Microsoft App Type */
|
|
87
103
|
appType?: "MultiTenant" | "SingleTenant";
|
|
88
|
-
/**
|
|
89
|
-
|
|
104
|
+
/** Certificate-based authentication */
|
|
105
|
+
certificate?: TeamsAuthCertificate;
|
|
106
|
+
/** Federated (workload identity) authentication */
|
|
107
|
+
federated?: TeamsAuthFederated;
|
|
108
|
+
/** Logger instance for error reporting. Defaults to ConsoleLogger. */
|
|
109
|
+
logger?: Logger;
|
|
90
110
|
/** Override bot username (optional) */
|
|
91
111
|
userName?: string;
|
|
92
112
|
}
|
|
@@ -106,7 +126,7 @@ declare class TeamsAdapter implements Adapter<TeamsThreadId, unknown> {
|
|
|
106
126
|
private readonly logger;
|
|
107
127
|
private readonly formatConverter;
|
|
108
128
|
private readonly config;
|
|
109
|
-
constructor(config
|
|
129
|
+
constructor(config?: TeamsAdapterConfig);
|
|
110
130
|
initialize(chat: ChatInstance): Promise<void>;
|
|
111
131
|
handleWebhook(request: Request, options?: WebhookOptions): Promise<Response>;
|
|
112
132
|
private handleTurn;
|
|
@@ -225,6 +245,6 @@ declare class TeamsAdapter implements Adapter<TeamsThreadId, unknown> {
|
|
|
225
245
|
*/
|
|
226
246
|
private handleTeamsError;
|
|
227
247
|
}
|
|
228
|
-
declare function createTeamsAdapter(config?:
|
|
248
|
+
declare function createTeamsAdapter(config?: TeamsAdapterConfig): TeamsAdapter;
|
|
229
249
|
|
|
230
|
-
export { TeamsAdapter, type TeamsAdapterConfig, TeamsFormatConverter, type TeamsThreadId, cardToAdaptiveCard, cardToFallbackText, createTeamsAdapter };
|
|
250
|
+
export { TeamsAdapter, type TeamsAdapterConfig, type TeamsAuthCertificate, type TeamsAuthFederated, TeamsFormatConverter, type TeamsThreadId, cardToAdaptiveCard, cardToFallbackText, createTeamsAdapter };
|
package/dist/index.js
CHANGED
|
@@ -671,7 +671,11 @@ var require_azureTokenCredentials = __commonJS({
|
|
|
671
671
|
});
|
|
672
672
|
|
|
673
673
|
// src/index.ts
|
|
674
|
-
import {
|
|
674
|
+
import {
|
|
675
|
+
ClientCertificateCredential,
|
|
676
|
+
ClientSecretCredential,
|
|
677
|
+
DefaultAzureCredential
|
|
678
|
+
} from "@azure/identity";
|
|
675
679
|
|
|
676
680
|
// ../../node_modules/.pnpm/@microsoft+microsoft-graph-client@3.0.7_@azure+identity@4.13.0/node_modules/@microsoft/microsoft-graph-client/lib/es/src/content/BatchRequestContent.js
|
|
677
681
|
init_tslib_es6();
|
|
@@ -3563,6 +3567,10 @@ import {
|
|
|
3563
3567
|
ConfigurationBotFrameworkAuthentication,
|
|
3564
3568
|
TeamsInfo
|
|
3565
3569
|
} from "botbuilder";
|
|
3570
|
+
import {
|
|
3571
|
+
CertificateServiceClientCredentialsFactory,
|
|
3572
|
+
FederatedServiceClientCredentialsFactory
|
|
3573
|
+
} from "botframework-connector";
|
|
3566
3574
|
import {
|
|
3567
3575
|
AdapterRateLimitError,
|
|
3568
3576
|
AuthenticationError,
|
|
@@ -3882,8 +3890,22 @@ var TeamsFormatConverter = class extends BaseFormatConverter {
|
|
|
3882
3890
|
);
|
|
3883
3891
|
markdown = markdown.replace(/<code>([^<]+)<\/code>/gi, "`$1`");
|
|
3884
3892
|
markdown = markdown.replace(/<pre>([^<]+)<\/pre>/gi, "```\n$1\n```");
|
|
3885
|
-
|
|
3886
|
-
|
|
3893
|
+
let prev;
|
|
3894
|
+
do {
|
|
3895
|
+
prev = markdown;
|
|
3896
|
+
markdown = markdown.replace(/<[^>]+>/g, "");
|
|
3897
|
+
} while (markdown !== prev);
|
|
3898
|
+
const entityMap = {
|
|
3899
|
+
"<": "<",
|
|
3900
|
+
">": ">",
|
|
3901
|
+
"&": "&",
|
|
3902
|
+
""": '"',
|
|
3903
|
+
"'": "'"
|
|
3904
|
+
};
|
|
3905
|
+
markdown = markdown.replace(
|
|
3906
|
+
/&(?:lt|gt|amp|quot|#39);/g,
|
|
3907
|
+
(match) => entityMap[match] ?? match
|
|
3908
|
+
);
|
|
3887
3909
|
return parseMarkdown(markdown);
|
|
3888
3910
|
}
|
|
3889
3911
|
nodeToTeams(node) {
|
|
@@ -3981,31 +4003,110 @@ var TeamsAdapter = class {
|
|
|
3981
4003
|
logger;
|
|
3982
4004
|
formatConverter = new TeamsFormatConverter();
|
|
3983
4005
|
config;
|
|
3984
|
-
constructor(config) {
|
|
3985
|
-
|
|
3986
|
-
|
|
4006
|
+
constructor(config = {}) {
|
|
4007
|
+
const appId = config.appId ?? process.env.TEAMS_APP_ID;
|
|
4008
|
+
if (!appId) {
|
|
4009
|
+
throw new ValidationError(
|
|
4010
|
+
"teams",
|
|
4011
|
+
"appId is required. Set TEAMS_APP_ID or provide it in config."
|
|
4012
|
+
);
|
|
4013
|
+
}
|
|
4014
|
+
const hasExplicitAuth = config.appPassword || config.certificate || config.federated;
|
|
4015
|
+
const appPassword = hasExplicitAuth ? config.appPassword : config.appPassword ?? process.env.TEAMS_APP_PASSWORD;
|
|
4016
|
+
const appTenantId = config.appTenantId ?? process.env.TEAMS_APP_TENANT_ID;
|
|
4017
|
+
this.config = {
|
|
4018
|
+
...config,
|
|
4019
|
+
appId,
|
|
4020
|
+
appPassword,
|
|
4021
|
+
appTenantId
|
|
4022
|
+
};
|
|
4023
|
+
this.logger = config.logger ?? new ConsoleLogger("info").child("teams");
|
|
3987
4024
|
this.userName = config.userName || "bot";
|
|
3988
|
-
|
|
4025
|
+
const authMethodCount = [
|
|
4026
|
+
appPassword,
|
|
4027
|
+
config.certificate,
|
|
4028
|
+
config.federated
|
|
4029
|
+
].filter(Boolean).length;
|
|
4030
|
+
if (authMethodCount === 0) {
|
|
4031
|
+
throw new ValidationError(
|
|
4032
|
+
"teams",
|
|
4033
|
+
"One of appPassword, certificate, or federated must be provided"
|
|
4034
|
+
);
|
|
4035
|
+
}
|
|
4036
|
+
if (authMethodCount > 1) {
|
|
4037
|
+
throw new ValidationError(
|
|
4038
|
+
"teams",
|
|
4039
|
+
"Only one of appPassword, certificate, or federated can be provided"
|
|
4040
|
+
);
|
|
4041
|
+
}
|
|
4042
|
+
if (config.appType === "SingleTenant" && !appTenantId) {
|
|
3989
4043
|
throw new ValidationError(
|
|
3990
4044
|
"teams",
|
|
3991
4045
|
"appTenantId is required for SingleTenant app type"
|
|
3992
4046
|
);
|
|
3993
4047
|
}
|
|
3994
|
-
const
|
|
3995
|
-
MicrosoftAppId:
|
|
3996
|
-
MicrosoftAppPassword: config.appPassword,
|
|
4048
|
+
const botFrameworkConfig = {
|
|
4049
|
+
MicrosoftAppId: appId,
|
|
3997
4050
|
MicrosoftAppType: config.appType || "MultiTenant",
|
|
3998
|
-
MicrosoftAppTenantId: config.appType === "SingleTenant" ?
|
|
3999
|
-
}
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4051
|
+
MicrosoftAppTenantId: config.appType === "SingleTenant" ? appTenantId : void 0
|
|
4052
|
+
};
|
|
4053
|
+
let credentialsFactory;
|
|
4054
|
+
let graphCredential;
|
|
4055
|
+
if (config.certificate) {
|
|
4056
|
+
const { certificatePrivateKey, certificateThumbprint, x5c } = config.certificate;
|
|
4057
|
+
if (x5c) {
|
|
4058
|
+
credentialsFactory = new CertificateServiceClientCredentialsFactory(
|
|
4059
|
+
appId,
|
|
4060
|
+
x5c,
|
|
4061
|
+
certificatePrivateKey,
|
|
4062
|
+
appTenantId
|
|
4063
|
+
);
|
|
4064
|
+
} else if (certificateThumbprint) {
|
|
4065
|
+
credentialsFactory = new CertificateServiceClientCredentialsFactory(
|
|
4066
|
+
appId,
|
|
4067
|
+
certificateThumbprint,
|
|
4068
|
+
certificatePrivateKey,
|
|
4069
|
+
appTenantId
|
|
4070
|
+
);
|
|
4071
|
+
} else {
|
|
4072
|
+
throw new ValidationError(
|
|
4073
|
+
"teams",
|
|
4074
|
+
"Certificate auth requires either certificateThumbprint or x5c"
|
|
4075
|
+
);
|
|
4076
|
+
}
|
|
4077
|
+
if (appTenantId) {
|
|
4078
|
+
graphCredential = new ClientCertificateCredential(appTenantId, appId, {
|
|
4079
|
+
certificate: certificatePrivateKey
|
|
4080
|
+
});
|
|
4081
|
+
}
|
|
4082
|
+
} else if (config.federated) {
|
|
4083
|
+
credentialsFactory = new FederatedServiceClientCredentialsFactory(
|
|
4084
|
+
appId,
|
|
4085
|
+
config.federated.clientId,
|
|
4086
|
+
appTenantId,
|
|
4087
|
+
config.federated.clientAudience
|
|
4088
|
+
);
|
|
4089
|
+
if (appTenantId) {
|
|
4090
|
+
graphCredential = new DefaultAzureCredential();
|
|
4091
|
+
}
|
|
4092
|
+
} else if (appPassword && appTenantId) {
|
|
4093
|
+
graphCredential = new ClientSecretCredential(
|
|
4094
|
+
appTenantId,
|
|
4095
|
+
appId,
|
|
4096
|
+
appPassword
|
|
4006
4097
|
);
|
|
4098
|
+
}
|
|
4099
|
+
const auth = new ConfigurationBotFrameworkAuthentication(
|
|
4100
|
+
{
|
|
4101
|
+
...botFrameworkConfig,
|
|
4102
|
+
...appPassword ? { MicrosoftAppPassword: appPassword } : {}
|
|
4103
|
+
},
|
|
4104
|
+
credentialsFactory
|
|
4105
|
+
);
|
|
4106
|
+
this.botAdapter = new ServerlessCloudAdapter(auth);
|
|
4107
|
+
if (graphCredential) {
|
|
4007
4108
|
const authProvider = new import_azureTokenCredentials.TokenCredentialAuthenticationProvider(
|
|
4008
|
-
|
|
4109
|
+
graphCredential,
|
|
4009
4110
|
{
|
|
4010
4111
|
scopes: ["https://graph.microsoft.com/.default"]
|
|
4011
4112
|
}
|
|
@@ -5000,7 +5101,13 @@ var TeamsAdapter = class {
|
|
|
5000
5101
|
}
|
|
5001
5102
|
let text = "";
|
|
5002
5103
|
if (msg.body?.content) {
|
|
5003
|
-
|
|
5104
|
+
let stripped = msg.body.content;
|
|
5105
|
+
let prev;
|
|
5106
|
+
do {
|
|
5107
|
+
prev = stripped;
|
|
5108
|
+
stripped = stripped.replace(/<[^>]*>/g, "");
|
|
5109
|
+
} while (stripped !== prev);
|
|
5110
|
+
text = stripped.trim();
|
|
5004
5111
|
}
|
|
5005
5112
|
if (!text && msg.attachments?.length) {
|
|
5006
5113
|
for (const att of msg.attachments) {
|
|
@@ -5589,29 +5696,7 @@ var TeamsAdapter = class {
|
|
|
5589
5696
|
}
|
|
5590
5697
|
};
|
|
5591
5698
|
function createTeamsAdapter(config) {
|
|
5592
|
-
|
|
5593
|
-
if (!appId) {
|
|
5594
|
-
throw new ValidationError(
|
|
5595
|
-
"teams",
|
|
5596
|
-
"appId is required. Set TEAMS_APP_ID or provide it in config."
|
|
5597
|
-
);
|
|
5598
|
-
}
|
|
5599
|
-
const appPassword = config?.appPassword ?? process.env.TEAMS_APP_PASSWORD;
|
|
5600
|
-
if (!appPassword) {
|
|
5601
|
-
throw new ValidationError(
|
|
5602
|
-
"teams",
|
|
5603
|
-
"appPassword is required. Set TEAMS_APP_PASSWORD or provide it in config."
|
|
5604
|
-
);
|
|
5605
|
-
}
|
|
5606
|
-
const resolved = {
|
|
5607
|
-
appId,
|
|
5608
|
-
appPassword,
|
|
5609
|
-
appTenantId: config?.appTenantId ?? process.env.TEAMS_APP_TENANT_ID,
|
|
5610
|
-
appType: config?.appType,
|
|
5611
|
-
logger: config?.logger ?? new ConsoleLogger("info").child("teams"),
|
|
5612
|
-
userName: config?.userName
|
|
5613
|
-
};
|
|
5614
|
-
return new TeamsAdapter(resolved);
|
|
5699
|
+
return new TeamsAdapter(config ?? {});
|
|
5615
5700
|
}
|
|
5616
5701
|
export {
|
|
5617
5702
|
TeamsAdapter,
|