eionet2-dashboard 3.1.7 → 3.2.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.
Files changed (42) hide show
  1. package/.nvmrc +1 -0
  2. package/.vscode/launch.json +1 -0
  3. package/.vscode/settings.json +1 -2
  4. package/.vscode/tasks.json +1 -1
  5. package/CHANGELOG.md +14 -1
  6. package/Jenkinsfile +2 -2
  7. package/aad.manifest.json +118 -114
  8. package/api/extensions.csproj +1 -2
  9. package/api/getGraphData/function.json +1 -6
  10. package/api/getGraphData/index.js +62 -63
  11. package/api/host.json +1 -1
  12. package/api/package-lock.json +479 -1353
  13. package/api/package.json +8 -4
  14. package/env/.env.Prod_EEA +1 -1
  15. package/env/.env.dev +2 -1
  16. package/package.json +1 -1
  17. package/tabs/.env.teamsfx.dev +1 -0
  18. package/tabs/eslint.config.mjs +69 -0
  19. package/tabs/package-lock.json +21626 -13872
  20. package/tabs/package.json +58 -49
  21. package/tabs/public/auth-end.html +1 -1
  22. package/tabs/public/auth-start.html +3 -3
  23. package/tabs/src/components/App.jsx +38 -16
  24. package/tabs/src/components/Tab.jsx +8 -4
  25. package/tabs/src/components/Tab.scss +8 -8
  26. package/tabs/src/components/activity/activity.scss +8 -8
  27. package/tabs/src/components/lib/useTeamsAuth.js +87 -0
  28. package/tabs/src/components/my_country/my_country.scss +2 -2
  29. package/tabs/src/components/self_service/UserEdit.jsx +1 -1
  30. package/tabs/src/components/self_service/UserEdit.scss +5 -5
  31. package/tabs/src/data/apiProvider.js +23 -10
  32. package/tabs/src/data/provider.js +1 -1
  33. package/tabs/src/data/selfServiceSharepointProvider.js +1 -1
  34. package/tabs/src/data/sharepointProvider.js +1 -1
  35. package/tabs/src/index.css +0 -1
  36. package/tabs/src/index.jsx +8 -2
  37. package/tabs/yarn.lock +6453 -5770
  38. package/teamsapp.local.yml +10 -9
  39. package/teamsapp.yml +9 -9
  40. package/templates/azure/provision/function.bicep +16 -6
  41. package/tabs/src/components/lib/useGraph.js +0 -39
  42. package/tabs/src/components/lib/useTeamsFx.js +0 -55
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ 24
@@ -30,6 +30,7 @@
30
30
  "cascadeTerminateToConfigurations": [
31
31
  "Attach to Backend"
32
32
  ],
33
+ "runtimeExecutable": "/usr/bin/microsoft-edge",
33
34
  "presentation": {
34
35
  "group": "all",
35
36
  "hidden": true
@@ -2,5 +2,4 @@
2
2
  "debug.onTaskErrors": "abort",
3
3
  "azureFunctions.stopFuncTaskPostDebug": false,
4
4
  "azureFunctions.showProjectWarning": false,
5
- "csharp.suppressDotnetRestoreNotification": true
6
- }
5
+ }
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "args": {
23
23
  "prerequisites": [
24
- "nodejs", // Validate if Node.js is installed.
24
+ //"nodejs", // Validate if Node.js is installed.
25
25
  "m365Account", // Sign-in prompt for Microsoft 365 account, then validate if the account enables the sideloading permission.
26
26
  "portOccupancy" // Validate available ports to ensure those debug ones are not occupied.
27
27
  ],
package/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ ### [3.2.0](https://github.com/eea/eionet2-dashboard/compare/3.1.7...3.2.0) - 18 February 2026
8
+
9
+ #### :bug: Bug Fixes
10
+
11
+ - fix: email filtering( Refs #297435) [Mihai Nicolae - [`a0ea6d0`](https://github.com/eea/eionet2-dashboard/commit/a0ea6d014642868e3ac7cb2ef7462408b2d11bbd)]
12
+
13
+ #### :house: Internal changes
14
+
15
+ - chore: build fix [Mihai Nicolae - [`0e2ec2c`](https://github.com/eea/eionet2-dashboard/commit/0e2ec2c1ce3f8e92a4d89d8aef6ff0fcefb2c7c3)]
16
+ - chore: format [Mihai Nicolae - [`df7b3e5`](https://github.com/eea/eionet2-dashboard/commit/df7b3e54cf5c9bd97a2e87477259d7cebef126d3)]
17
+ - chore: formatting [Mihai Nicolae - [`e85e1cb`](https://github.com/eea/eionet2-dashboard/commit/e85e1cb927ac9adeaf4ae853dbb300f13cf6c75a)]
18
+ - chore: node build version [Mihai Nicolae - [`cc21733`](https://github.com/eea/eionet2-dashboard/commit/cc21733609aa8a6749ad1ba00424690c41d659ae)]
19
+ - chore: build fix [Mihai Nicolae - [`328bc71`](https://github.com/eea/eionet2-dashboard/commit/328bc71f4d3677d86b912e1d6f1e4d01f193f6c2)]
20
+
7
21
  ### [3.1.7](https://github.com/eea/eionet2-dashboard/compare/3.1.4...3.1.7) - 6 February 2026
8
22
 
9
23
  #### :rocket: New Features
@@ -20,7 +34,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
20
34
  #### :bug: Bug Fixes
21
35
 
22
36
  - fix: correct email filtering (Refs #297435) [Mihai Nicolae - [`469a593`](https://github.com/eea/eionet2-dashboard/commit/469a593e71bf153e5ecc6c7d022ffeeb0fe7284d)]
23
- - fix: send correct notification [Mihai Nicolae - [`2d422b9`](https://github.com/eea/eionet2-dashboard/commit/2d422b9defaf23bd430561fb65f86d2dcc7954b4)]
24
37
 
25
38
  #### :house: Internal changes
26
39
 
package/Jenkinsfile CHANGED
@@ -5,7 +5,7 @@ pipeline {
5
5
  environment {
6
6
  GIT_NAME = "eionet2-dashboard"
7
7
  SONARQUBE_TAGS = "eionet2"
8
- PATH = "${tool 'NodeJS16'}/bin:${tool 'SonarQubeScanner'}/bin:$PATH"
8
+ PATH = "${tool 'NodeJS24'}/bin:${tool 'SonarQubeScanner'}/bin:$PATH"
9
9
  }
10
10
  stages{
11
11
 
@@ -37,7 +37,7 @@ pipeline {
37
37
  steps {
38
38
  script{
39
39
  checkout scm
40
- tool 'NodeJS16'
40
+ tool 'NodeJS24'
41
41
  tool 'SonarQubeScanner'
42
42
  sh "cd tabs; yarn install"
43
43
  }
package/aad.manifest.json CHANGED
@@ -1,133 +1,137 @@
1
1
  {
2
- "id": "${{AAD_APP_OBJECT_ID}}",
3
- "appId": "${{AAD_APP_CLIENT_ID}}",
4
- "name": "${{CONFIG__MANIFEST__APPNAME__SHORT}}-aad",
5
- "accessTokenAcceptedVersion": 2,
6
- "signInAudience": "AzureADMyOrg",
7
- "optionalClaims": {
8
- "idToken": [],
9
- "accessToken": [
10
- {
11
- "name": "idtyp",
12
- "source": null,
13
- "essential": false,
14
- "additionalProperties": []
15
- }
16
- ],
17
- "saml2Token": []
18
- },
19
- "requiredResourceAccess": [
20
- {
21
- "resourceAppId": "Microsoft Graph",
22
- "resourceAccess": [
23
- {
24
- "id": "User.Read.All",
25
- "type": "Role"
26
- },
27
- {
28
- "id": "Sites.Read.All",
29
- "type": "Role"
30
- },
31
- {
32
- "id": "OnlineMeetings.Read.All",
33
- "type": "Role"
34
- },
35
- {
36
- "id": "User.Read",
37
- "type": "Scope"
38
- },
39
- {
40
- "id": "Mail.Send",
41
- "type": "Role"
42
- },
43
- {
44
- "id": "User.ReadWrite.All",
45
- "type": "Role"
46
- },
47
- {
48
- "id": "Sites.ReadWrite.All",
49
- "type": "Role"
50
- }
51
- ]
52
- }
53
- ],
54
- "oauth2Permissions": [
55
- {
56
- "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.",
57
- "adminConsentDisplayName": "Teams can access app's web APIs",
58
- "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}",
59
- "isEnabled": true,
60
- "type": "User",
61
- "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have",
62
- "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf",
63
- "value": "access_as_user"
64
- }
2
+ "id": "${{AAD_APP_OBJECT_ID}}",
3
+ "appId": "${{AAD_APP_CLIENT_ID}}",
4
+ "displayName": "${{CONFIG__MANIFEST__APPNAME__SHORT}}-aad",
5
+ "identifierUris": [
6
+ "api://${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__DOMAIN}}/${{AAD_APP_CLIENT_ID}}"
7
+ ],
8
+ "signInAudience": "AzureADMyOrg",
9
+ "api": {
10
+ "requestedAccessTokenVersion": 2,
11
+ "oauth2PermissionScopes": [
12
+ {
13
+ "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.",
14
+ "adminConsentDisplayName": "Teams can access app's web APIs",
15
+ "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}",
16
+ "isEnabled": true,
17
+ "type": "User",
18
+ "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have",
19
+ "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf",
20
+ "value": "access_as_user"
21
+ }
65
22
  ],
66
23
  "preAuthorizedApplications": [
24
+ {
25
+ "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
26
+ "delegatedPermissionIds": [
27
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
28
+ ]
29
+ },
30
+ {
31
+ "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346",
32
+ "delegatedPermissionIds": [
33
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
34
+ ]
35
+ },
36
+ {
37
+ "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c",
38
+ "delegatedPermissionIds": [
39
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
40
+ ]
41
+ },
42
+ {
43
+ "appId": "00000002-0000-0ff1-ce00-000000000000",
44
+ "delegatedPermissionIds": [
45
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
46
+ ]
47
+ },
48
+ {
49
+ "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3",
50
+ "delegatedPermissionIds": [
51
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
52
+ ]
53
+ },
54
+ {
55
+ "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c",
56
+ "delegatedPermissionIds": [
57
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
58
+ ]
59
+ },
60
+ {
61
+ "appId": "4765445b-32c6-49b0-83e6-1d93765276ca",
62
+ "delegatedPermissionIds": [
63
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
64
+ ]
65
+ },
66
+ {
67
+ "appId": "4345a7b9-9a63-4910-a426-35363201d503",
68
+ "delegatedPermissionIds": [
69
+ "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
70
+ ]
71
+ }
72
+ ]
73
+ },
74
+ "info": {},
75
+ "optionalClaims": {
76
+ "idToken": [],
77
+ "accessToken": [
78
+ {
79
+ "name": "idtyp",
80
+ "source": null,
81
+ "essential": false,
82
+ "additionalProperties": []
83
+ }
84
+ ],
85
+ "saml2Token": []
86
+ },
87
+ "publicClient": {
88
+ "redirectUris": []
89
+ },
90
+ "requiredResourceAccess": [
91
+ {
92
+ "resourceAppId": "00000003-0000-0000-c000-000000000000",
93
+ "resourceAccess": [
67
94
  {
68
- "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
69
- "permissionIds": [
70
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
71
- ]
72
- },
73
- {
74
- "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346",
75
- "permissionIds": [
76
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
77
- ]
95
+ "id": "df021288-bdef-4463-88db-98f22de89214",
96
+ "type": "Role"
78
97
  },
79
98
  {
80
- "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c",
81
- "permissionIds": [
82
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
83
- ]
99
+ "id": "332a536c-c7ef-4017-ab91-336970924f0d",
100
+ "type": "Role"
84
101
  },
85
102
  {
86
- "appId": "00000002-0000-0ff1-ce00-000000000000",
87
- "permissionIds": [
88
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
89
- ]
103
+ "id": "c1684f21-1984-47fa-9d61-2dc8c296bb70",
104
+ "type": "Role"
90
105
  },
91
106
  {
92
- "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3",
93
- "permissionIds": [
94
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
95
- ]
107
+ "id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
108
+ "type": "Scope"
96
109
  },
97
110
  {
98
- "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c",
99
- "permissionIds": [
100
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
101
- ]
111
+ "id": "b633e1c5-b582-4048-a93e-9f11b44c7e96",
112
+ "type": "Role"
102
113
  },
103
114
  {
104
- "appId": "4765445b-32c6-49b0-83e6-1d93765276ca",
105
- "permissionIds": [
106
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
107
- ]
115
+ "id": "741f803b-c850-494e-b5df-cde7c675a1ca",
116
+ "type": "Role"
108
117
  },
109
118
  {
110
- "appId": "4345a7b9-9a63-4910-a426-35363201d503",
111
- "permissionIds": [
112
- "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
113
- ]
119
+ "id": "9492366f-7969-46a4-8d15-ed1a20078fff",
120
+ "type": "Role"
114
121
  }
122
+ ]
123
+ }
124
+ ],
125
+ "web": {
126
+ "redirectUris": [
127
+ "${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__ENDPOINT}}/auth-end.html"
115
128
  ],
116
- "identifierUris": [
117
- "api://${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__DOMAIN}}/${{AAD_APP_CLIENT_ID}}"
118
- ],
119
- "replyUrlsWithType": [
120
- {
121
- "url": "${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__ENDPOINT}}/auth-end.html",
122
- "type": "Web"
123
- },
124
- {
125
- "url": "${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__ENDPOINT}}/auth-end.html?clientId=${{AAD_APP_CLIENT_ID}}",
126
- "type": "Spa"
127
- },
128
- {
129
- "url": "${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__ENDPOINT}}/blank-auth-end.html",
130
- "type": "Spa"
131
- }
129
+ "implicitGrantSettings": {}
130
+ },
131
+ "spa": {
132
+ "redirectUris": [
133
+ "${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__ENDPOINT}}/auth-end.html?clientId=${{AAD_APP_CLIENT_ID}}",
134
+ "${{PROVISIONOUTPUT__FRONTENDHOSTINGOUTPUT__ENDPOINT}}/blank-auth-end.html"
132
135
  ]
133
- }
136
+ }
137
+ }
@@ -5,7 +5,6 @@
5
5
  <DefaultItemExcludes>**</DefaultItemExcludes>
6
6
  </PropertyGroup>
7
7
  <ItemGroup>
8
- <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.TeamsFx" Version="0.1.*" />
9
8
  <PackageReference Include="Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator" Version="1.1.3" />
10
9
  </ItemGroup>
11
- </Project>
10
+ </Project>
@@ -17,11 +17,6 @@
17
17
  "type": "http",
18
18
  "direction": "out",
19
19
  "name": "$return"
20
- },
21
- {
22
- "direction": "in",
23
- "name": "teamsfxContext",
24
- "type": "TeamsFx"
25
20
  }
26
21
  ]
27
- }
22
+ }
@@ -1,26 +1,16 @@
1
1
  require("isomorphic-fetch");
2
- const teamsfx = require("@microsoft/teamsfx");
2
+ const { ConfidentialClientApplication } = require("@azure/msal-node");
3
+ const { Client } = require("@microsoft/microsoft-graph-client");
3
4
 
4
5
  /**
5
- * This function handles requests from teamsfx client.
6
- * The HTTP request should contain an SSO token queried from Teams in the header.
7
- * Before trigger this function, teamsfx binding would process the SSO token and generate teamsfx configuration.
8
- *
9
- * This function initializes the teamsfx SDK with the configuration and calls these APIs:
10
- * - OnBehalfOfUserCredential() - Construct credential with the received SSO token and initialized configuration.
11
- * - getUserInfo() - Get the user's information from the received SSO token.
12
- * - createMicrosoftGraphClient() - Get a graph client to access user's Microsoft 365 data.
13
- *
14
- * The response contains multiple message blocks constructed into a JSON object, including:
15
- * - An echo of the request body.
16
- * - The display name encoded in the SSO token.
17
- * - Current user's Microsoft 365 profile if the user has consented.
6
+ * This function handles requests from the Teams tab client.
7
+ * The HTTP request must include a Teams SSO token in the Authorization header.
8
+ * This function performs OBO (on-behalf-of) to call Microsoft Graph.
18
9
  *
19
10
  * @param {Context} context - The Azure Functions context object.
20
11
  * @param {HttpRequest} req - The HTTP request.
21
- * @param {teamsfxContext} { [key: string]: any; } - The context generated by teamsfx binding.
22
12
  */
23
- module.exports = async function (context, req, teamsfxContext) {
13
+ module.exports = async function (context, req) {
24
14
  context.log("HTTP trigger function processed a request.");
25
15
 
26
16
  // Initialize response.
@@ -33,72 +23,81 @@ module.exports = async function (context, req, teamsfxContext) {
33
23
  res.body.receivedHTTPRequestBody = req.body || "";
34
24
 
35
25
 
36
- // Set default configuration for teamsfx SDK.
37
- try {
38
- teamsfx.loadConfiguration();
39
- } catch (e) {
40
- context.log.error(e);
26
+ // Prepare access token.
27
+ const authHeader = req.headers && (req.headers.authorization || req.headers.Authorization);
28
+ const accessToken = authHeader && authHeader.startsWith("Bearer ")
29
+ ? authHeader.slice("Bearer ".length)
30
+ : null;
31
+ if (!accessToken) {
41
32
  return {
42
- status: 500,
33
+ status: 400,
43
34
  body: {
44
- error: "Failed to load app configuration.",
35
+ error: "No access token was found in request header. Expected Authorization: Bearer <token>.",
45
36
  },
46
37
  };
47
38
  }
48
39
 
49
- // Prepare access token.
50
- const accessToken = teamsfxContext["AccessToken"];
51
- if (!accessToken) {
40
+ const method = req.method.toLowerCase();
41
+ const credentialType =
42
+ method !== "get" ? (req.body && req.body.credentialType) : req.query.credentialType;
43
+ const eTag = method == 'patch' ? req.body.eTag : undefined;
44
+
45
+ const tenantId = process.env.M365_TENANT_ID;
46
+ const clientId = process.env.M365_CLIENT_ID;
47
+ const clientSecret = process.env.M365_CLIENT_SECRET;
48
+ const authorityHost = process.env.M365_AUTHORITY_HOST || "https://login.microsoftonline.com";
49
+ const graphScopes = (process.env.GRAPH_SCOPES || "https://graph.microsoft.com/.default")
50
+ .split(/[,\s]+/)
51
+ .map((scope) => scope.trim())
52
+ .filter(Boolean);
53
+
54
+ if (!tenantId || !clientId || !clientSecret) {
52
55
  return {
53
- status: 400,
56
+ status: 500,
54
57
  body: {
55
- error: "No access token was found in request header.",
58
+ error: "Missing required M365_* configuration for OBO.",
56
59
  },
57
60
  };
58
61
  }
59
62
 
63
+ const msalClient = new ConfidentialClientApplication({
64
+ auth: {
65
+ clientId,
66
+ clientSecret,
67
+ authority: `${authorityHost}/${tenantId}`,
68
+ },
69
+ });
60
70
 
61
-
62
- // Construct credential.
63
- let credential;
64
- const method = req.method.toLowerCase();
65
- const credentialType = method != "get" ? req.body && req.body.credentialType : req.query.credentialType;
66
- const eTag = method == 'patch' ? req.body.eTag : undefined;
67
71
  try {
68
- if (!credentialType) {
72
+ let tokenResult;
73
+ if (credentialType === "app") {
74
+ tokenResult = await msalClient.acquireTokenByClientCredential({
75
+ scopes: graphScopes,
76
+ });
77
+ } else {
78
+ tokenResult = await msalClient.acquireTokenOnBehalfOf({
79
+ oboAssertion: accessToken,
80
+ scopes: graphScopes,
81
+ });
82
+ }
83
+
84
+ if (!tokenResult || !tokenResult.accessToken) {
69
85
  return {
70
86
  status: 500,
71
87
  body: {
72
- error: "Specify the type of credential in the body using field credentialType.",
88
+ error:
89
+ credentialType === "app"
90
+ ? "Failed to obtain Graph access token via client credentials."
91
+ : "Failed to obtain Graph access token via OBO.",
73
92
  },
74
93
  };
75
94
  }
76
95
 
77
- switch (credentialType) {
78
- case ("user"):
79
- credential = new teamsfx.OnBehalfOfUserCredential(accessToken);
80
- break;
81
- case ("app"):
82
- credential = new teamsfx.M365TenantCredential();
83
- break;
84
- }
96
+ const graphClient = Client.init({
97
+ authProvider: (done) => done(null, tokenResult.accessToken),
98
+ });
85
99
 
86
- } catch (e) {
87
- context.log.error(e);
88
- return {
89
- status: 500,
90
- body: {
91
- error:
92
- "Failed to obtain on-behalf-of credential using your accessToken. " +
93
- "Ensure your function app is configured with the right Azure AD App registration.",
94
- },
95
- };
96
- }
97
-
98
- // Create a graph client to access user's Microsoft 365 data after user has consented.
99
- try {
100
- const graphClient = teamsfx.createMicrosoftGraphClient(credential);
101
- graphClient.config.defaultVersion = 'beta';
100
+ //graphClient.config.defaultVersion = 'beta';
102
101
  let path = "";
103
102
  let result;
104
103
 
@@ -134,7 +133,7 @@ module.exports = async function (context, req, teamsfxContext) {
134
133
  break;
135
134
  }
136
135
 
137
- if (result.type == 'image/jpeg') {
136
+ if (result?.type == 'image/jpeg') {
138
137
  res.headers = {
139
138
  'Content-Type': 'image/jpeg',
140
139
  }
@@ -147,8 +146,8 @@ module.exports = async function (context, req, teamsfxContext) {
147
146
 
148
147
  } catch (e) {
149
148
  return {
150
- status: e.statusCode,
151
- body: e.body
149
+ status: e.statusCode || e.status || 500,
150
+ body: e.body || { error: e.message },
152
151
  };
153
152
  }
154
153
 
package/api/host.json CHANGED
@@ -8,4 +8,4 @@
8
8
  }
9
9
  }
10
10
  }
11
- }
11
+ }