@chat-adapter/teams 4.16.0 → 4.17.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 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: string;
82
- /** Microsoft App Password */
83
- appPassword: string;
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
- /** Logger instance for error reporting */
89
- logger: Logger;
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: TeamsAdapterConfig);
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?: Partial<TeamsAdapterConfig>): TeamsAdapter;
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 { ClientSecretCredential } from "@azure/identity";
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,
@@ -3820,7 +3828,6 @@ import {
3820
3828
  isEmphasisNode,
3821
3829
  isInlineCodeNode,
3822
3830
  isLinkNode,
3823
- isListItemNode,
3824
3831
  isListNode,
3825
3832
  isParagraphNode,
3826
3833
  isStrongNode,
@@ -3922,14 +3929,7 @@ ${node.value}
3922
3929
  return getNodeChildren(node).map((child) => `> ${this.nodeToTeams(child)}`).join("\n");
3923
3930
  }
3924
3931
  if (isListNode(node)) {
3925
- return getNodeChildren(node).map((item, i) => {
3926
- const prefix = node.ordered ? `${i + 1}.` : "-";
3927
- const content = getNodeChildren(item).map((child) => this.nodeToTeams(child)).join("");
3928
- return `${prefix} ${content}`;
3929
- }).join("\n");
3930
- }
3931
- if (isListItemNode(node)) {
3932
- return getNodeChildren(node).map((child) => this.nodeToTeams(child)).join("");
3932
+ return this.renderList(node, 0, (child) => this.nodeToTeams(child));
3933
3933
  }
3934
3934
  if (node.type === "break") {
3935
3935
  return "\n";
@@ -3989,31 +3989,110 @@ var TeamsAdapter = class {
3989
3989
  logger;
3990
3990
  formatConverter = new TeamsFormatConverter();
3991
3991
  config;
3992
- constructor(config) {
3993
- this.config = config;
3994
- this.logger = config.logger;
3992
+ constructor(config = {}) {
3993
+ const appId = config.appId ?? process.env.TEAMS_APP_ID;
3994
+ if (!appId) {
3995
+ throw new ValidationError(
3996
+ "teams",
3997
+ "appId is required. Set TEAMS_APP_ID or provide it in config."
3998
+ );
3999
+ }
4000
+ const hasExplicitAuth = config.appPassword || config.certificate || config.federated;
4001
+ const appPassword = hasExplicitAuth ? config.appPassword : config.appPassword ?? process.env.TEAMS_APP_PASSWORD;
4002
+ const appTenantId = config.appTenantId ?? process.env.TEAMS_APP_TENANT_ID;
4003
+ this.config = {
4004
+ ...config,
4005
+ appId,
4006
+ appPassword,
4007
+ appTenantId
4008
+ };
4009
+ this.logger = config.logger ?? new ConsoleLogger("info").child("teams");
3995
4010
  this.userName = config.userName || "bot";
3996
- if (config.appType === "SingleTenant" && !config.appTenantId) {
4011
+ const authMethodCount = [
4012
+ appPassword,
4013
+ config.certificate,
4014
+ config.federated
4015
+ ].filter(Boolean).length;
4016
+ if (authMethodCount === 0) {
4017
+ throw new ValidationError(
4018
+ "teams",
4019
+ "One of appPassword, certificate, or federated must be provided"
4020
+ );
4021
+ }
4022
+ if (authMethodCount > 1) {
4023
+ throw new ValidationError(
4024
+ "teams",
4025
+ "Only one of appPassword, certificate, or federated can be provided"
4026
+ );
4027
+ }
4028
+ if (config.appType === "SingleTenant" && !appTenantId) {
3997
4029
  throw new ValidationError(
3998
4030
  "teams",
3999
4031
  "appTenantId is required for SingleTenant app type"
4000
4032
  );
4001
4033
  }
4002
- const auth = new ConfigurationBotFrameworkAuthentication({
4003
- MicrosoftAppId: config.appId,
4004
- MicrosoftAppPassword: config.appPassword,
4034
+ const botFrameworkConfig = {
4035
+ MicrosoftAppId: appId,
4005
4036
  MicrosoftAppType: config.appType || "MultiTenant",
4006
- MicrosoftAppTenantId: config.appType === "SingleTenant" ? config.appTenantId : void 0
4007
- });
4008
- this.botAdapter = new ServerlessCloudAdapter(auth);
4009
- if (config.appTenantId) {
4010
- const credential = new ClientSecretCredential(
4011
- config.appTenantId,
4012
- config.appId,
4013
- config.appPassword
4037
+ MicrosoftAppTenantId: config.appType === "SingleTenant" ? appTenantId : void 0
4038
+ };
4039
+ let credentialsFactory;
4040
+ let graphCredential;
4041
+ if (config.certificate) {
4042
+ const { certificatePrivateKey, certificateThumbprint, x5c } = config.certificate;
4043
+ if (x5c) {
4044
+ credentialsFactory = new CertificateServiceClientCredentialsFactory(
4045
+ appId,
4046
+ x5c,
4047
+ certificatePrivateKey,
4048
+ appTenantId
4049
+ );
4050
+ } else if (certificateThumbprint) {
4051
+ credentialsFactory = new CertificateServiceClientCredentialsFactory(
4052
+ appId,
4053
+ certificateThumbprint,
4054
+ certificatePrivateKey,
4055
+ appTenantId
4056
+ );
4057
+ } else {
4058
+ throw new ValidationError(
4059
+ "teams",
4060
+ "Certificate auth requires either certificateThumbprint or x5c"
4061
+ );
4062
+ }
4063
+ if (appTenantId) {
4064
+ graphCredential = new ClientCertificateCredential(appTenantId, appId, {
4065
+ certificate: certificatePrivateKey
4066
+ });
4067
+ }
4068
+ } else if (config.federated) {
4069
+ credentialsFactory = new FederatedServiceClientCredentialsFactory(
4070
+ appId,
4071
+ config.federated.clientId,
4072
+ appTenantId,
4073
+ config.federated.clientAudience
4014
4074
  );
4075
+ if (appTenantId) {
4076
+ graphCredential = new DefaultAzureCredential();
4077
+ }
4078
+ } else if (appPassword && appTenantId) {
4079
+ graphCredential = new ClientSecretCredential(
4080
+ appTenantId,
4081
+ appId,
4082
+ appPassword
4083
+ );
4084
+ }
4085
+ const auth = new ConfigurationBotFrameworkAuthentication(
4086
+ {
4087
+ ...botFrameworkConfig,
4088
+ ...appPassword ? { MicrosoftAppPassword: appPassword } : {}
4089
+ },
4090
+ credentialsFactory
4091
+ );
4092
+ this.botAdapter = new ServerlessCloudAdapter(auth);
4093
+ if (graphCredential) {
4015
4094
  const authProvider = new import_azureTokenCredentials.TokenCredentialAuthenticationProvider(
4016
- credential,
4095
+ graphCredential,
4017
4096
  {
4018
4097
  scopes: ["https://graph.microsoft.com/.default"]
4019
4098
  }
@@ -5597,29 +5676,7 @@ var TeamsAdapter = class {
5597
5676
  }
5598
5677
  };
5599
5678
  function createTeamsAdapter(config) {
5600
- const appId = config?.appId ?? process.env.TEAMS_APP_ID;
5601
- if (!appId) {
5602
- throw new ValidationError(
5603
- "teams",
5604
- "appId is required. Set TEAMS_APP_ID or provide it in config."
5605
- );
5606
- }
5607
- const appPassword = config?.appPassword ?? process.env.TEAMS_APP_PASSWORD;
5608
- if (!appPassword) {
5609
- throw new ValidationError(
5610
- "teams",
5611
- "appPassword is required. Set TEAMS_APP_PASSWORD or provide it in config."
5612
- );
5613
- }
5614
- const resolved = {
5615
- appId,
5616
- appPassword,
5617
- appTenantId: config?.appTenantId ?? process.env.TEAMS_APP_TENANT_ID,
5618
- appType: config?.appType,
5619
- logger: config?.logger ?? new ConsoleLogger("info").child("teams"),
5620
- userName: config?.userName
5621
- };
5622
- return new TeamsAdapter(resolved);
5679
+ return new TeamsAdapter(config ?? {});
5623
5680
  }
5624
5681
  export {
5625
5682
  TeamsAdapter,