diff --git a/samples/tab-channel-group/razor-csharp/.gitignore b/samples/tab-channel-group/razor-csharp/.gitignore new file mode 100644 index 0000000000..9324f35f59 --- /dev/null +++ b/samples/tab-channel-group/razor-csharp/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +AppManifest/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json diff --git a/samples/tab-channel-group/razor-csharp/AppManifest/manifest.json b/samples/tab-channel-group/razor-csharp/AppManifest/manifest.json index 2bc6134802..78de4a3ac0 100644 --- a/samples/tab-channel-group/razor-csharp/AppManifest/manifest.json +++ b/samples/tab-channel-group/razor-csharp/AppManifest/manifest.json @@ -1,14 +1,14 @@ { "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json", "manifestVersion": "1.16", - "id": "<>", + "id": "${{TEAMS_APP_ID}}", "version": "1.0.0", "packageName": "com.custom.tab", "developer": { "name": "Microsoft", - "websiteUrl": "https://www.microsoft.com", - "privacyUrl": "https://www.microsoft.com/privacy", - "termsOfUseUrl": "https://www.microsoft.com/termsofuse" + "websiteUrl": "https://${{TAB_DOMAIN}}", + "privacyUrl": "https://${{TAB_DOMAIN}}/privacy", + "termsOfUseUrl": "https://${{TAB_DOMAIN}}/termsofuse" }, "name": { "short": "Channel Group Tab", @@ -25,7 +25,7 @@ "accentColor": "#D85028", "configurableTabs": [ { - "configurationUrl": "https:///tab", + "configurationUrl": "https://${{TAB_DOMAIN}}/tab", "canUpdateConfiguration": true, "scopes": [ "groupchat", @@ -38,6 +38,7 @@ "messageTeamMembers" ], "validDomains": [ - "{{domain-name}}" + "*.ngrok-free.app", + "${{TAB_DOMAIN}}" ] } \ No newline at end of file diff --git a/samples/tab-channel-group/razor-csharp/Properties/launchSettings.json b/samples/tab-channel-group/razor-csharp/Properties/launchSettings.json index b49680462a..ddc26edfee 100644 --- a/samples/tab-channel-group/razor-csharp/Properties/launchSettings.json +++ b/samples/tab-channel-group/razor-csharp/Properties/launchSettings.json @@ -1,27 +1,28 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:3978", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "ChannelGroupTab": { + // Debug project within Teams + "Microsoft Teams (browser)": { "commandName": "Project", + "dotnetRunMessages": true, "launchBrowser": true, + "launchUrl": "https://teams.microsoft.com/l/app/%TEAMSAPPID%?installAppPackage=true&webjoin=true&appTenantId=%TENANTID%&login_hint=%USERNAME%", + "applicationUrl": "https://localhost:44302;http://localhost:2544", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "https://localhost:3979;http://localhost:3978" + "hotReloadProfile": "aspnetcore" } + //// Uncomment following profile to debug project only (without launching Teams) + //, + //"Start Project (not in Teams)": { + // "commandName": "Project", + // "dotnetRunMessages": true, + // "launchBrowser": true, + // "applicationUrl": "https://localhost:44302;http://localhost:2544", + // "environmentVariables": { + // "ASPNETCORE_ENVIRONMENT": "Development" + // }, + // "hotReloadProfile": "aspnetcore" + //} } } \ No newline at end of file diff --git a/samples/tab-channel-group/razor-csharp/README.md b/samples/tab-channel-group/razor-csharp/README.md index 78ef9a8214..2a507e906f 100644 --- a/samples/tab-channel-group/razor-csharp/README.md +++ b/samples/tab-channel-group/razor-csharp/README.md @@ -41,6 +41,19 @@ Please find below demo manifest which is deployed on Microsoft Azure and you can - [Teams](https://teams.microsoft.com) Microsoft Teams is installed and you have an account +- [Teams Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Teams Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Teams Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.8 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Teams Toolkit for Visual Studio [Teams Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In Visual Studio, right-click your project and **Select Teams Toolkit > Prepare Teams App Dependencies** +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps. +1. Select **Debug > Start Debugging** or **F5** to run the menu in Visual Studio. +1. In the browser that launches, select the **Add** button to install the app to Teams. +> If you do not have permission to upload custom apps (sideloading), Teams Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + ## Setup 1. Run ngrok - point to port 3978 diff --git a/samples/tab-channel-group/razor-csharp/channelGroupTab.csproj b/samples/tab-channel-group/razor-csharp/channelGroupTab.csproj index d7d644100a..3f13f63d65 100644 --- a/samples/tab-channel-group/razor-csharp/channelGroupTab.csproj +++ b/samples/tab-channel-group/razor-csharp/channelGroupTab.csproj @@ -15,4 +15,8 @@ + + + + diff --git a/samples/tab-channel-group/razor-csharp/env/.env.local b/samples/tab-channel-group/razor-csharp/env/.env.local new file mode 100644 index 0000000000..b36807f000 --- /dev/null +++ b/samples/tab-channel-group/razor-csharp/env/.env.local @@ -0,0 +1,14 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= +TAB_ENDPOINT= + +TEAMSFX_M365_USER_NAME= + +APP_NAME_SUFFIX= +TAB_DOMAIN= +TEAMS_APP_TENANT_ID= \ No newline at end of file diff --git a/samples/tab-channel-group/razor-csharp/teamsapp.local.yml b/samples/tab-channel-group/razor-csharp/teamsapp.local.yml new file mode 100644 index 0000000000..51aa1425a6 --- /dev/null +++ b/samples/tab-channel-group/razor-csharp/teamsapp.local.yml @@ -0,0 +1,66 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-channel-group-razor-csharp + +provision: + # Set TAB_DOMAIN and TAB_ENDPOINT for local launch + - uses: script + with: + run: + echo "::set-teamsfx-env TAB_DOMAIN=localhost:44302"; + echo "::set-teamsfx-env TAB_ENDPOINT=https://localhost:44302"; + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-channel-group-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + outputZipPath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./AppManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + # Apply the Teams app manifest to an existing Teams app in + # Teams Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + + # Create or update debug profile in lauchsettings file + - uses: file/createOrUpdateJsonFile + with: + target: ./Properties/launchSettings.json + content: + profiles: + Microsoft Teams (browser): + commandName: "Project" + dotnetRunMessages: true + launchBrowser: true + launchUrl: "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + applicationUrl: "https://localhost:44302;http://localhost:2544" + environmentVariables: + ASPNETCORE_ENVIRONMENT: "Development" + hotReloadProfile: "aspnetcore" \ No newline at end of file diff --git a/samples/tab-channel-group/razor-csharp/teamsapp.yml b/samples/tab-channel-group/razor-csharp/teamsapp.yml new file mode 100644 index 0000000000..d2592ffeef --- /dev/null +++ b/samples/tab-channel-group/razor-csharp/teamsapp.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-channel-group-razor-csharp + +environmentFolderPath: ./env diff --git a/samples/tab-conversations/csharp/README.md b/samples/tab-conversations/csharp/README.md index 6b96e820a8..2e80d3b826 100644 --- a/samples/tab-conversations/csharp/README.md +++ b/samples/tab-conversations/csharp/README.md @@ -37,6 +37,18 @@ Please find below demo manifest which is deployed on Microsoft Azure and you can # determine dotnet version dotnet --version ``` +- [Teams Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Teams Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Teams Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.8 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Teams Toolkit for Visual Studio [Teams Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In Visual Studio, right-click your project and **Select Teams Toolkit > Prepare Teams App Dependencies** +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps. +1. Select **Debug > Start Debugging** or **F5** to run the menu in Visual Studio. +1. In the browser that launches, select the **Add** button to install the app to Teams. +> If you do not have permission to upload custom apps (sideloading), Teams Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. ## Setup 1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. diff --git a/samples/tab-conversations/csharp/TabConversation/.gitignore b/samples/tab-conversations/csharp/TabConversation/.gitignore new file mode 100644 index 0000000000..9324f35f59 --- /dev/null +++ b/samples/tab-conversations/csharp/TabConversation/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +AppManifest/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json diff --git a/samples/tab-conversations/csharp/TabConversation/AppManifest/manifest.json b/samples/tab-conversations/csharp/TabConversation/AppManifest/manifest.json index ba0b135cd5..8ea7609b53 100644 --- a/samples/tab-conversations/csharp/TabConversation/AppManifest/manifest.json +++ b/samples/tab-conversations/csharp/TabConversation/AppManifest/manifest.json @@ -2,7 +2,7 @@ "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.12/MicrosoftTeams.schema.json", "manifestVersion": "1.12", "version": "1.0.0", - "id": "b404cc0a-f062-42c5-85c8-d8bb1dd12fc1", + "id": "${{TEAMS_APP_ID}}", "packageName": "com.microsoft.tabconversations", "developer": { "name": "Microsoft", @@ -25,7 +25,7 @@ "accentColor": "#60A18E", "configurableTabs": [ { - "configurationUrl": "<>/configure", + "configurationUrl": "https://${{TAB_DOMAIN}}/configure", "canUpdateConfiguration": true, "scopes": [ "team" @@ -37,6 +37,7 @@ ], "permissions": [ "identity", "messageTeamMembers" ], "validDomains": [ - "<>" + "*.ngrok-free.app", + "${{TAB_DOMAIN}}" ] } \ No newline at end of file diff --git a/samples/tab-conversations/csharp/TabConversation/Properties/launchSettings.json b/samples/tab-conversations/csharp/TabConversation/Properties/launchSettings.json index ca78a2f678..8eefd9188e 100644 --- a/samples/tab-conversations/csharp/TabConversation/Properties/launchSettings.json +++ b/samples/tab-conversations/csharp/TabConversation/Properties/launchSettings.json @@ -1,29 +1,28 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:3978", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" - } - }, - "TabConversation": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" - }, - "applicationUrl": "http://localhost:5000" - } - } + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "https://teams.microsoft.com/l/app/294d0749-3209-4cfe-9f85-2d0c99684e8d?installAppPackage=true&webjoin=true&appTenantId=72f988bf-86f1-41af-91ab-2d7cd011db47&login_hint=v-hrajandira@microsoft.com", + "applicationUrl": "https://localhost:44302;http://localhost:2544", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + //// Uncomment following profile to debug project only (without launching Teams) + //, + //"Start Project (not in Teams)": { + // "commandName": "Project", + // "dotnetRunMessages": true, + // "launchBrowser": true, + // "applicationUrl": "https://localhost:44302;http://localhost:2544", + // "environmentVariables": { + // "ASPNETCORE_ENVIRONMENT": "Development" + // }, + // "hotReloadProfile": "aspnetcore" + //} + } } \ No newline at end of file diff --git a/samples/tab-conversations/csharp/TabConversation/TabConversation.csproj b/samples/tab-conversations/csharp/TabConversation/TabConversation.csproj index dbc869398b..191e892cbe 100644 --- a/samples/tab-conversations/csharp/TabConversation/TabConversation.csproj +++ b/samples/tab-conversations/csharp/TabConversation/TabConversation.csproj @@ -9,4 +9,8 @@ + + + + diff --git a/samples/tab-conversations/csharp/TabConversation/env/.env.local b/samples/tab-conversations/csharp/TabConversation/env/.env.local new file mode 100644 index 0000000000..e4709f290f --- /dev/null +++ b/samples/tab-conversations/csharp/TabConversation/env/.env.local @@ -0,0 +1,13 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= +TAB_ENDPOINT= + +APP_NAME_SUFFIX= +TAB_DOMAIN= +TEAMS_APP_TENANT_ID= +TEAMSFX_M365_USER_NAME= \ No newline at end of file diff --git a/samples/tab-conversations/csharp/TabConversation/teamsapp.local.yml b/samples/tab-conversations/csharp/TabConversation/teamsapp.local.yml new file mode 100644 index 0000000000..cb19a48843 --- /dev/null +++ b/samples/tab-conversations/csharp/TabConversation/teamsapp.local.yml @@ -0,0 +1,66 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-conversations-csharp + +provision: + # Set TAB_DOMAIN and TAB_ENDPOINT for local launch + - uses: script + with: + run: + echo "::set-teamsfx-env TAB_DOMAIN=localhost:44302"; + echo "::set-teamsfx-env TAB_ENDPOINT=https://localhost:44302"; + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-conversations-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + outputZipPath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./AppManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + # Apply the Teams app manifest to an existing Teams app in + # Teams Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + + # Create or update debug profile in lauchsettings file + - uses: file/createOrUpdateJsonFile + with: + target: ./Properties/launchSettings.json + content: + profiles: + Microsoft Teams (browser): + commandName: "Project" + dotnetRunMessages: true + launchBrowser: true + launchUrl: "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + applicationUrl: "https://localhost:44302;http://localhost:2544" + environmentVariables: + ASPNETCORE_ENVIRONMENT: "Development" + hotReloadProfile: "aspnetcore" \ No newline at end of file diff --git a/samples/tab-conversations/csharp/TabConversation/teamsapp.yml b/samples/tab-conversations/csharp/TabConversation/teamsapp.yml new file mode 100644 index 0000000000..7f3eed5ff8 --- /dev/null +++ b/samples/tab-conversations/csharp/TabConversation/teamsapp.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-conversations-csharp + +environmentFolderPath: ./env \ No newline at end of file diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/.gitignore b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/.gitignore new file mode 100644 index 0000000000..9324f35f59 --- /dev/null +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +AppManifest/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/AppManifest/manifest.json b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/AppManifest/manifest.json index aa00faf8d2..5a85986b2d 100644 --- a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/AppManifest/manifest.json +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/AppManifest/manifest.json @@ -2,7 +2,7 @@ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json", "manifestVersion": "1.16", "version": "1.0.1", - "id": "<>", + "id": "${{TEAMS_APP_ID}}", "packageName": "com.contoso.teamsauthsso", "developer": { "name": "Microsoft", @@ -27,7 +27,7 @@ { "entityId": "auth", "name": "Auth", - "contentUrl": "https://{{domain-name}}/Home/Index", + "contentUrl": "https://${{TAB_DOMAIN}}/Home/Index", "scopes": [ "personal" ] @@ -38,11 +38,11 @@ "messageTeamMembers" ], "validDomains": [ - "{{domain-name}}", - "{{domain-name}}" + "*.ngrok-free.app", + "${{TAB_DOMAIN}}" ], "webApplicationInfo": { - "id": "<>", - "resource": "api://{{domain-name}}/<>" + "id": "${{AAD_APP_CLIENT_ID}}", + "resource": "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" } } \ No newline at end of file diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/PersonalTabSSO.csproj b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/PersonalTabSSO.csproj index bdb2307f9e..e45c14f22c 100644 --- a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/PersonalTabSSO.csproj +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/PersonalTabSSO.csproj @@ -18,6 +18,10 @@ + + + + false diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/Properties/launchSettings.json b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/Properties/launchSettings.json index c73d4ca813..ddc26edfee 100644 --- a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/Properties/launchSettings.json +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/Properties/launchSettings.json @@ -1,27 +1,28 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:3978/", - "sslPort": 0 - } - }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "TeamsAuthSSO": { + // Debug project within Teams + "Microsoft Teams (browser)": { "commandName": "Project", + "dotnetRunMessages": true, "launchBrowser": true, + "launchUrl": "https://teams.microsoft.com/l/app/%TEAMSAPPID%?installAppPackage=true&webjoin=true&appTenantId=%TENANTID%&login_hint=%USERNAME%", + "applicationUrl": "https://localhost:44302;http://localhost:2544", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "http://localhost:58257/" + "hotReloadProfile": "aspnetcore" } + //// Uncomment following profile to debug project only (without launching Teams) + //, + //"Start Project (not in Teams)": { + // "commandName": "Project", + // "dotnetRunMessages": true, + // "launchBrowser": true, + // "applicationUrl": "https://localhost:44302;http://localhost:2544", + // "environmentVariables": { + // "ASPNETCORE_ENVIRONMENT": "Development" + // }, + // "hotReloadProfile": "aspnetcore" + //} } } \ No newline at end of file diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/README.md b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/README.md index 4185813f1c..2fa04090d2 100644 --- a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/README.md +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/README.md @@ -37,6 +37,19 @@ This sample illustrates how to implement SSO authentication for Teams Tab. - [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [Ngrok](https://ngrok.com/download) (For local environment testing) latest version (any other tunneling software can also be used) - [Teams](https://teams.microsoft.com) Microsoft Teams is installed and you have an account + +- [Teams Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Teams Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Teams Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.8 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Teams Toolkit for Visual Studio [Teams Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In Visual Studio, right-click your project and **Select Teams Toolkit > Prepare Teams App Dependencies** +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps. +1. Select **Debug > Start Debugging** or **F5** to run the menu in Visual Studio. +1. In the browser that launches, select the **Add** button to install the app to Teams. +> If you do not have permission to upload custom apps (sideloading), Teams Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. ## Setup diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/aad.manifest.json b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/aad.manifest.json new file mode 100644 index 0000000000..2880968522 --- /dev/null +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/aad.manifest.json @@ -0,0 +1,101 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "tab-personal-sso-quickstart-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMultipleOrgs", + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "oauth2Permissions": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ], + "identifierUris": [ + "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" + ], + "replyUrlsWithType": [ + { + "url": "${{TAB_ENDPOINT}}/Auth/End", + "type": "Spa" + } + ] +} \ No newline at end of file diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/env/.env.local b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/env/.env.local new file mode 100644 index 0000000000..86528dae75 --- /dev/null +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/env/.env.local @@ -0,0 +1,21 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_OAUTH2_PERMISSION_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY_HOST= +AAD_APP_OAUTH_AUTHORITY= +TAB_ENDPOINT= + +TEAMSFX_M365_USER_NAME= + +APP_NAME_SUFFIX= +TAB_DOMAIN= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= \ No newline at end of file diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/teamsapp.local.yml b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/teamsapp.local.yml new file mode 100644 index 0000000000..084523d0f7 --- /dev/null +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/teamsapp.local.yml @@ -0,0 +1,111 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-personal-sso-quickstart-csharp + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if + # the environment variable that stores clientId is empty + - uses: aadApp/create + with: + # Note: when you run aadApp/update, the AAD app name will be updated + # based on the definition in manifest. If you don't want to change the + # name, make sure the name in AAD manifest is the same with the name + # defined here. + name: tab-personal-sso-quickstart-aad + # If the value is false, the action will not generate client secret for you + generateClientSecret: true + # Authenticate users with a Microsoft work or school account in your + # organization's Azure AD tenant (for example, single tenant). + signInAudience: AzureADMultipleOrgs + # Write the information of created resources into environment file for the + # specified environment variable(s). + writeToEnvironmentFile: + clientId: AAD_APP_CLIENT_ID + # Environment variable that starts with `SECRET_` will be stored to the + # .env.{envName}.user environment file + clientSecret: SECRET_AAD_APP_CLIENT_SECRET + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Set TAB_DOMAIN and TAB_ENDPOINT for local launch + - uses: script + with: + run: + echo "::set-teamsfx-env TAB_DOMAIN=localhost:44302"; + echo "::set-teamsfx-env TAB_ENDPOINT=https://localhost:44302"; + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-personal-sso-quickstart-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ./appsettings.json + content: + AzureAd: + ClientId: ${{AAD_APP_CLIENT_ID}} + AppSecret: ${{SECRET_AAD_APP_CLIENT_SECRET}} + ApplicationIdURI: api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}} + + # Apply the AAD manifest to an existing AAD app. Will use the object id in + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + outputZipPath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./AppManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + # Apply the Teams app manifest to an existing Teams app in + # Teams Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + + # Create or update debug profile in lauchsettings file + - uses: file/createOrUpdateJsonFile + with: + target: ./Properties/launchSettings.json + content: + profiles: + Microsoft Teams (browser): + commandName: "Project" + dotnetRunMessages: true + launchBrowser: true + launchUrl: "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + applicationUrl: "https://localhost:44302;http://localhost:2544" + environmentVariables: + ASPNETCORE_ENVIRONMENT: "Development" + hotReloadProfile: "aspnetcore" \ No newline at end of file diff --git a/samples/tab-personal-sso-quickstart/csharp_dotnetcore/teamsapp.yml b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/teamsapp.yml new file mode 100644 index 0000000000..0fe7676734 --- /dev/null +++ b/samples/tab-personal-sso-quickstart/csharp_dotnetcore/teamsapp.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-personal-sso-quickstart-csharp + +environmentFolderPath: ./env diff --git a/samples/tab-product-inspection/csharp/ProductInspection/.gitignore b/samples/tab-product-inspection/csharp/ProductInspection/.gitignore new file mode 100644 index 0000000000..9324f35f59 --- /dev/null +++ b/samples/tab-product-inspection/csharp/ProductInspection/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +AppManifest/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json diff --git a/samples/tab-product-inspection/csharp/ProductInspection/AppManifest/manifest.json b/samples/tab-product-inspection/csharp/ProductInspection/AppManifest/manifest.json index 9f5d307196..60ce378604 100644 --- a/samples/tab-product-inspection/csharp/ProductInspection/AppManifest/manifest.json +++ b/samples/tab-product-inspection/csharp/ProductInspection/AppManifest/manifest.json @@ -2,13 +2,13 @@ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json", "manifestVersion": "1.16", "version": "1.0.0", - "id": "{{Microsoft-App-Id}}", + "id": "${{TEAMS_APP_ID}}", "packageName": "com.teams.productinspection", "developer": { "name": "Microsoft", - "websiteUrl": "https://www.microsoft.com", - "privacyUrl": "https://www.teams.com/privacy", - "termsOfUseUrl": "https://www.teams.com/termsofuser" + "websiteUrl": "https://${{TAB_DOMAIN}}", + "privacyUrl": "https://${{TAB_DOMAIN}}/privacy", + "termsOfUseUrl": "https://${{TAB_DOMAIN}}/termsofuser" }, "icons": { "color": "color.png", @@ -27,8 +27,8 @@ { "entityId": "TabProductInspection", "name": "Capture image tab", - "contentUrl": "https://{{domain-name}}/index", - "websiteUrl": "https://{{domain-name}}/index", + "contentUrl": "https://${{TAB_DOMAIN}}/index", + "websiteUrl": "https://${{TAB_DOMAIN}}/index", "scopes": [ "personal" ] @@ -39,8 +39,8 @@ "messageTeamMembers" ], "validDomains": [ - "{{domain-name}}", - "{{domain-name}}" + "*.ngrok-free.app", + "${{TAB_DOMAIN}}" ], "devicePermissions": [ "media" diff --git a/samples/tab-product-inspection/csharp/ProductInspection/ProductInspection.csproj b/samples/tab-product-inspection/csharp/ProductInspection/ProductInspection.csproj index 383db59c11..cc1a8f087d 100644 --- a/samples/tab-product-inspection/csharp/ProductInspection/ProductInspection.csproj +++ b/samples/tab-product-inspection/csharp/ProductInspection/ProductInspection.csproj @@ -13,4 +13,8 @@ + + + + \ No newline at end of file diff --git a/samples/tab-product-inspection/csharp/ProductInspection/Properties/launchSettings.json b/samples/tab-product-inspection/csharp/ProductInspection/Properties/launchSettings.json index 1e0ef46e36..ab57801b19 100644 --- a/samples/tab-product-inspection/csharp/ProductInspection/Properties/launchSettings.json +++ b/samples/tab-product-inspection/csharp/ProductInspection/Properties/launchSettings.json @@ -1,28 +1,28 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:3978", - "sslPort": 0 - } - }, - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "EchoBot": { - "commandName": "Project", - "launchBrowser": true, - "applicationUrl": "https://localhost:3979;http://localhost:3978", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } +{ + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "https://teams.microsoft.com/l/app/%TEAMSAPPID%?installAppPackage=true&webjoin=true&appTenantId=%TENANTID%&login_hint=%USERNAME%", + "applicationUrl": "https://localhost:44302;http://localhost:2544", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + //// Uncomment following profile to debug project only (without launching Teams) + //, + //"Start Project (not in Teams)": { + // "commandName": "Project", + // "dotnetRunMessages": true, + // "launchBrowser": true, + // "applicationUrl": "https://localhost:44302;http://localhost:2544", + // "environmentVariables": { + // "ASPNETCORE_ENVIRONMENT": "Development" + // }, + // "hotReloadProfile": "aspnetcore" + //} + } } \ No newline at end of file diff --git a/samples/tab-product-inspection/csharp/ProductInspection/env/.env.local b/samples/tab-product-inspection/csharp/ProductInspection/env/.env.local new file mode 100644 index 0000000000..b36807f000 --- /dev/null +++ b/samples/tab-product-inspection/csharp/ProductInspection/env/.env.local @@ -0,0 +1,14 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= +TAB_ENDPOINT= + +TEAMSFX_M365_USER_NAME= + +APP_NAME_SUFFIX= +TAB_DOMAIN= +TEAMS_APP_TENANT_ID= \ No newline at end of file diff --git a/samples/tab-product-inspection/csharp/ProductInspection/teamsapp.local.yml b/samples/tab-product-inspection/csharp/ProductInspection/teamsapp.local.yml new file mode 100644 index 0000000000..f076e05503 --- /dev/null +++ b/samples/tab-product-inspection/csharp/ProductInspection/teamsapp.local.yml @@ -0,0 +1,66 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-product-inspection-csharp + +provision: + # Set TAB_DOMAIN and TAB_ENDPOINT for local launch + - uses: script + with: + run: + echo "::set-teamsfx-env TAB_DOMAIN=localhost:44302"; + echo "::set-teamsfx-env TAB_ENDPOINT=https://localhost:44302"; + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-product-inspection-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + outputZipPath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./AppManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + # Apply the Teams app manifest to an existing Teams app in + # Teams Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + + # Create or update debug profile in lauchsettings file + - uses: file/createOrUpdateJsonFile + with: + target: ./Properties/launchSettings.json + content: + profiles: + Microsoft Teams (browser): + commandName: "Project" + dotnetRunMessages: true + launchBrowser: true + launchUrl: "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + applicationUrl: "https://localhost:44302;http://localhost:2544" + environmentVariables: + ASPNETCORE_ENVIRONMENT: "Development" + hotReloadProfile: "aspnetcore" \ No newline at end of file diff --git a/samples/tab-product-inspection/csharp/ProductInspection/teamsapp.yml b/samples/tab-product-inspection/csharp/ProductInspection/teamsapp.yml new file mode 100644 index 0000000000..109e1df8cc --- /dev/null +++ b/samples/tab-product-inspection/csharp/ProductInspection/teamsapp.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-product-inspection-csharp + +environmentFolderPath: ./env \ No newline at end of file diff --git a/samples/tab-product-inspection/csharp/README.md b/samples/tab-product-inspection/csharp/README.md index ea0133eb49..e387766bea 100644 --- a/samples/tab-product-inspection/csharp/README.md +++ b/samples/tab-product-inspection/csharp/README.md @@ -35,6 +35,18 @@ Please find below demo manifest which is deployed on Microsoft Azure and you can - [.NET Core SDK](https://dotnet.microsoft.com/download) version 6.0 - [dev tunnel](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started?tabs=windows) or [ngrok](https://ngrok.com/) latest version or equivalent tunneling solution - [M365 developer account](https://docs.microsoft.com/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant) or access to a Teams account with the +- [Teams Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Teams Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Teams Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.8 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Teams Toolkit for Visual Studio [Teams Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In Visual Studio, right-click your project and **Select Teams Toolkit > Prepare Teams App Dependencies** +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps. +1. Select **Debug > Start Debugging** or **F5** to run the menu in Visual Studio. +1. In the browser that launches, select the **Add** button to install the app to Teams. +> If you do not have permission to upload custom apps (sideloading), Teams Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. ## Setup. diff --git a/samples/tab-staggered-permission/csharp/README.md b/samples/tab-staggered-permission/csharp/README.md index 07078e8f0b..d95381c65f 100644 --- a/samples/tab-staggered-permission/csharp/README.md +++ b/samples/tab-staggered-permission/csharp/README.md @@ -43,6 +43,19 @@ Please find below demo manifest which is deployed on Microsoft Azure and you can - [Teams](https://teams.microsoft.com) Microsoft Teams is installed and you have an account +- [Teams Toolkit for Visual Studio](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) + +## Run the app (Using Teams Toolkit for Visual Studio) + +The simplest way to run this sample in Teams is to use Teams Toolkit for Visual Studio. +1. Install Visual Studio 2022 **Version 17.8 or higher** [Visual Studio](https://visualstudio.microsoft.com/downloads/) +1. Install Teams Toolkit for Visual Studio [Teams Toolkit extension](https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/toolkit-v4/install-teams-toolkit-vs?pivots=visual-studio-v17-7) +1. In Visual Studio, right-click your project and **Select Teams Toolkit > Prepare Teams App Dependencies** +1. Using the extension, sign in with your Microsoft 365 account where you have permissions to upload custom apps. +1. Select **Debug > Start Debugging** or **F5** to run the menu in Visual Studio. +1. In the browser that launches, select the **Add** button to install the app to Teams. +> If you do not have permission to upload custom apps (sideloading), Teams Toolkit will recommend creating and using a Microsoft 365 Developer Program account - a free program to get your own dev environment sandbox that includes Teams. + ## Setup 1. Register a new application in the [Microsoft Entra ID – App Registrations](https://go.microsoft.com/fwlink/?linkid=2083908) portal. diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/.gitignore b/samples/tab-staggered-permission/csharp/StaggeredPermission/.gitignore new file mode 100644 index 0000000000..9324f35f59 --- /dev/null +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/.gitignore @@ -0,0 +1,25 @@ +# TeamsFx files +build +AppManifest/build +env/.env.*.user +env/.env.local +appsettings.Development.json +.deployment + +# User-specific files +*.user + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Notification local store +.notification.localstore.json diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/AppManifest/manifest.json b/samples/tab-staggered-permission/csharp/StaggeredPermission/AppManifest/manifest.json index aabfc819b3..4fecaded64 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/AppManifest/manifest.json +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/AppManifest/manifest.json @@ -2,7 +2,7 @@ "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json", "manifestVersion": "1.16", "version": "1.0.1", - "id": "{{Microsoft-App-Id}}", + "id": "${{TEAMS_APP_ID}}", "packageName": "com.microsoft.teams.staggeredpermission", "developer": { "name": "Microsoft", @@ -27,8 +27,8 @@ { "entityId": "Staggered permission", "name": "tab", - "contentUrl": "https://{{domain-name}}/tab", - "websiteUrl": "https://{{domain-name}}/tab", + "contentUrl": "https://${{TAB_DOMAIN}}/tab", + "websiteUrl": "https://${{TAB_DOMAIN}}/tab", "scopes": [ "personal" ] @@ -39,10 +39,11 @@ "messageTeamMembers" ], "validDomains": [ - "{{domain-name}}" + "*.ngrok-free.app", + "${{TAB_DOMAIN}}" ], "webApplicationInfo": { - "id": "{{Microsoft-App-Id}}", - "resource": "api://{{domain-name}}/{{Microsoft-App-Id}}" + "id": "${{AAD_APP_CLIENT_ID}}", + "resource": "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" } } \ No newline at end of file diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/Controllers/TabController.cs b/samples/tab-staggered-permission/csharp/StaggeredPermission/Controllers/TabController.cs index aeb242e727..c6d74965d9 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/Controllers/TabController.cs +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/Controllers/TabController.cs @@ -122,9 +122,9 @@ public async Task DecodeToken(string accessToken) decodedValue.Payload.TryGetValue("name", out nameObj); } - if (decodedValue.Payload.ContainsKey("unique_name")) + if (decodedValue.Payload.ContainsKey("preferred_username")) { - decodedValue.Payload.TryGetValue("unique_name", out emailObj); + decodedValue.Payload.TryGetValue("preferred_username", out emailObj); } var userInfo = new UserData() diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml.cs b/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml.cs index fc31b93a05..8c68326141 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml.cs +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-end.cshtml.cs @@ -28,7 +28,7 @@ public authEnd(IConfiguration configuration) /// public void OnGet() { - ClientId = _configuration["MicrosoftAppId"]; + ClientId = _configuration["AzureAd:ClientId"]; } } } diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml.cs b/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml.cs index 8b80d4bf52..e84bb569e5 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml.cs +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/Pages/auth-start.cshtml.cs @@ -28,7 +28,7 @@ public authStart(IConfiguration configuration) /// public void OnGet() { - ClientId = _configuration["MicrosoftAppId"]; + ClientId = _configuration["AzureAd:ClientId"]; } } } \ No newline at end of file diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/Properties/launchSettings.json b/samples/tab-staggered-permission/csharp/StaggeredPermission/Properties/launchSettings.json index 7a1340493e..ab57801b19 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/Properties/launchSettings.json +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/Properties/launchSettings.json @@ -1,28 +1,28 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:3978", - "sslPort": 0 - } - }, - "$schema": "http://json.schemastore.org/launchsettings.json", - "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "EchoBot": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "applicationUrl": "http://localhost:3978" - } - } + "profiles": { + // Debug project within Teams + "Microsoft Teams (browser)": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "https://teams.microsoft.com/l/app/%TEAMSAPPID%?installAppPackage=true&webjoin=true&appTenantId=%TENANTID%&login_hint=%USERNAME%", + "applicationUrl": "https://localhost:44302;http://localhost:2544", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "hotReloadProfile": "aspnetcore" + } + //// Uncomment following profile to debug project only (without launching Teams) + //, + //"Start Project (not in Teams)": { + // "commandName": "Project", + // "dotnetRunMessages": true, + // "launchBrowser": true, + // "applicationUrl": "https://localhost:44302;http://localhost:2544", + // "environmentVariables": { + // "ASPNETCORE_ENVIRONMENT": "Development" + // }, + // "hotReloadProfile": "aspnetcore" + //} + } } \ No newline at end of file diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/StaggeredPermission.csproj b/samples/tab-staggered-permission/csharp/StaggeredPermission/StaggeredPermission.csproj index 393a72b8b6..9a58dd15e0 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/StaggeredPermission.csproj +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/StaggeredPermission.csproj @@ -23,4 +23,8 @@ + + + + diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/aad.manifest.json b/samples/tab-staggered-permission/csharp/StaggeredPermission/aad.manifest.json new file mode 100644 index 0000000000..6c7a97cd1e --- /dev/null +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/aad.manifest.json @@ -0,0 +1,101 @@ +{ + "id": "${{AAD_APP_OBJECT_ID}}", + "appId": "${{AAD_APP_CLIENT_ID}}", + "name": "tab-staggered-permission-aad", + "accessTokenAcceptedVersion": 2, + "signInAudience": "AzureADMultipleOrgs", + "optionalClaims": { + "idToken": [], + "accessToken": [ + { + "name": "idtyp", + "source": null, + "essential": false, + "additionalProperties": [] + } + ], + "saml2Token": [] + }, + "requiredResourceAccess": [ + { + "resourceAppId": "Microsoft Graph", + "resourceAccess": [ + { + "id": "User.Read", + "type": "Scope" + } + ] + } + ], + "oauth2Permissions": [ + { + "adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.", + "adminConsentDisplayName": "Teams can access app's web APIs", + "id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}", + "isEnabled": true, + "type": "User", + "userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have", + "userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf", + "value": "access_as_user" + } + ], + "preAuthorizedApplications": [ + { + "appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "d3590ed6-52b3-4102-aeff-aad2292ab01c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "00000002-0000-0ff1-ce00-000000000000", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "bc59ab01-8403-45c6-8796-ac3ef710b3e3", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "0ec893e0-5785-4de6-99da-4ed124e5296c", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4765445b-32c6-49b0-83e6-1d93765276ca", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + }, + { + "appId": "4345a7b9-9a63-4910-a426-35363201d503", + "permissionIds": [ + "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}" + ] + } + ], + "identifierUris": [ + "api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}}" + ], + "replyUrlsWithType": [ + { + "url": "${{TAB_ENDPOINT}}/auth-end", + "type": "Spa" + } + ] +} \ No newline at end of file diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/appsettings.json b/samples/tab-staggered-permission/csharp/StaggeredPermission/appsettings.json index 4c470fff76..f23c1c9653 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/appsettings.json +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/appsettings.json @@ -1,14 +1,11 @@ { - "MicrosoftAppId": "", - "MicrosoftAppPassword": "", - "ApplicationBaseUrl": "", - "AzureAd": { - "Instance": "https://login.microsoftonline.com/", - "TenantId": "common", - "MicrosoftAppId": "", - "MicrosoftAppPassword": "", - "ApplicationIdURI": "", - "AuthUrl": "/oauth2/v2.0/token", - "ValidIssuers": "https://login.microsoftonline.com/tenantId/v2.0,https://sts.windows.net/tenantId/" - } + "AzureAd": { + "Instance": "https://login.microsoftonline.com/", + "TenantId": "common", + "ClientId": "{{MicrosoftClientId}}", + "AppSecret": "{{MicrosoftAppPassword}}", + "ApplicationIdURI": "api://{{ApplicationBaseUrl}}/{{MicrosoftClientId}}", + "AuthUrl": "/oauth2/v2.0/token", + "ValidIssuers": "https://login.microsoftonline.com/common/v2.0,https://sts.windows.net/common/" + } } \ No newline at end of file diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/env/.env.local b/samples/tab-staggered-permission/csharp/StaggeredPermission/env/.env.local new file mode 100644 index 0000000000..84c497d21f --- /dev/null +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/env/.env.local @@ -0,0 +1,21 @@ +# This file includes environment variables that can be committed to git. It's gitignored by default because it represents your local development environment. + +# Built-in environment variables +TEAMSFX_ENV=local + +# Generated during provision, you can also add your own variables. +TEAMS_APP_ID= +AAD_APP_CLIENT_ID= +AAD_APP_OBJECT_ID= +AAD_APP_OAUTH2_PERMISSION_ID= +AAD_APP_TENANT_ID= +AAD_APP_OAUTH_AUTHORITY_HOST= +AAD_APP_OAUTH_AUTHORITY= +TAB_ENDPOINT= + +APP_NAME_SUFFIX= +TAB_DOMAIN= +TEAMS_APP_TENANT_ID= +AAD_APP_ACCESS_AS_USER_PERMISSION_ID= + +TEAMSFX_M365_USER_NAME= \ No newline at end of file diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/helper/AuthHelper.cs b/samples/tab-staggered-permission/csharp/StaggeredPermission/helper/AuthHelper.cs index 04ad263251..18c1afda45 100644 --- a/samples/tab-staggered-permission/csharp/StaggeredPermission/helper/AuthHelper.cs +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/helper/AuthHelper.cs @@ -20,7 +20,7 @@ public class AuthHelper /// Valid Audiences. public static IEnumerable GetValidAudiences(IConfiguration configuration) { - var clientId = configuration["AzureAd:MicrosoftAppId"]; + var clientId = configuration["AzureAd:ClientId"]; var applicationIdUri = configuration["AzureAd:ApplicationIdURI"]; var validAudiences = new List { clientId, applicationIdUri.ToLower() }; return validAudiences; @@ -83,8 +83,8 @@ public static bool AudienceValidator( public static async Task GetAccessTokenOnBehalfUserAsync(IConfiguration configuration, IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContextAccessor, string idToken) { var tenantId = configuration["AzureAd:TenantId"]; - IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(configuration["AzureAd:MicrosoftAppId"]) - .WithClientSecret(configuration["AzureAd:MicrosoftAppPassword"]) + IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(configuration["AzureAd:ClientId"]) + .WithClientSecret(configuration["AzureAd:AppSecret"]) .WithAuthority($"https://login.microsoftonline.com/{tenantId}") .Build(); diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/teamsapp.local.yml b/samples/tab-staggered-permission/csharp/StaggeredPermission/teamsapp.local.yml new file mode 100644 index 0000000000..0834734f7a --- /dev/null +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/teamsapp.local.yml @@ -0,0 +1,111 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-staggered-permission-csharp + +provision: + # Creates a new Azure Active Directory (AAD) app to authenticate users if + # the environment variable that stores clientId is empty + - uses: aadApp/create + with: + # Note: when you run aadApp/update, the AAD app name will be updated + # based on the definition in manifest. If you don't want to change the + # name, make sure the name in AAD manifest is the same with the name + # defined here. + name: tab-staggered-permission-aad + # If the value is false, the action will not generate client secret for you + generateClientSecret: true + # Authenticate users with a Microsoft work or school account in your + # organization's Azure AD tenant (for example, single tenant). + signInAudience: AzureADMultipleOrgs + # Write the information of created resources into environment file for the + # specified environment variable(s). + writeToEnvironmentFile: + clientId: AAD_APP_CLIENT_ID + # Environment variable that starts with `SECRET_` will be stored to the + # .env.{envName}.user environment file + clientSecret: SECRET_AAD_APP_CLIENT_SECRET + objectId: AAD_APP_OBJECT_ID + tenantId: AAD_APP_TENANT_ID + authority: AAD_APP_OAUTH_AUTHORITY + authorityHost: AAD_APP_OAUTH_AUTHORITY_HOST + + # Set TAB_DOMAIN and TAB_ENDPOINT for local launch + - uses: script + with: + run: + echo "::set-teamsfx-env TAB_DOMAIN=localhost:44302"; + echo "::set-teamsfx-env TAB_ENDPOINT=https://localhost:44302"; + + # Creates a Teams app + - uses: teamsApp/create + with: + # Teams app name + name: tab-staggered-permission-${{TEAMSFX_ENV}} + # Write the information of created resources into environment file for + # the specified environment variable(s). + writeToEnvironmentFile: + teamsAppId: TEAMS_APP_ID + + # Generate runtime appsettings to JSON file + - uses: file/createOrUpdateJsonFile + with: + target: ./appsettings.json + content: + AzureAd: + ClientId: ${{AAD_APP_CLIENT_ID}} + AppSecret: ${{SECRET_AAD_APP_CLIENT_SECRET}} + ApplicationIdURI: api://${{TAB_DOMAIN}}/${{AAD_APP_CLIENT_ID}} + + # Apply the AAD manifest to an existing AAD app. Will use the object id in + # manifest file to determine which AAD app to update. + - uses: aadApp/update + with: + # Relative path to this file. Environment variables in manifest will + # be replaced before apply to AAD app + manifestPath: ./aad.manifest.json + outputFilePath: ./build/aad.manifest.${{TEAMSFX_ENV}}.json + + # Validate using manifest schema + - uses: teamsApp/validateManifest + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + # Build Teams app package with latest env value + - uses: teamsApp/zipAppPackage + with: + # Path to manifest template + manifestPath: ./AppManifest/manifest.json + outputZipPath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + outputJsonPath: ./AppManifest/build/manifest.${{TEAMSFX_ENV}}.json + # Validate app package using validation rules + - uses: teamsApp/validateAppPackage + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + # Apply the Teams app manifest to an existing Teams app in + # Teams Developer Portal. + # Will use the app id in manifest file to determine which Teams app to update. + - uses: teamsApp/update + with: + # Relative path to this file. This is the path for built zip file. + appPackagePath: ./AppManifest/build/AppManifest.${{TEAMSFX_ENV}}.zip + + # Create or update debug profile in lauchsettings file + - uses: file/createOrUpdateJsonFile + with: + target: ./Properties/launchSettings.json + content: + profiles: + Microsoft Teams (browser): + commandName: "Project" + dotnetRunMessages: true + launchBrowser: true + launchUrl: "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&appTenantId=${{TEAMS_APP_TENANT_ID}}&login_hint=${{TEAMSFX_M365_USER_NAME}}" + applicationUrl: "https://localhost:44302;http://localhost:2544" + environmentVariables: + ASPNETCORE_ENVIRONMENT: "Development" + hotReloadProfile: "aspnetcore" \ No newline at end of file diff --git a/samples/tab-staggered-permission/csharp/StaggeredPermission/teamsapp.yml b/samples/tab-staggered-permission/csharp/StaggeredPermission/teamsapp.yml new file mode 100644 index 0000000000..edc751a5fe --- /dev/null +++ b/samples/tab-staggered-permission/csharp/StaggeredPermission/teamsapp.yml @@ -0,0 +1,9 @@ +# yaml-language-server: $schema=https://aka.ms/teams-toolkit/v1.2/yaml.schema.json +# Visit https://aka.ms/teamsfx-v5.0-guide for details on this file +# Visit https://aka.ms/teamsfx-actions for details on actions +version: v1.2 + +additionalMetadata: + sampleTag: Microsoft-Teams-Samples:tab-staggered-permission-csharp + +environmentFolderPath: ./env \ No newline at end of file