<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dev365</title>
    <description>The latest articles on DEV Community by Dev365 (@dev365).</description>
    <link>https://dev.to/dev365</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F496416%2Fd27183ee-de4b-4286-95db-18489782df8a.png</url>
      <title>DEV Community: Dev365</title>
      <link>https://dev.to/dev365</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dev365"/>
    <language>en</language>
    <item>
      <title>What details can be accessed via Teams context</title>
      <dc:creator>Dev365</dc:creator>
      <pubDate>Thu, 11 Feb 2021 08:20:25 +0000</pubDate>
      <link>https://dev.to/dev365/what-details-can-be-accessed-via-teams-context-3m2g</link>
      <guid>https://dev.to/dev365/what-details-can-be-accessed-via-teams-context-3m2g</guid>
      <description>&lt;p&gt;When you are building a Microsoft Teams Tap app, you might want to know what kind of information are exposed via the teams context.&lt;/p&gt;

&lt;p&gt;Context details are revealed about some user, team and company information. following code &lt;em&gt;foreach&lt;/em&gt; context properties that is taken from personal tab app&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Object.keys(microsoftTeams.context).forEach(key =&amp;gt; { &lt;br&gt;
//...       &lt;br&gt;
});&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;locale&lt;/strong&gt;: en-us&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;theme&lt;/strong&gt;: default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;entityId&lt;/strong&gt;: personal-tab-entityId&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;subEntityId&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;isFullScreen&lt;/strong&gt;: false&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sessionId&lt;/strong&gt;: 6a9040ee-3e75-b7b1-1c34-b33cb38e4c22&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;chatId&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;meetingId&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hostClientType&lt;/strong&gt;: web&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tenantSKU&lt;/strong&gt;: unknown&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jsonTabUrl&lt;/strong&gt;: microsoft-teams-json-tab.azurewebsites.net&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;userLicenseType&lt;/strong&gt;: Unknown&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;appSessionId&lt;/strong&gt;: c94922f8-6cfb-425a-9675-034631329eae&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;isMultiWindow&lt;/strong&gt;: false&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;appIconPosition&lt;/strong&gt;: 303&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;frameContext&lt;/strong&gt;: content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;teamSiteDomain&lt;/strong&gt;: abc.sharepoint.com&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;teamSitePath&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;teamSiteUrl&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ringId&lt;/strong&gt;: general&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;tid&lt;/strong&gt;: 22235f37-6421-4209-a601-aad98974a222&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;loginHint&lt;/strong&gt;: &lt;a href="mailto:admin@abc.onmicrosoft.com"&gt;admin@abc.onmicrosoft.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;upn&lt;/strong&gt;: &lt;a href="mailto:admi@abc.onmicrosoft.com"&gt;admi@abc.onmicrosoft.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;userPrincipalName&lt;/strong&gt;: &lt;a href="mailto:admin@abc.onmicrosoft.com"&gt;admin@abc.onmicrosoft.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;userObjectId&lt;/strong&gt;: 226ca1c0-2108-4be7-955b-90f39abdcc22&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;more details can be found here &lt;br&gt;
&lt;a href="https://docs.microsoft.com/en-us/microsoftteams/platform/tabs/how-to/access-teams-context#getting-context-by-inserting-url-placeholder-values"&gt;https://docs.microsoft.com/en-us/microsoftteams/platform/tabs/how-to/access-teams-context#getting-context-by-inserting-url-placeholder-values&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microsofteams</category>
    </item>
    <item>
      <title>IdentityServer4 from the scratch - Part 1</title>
      <dc:creator>Dev365</dc:creator>
      <pubDate>Tue, 26 Jan 2021 10:58:20 +0000</pubDate>
      <link>https://dev.to/dev365/identityserver4-from-the-scratch-part-1-3gbg</link>
      <guid>https://dev.to/dev365/identityserver4-from-the-scratch-part-1-3gbg</guid>
      <description>&lt;h3&gt;
  
  
  Why IdentityServer
&lt;/h3&gt;

&lt;p&gt;if you have number of applications, but you need to Centralized login logic and workflow for all of your applications (web, native, mobile, services). IdentityServer might be your solution. It also enable Single sign capability . IdentityServer4 is an officially certified implementation of OpenID Connect.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating IdentityServer4 project
&lt;/h3&gt;

&lt;p&gt;Simplest way to create an identity server instance is to use &lt;strong&gt;dotnet&lt;/strong&gt; template. dotnet template can be installed as below&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new-i identityserver4.template&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;but in this  IdentityServer4 post series, lets starts from scratch&lt;/p&gt;

&lt;p&gt;Create an empty web project based on net core using command prompt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new web 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmvmm0gewaivgf3mnaxdw.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmvmm0gewaivgf3mnaxdw.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project is nothing much more than program cs file and a startup cs files &amp;amp; it will run on port &lt;strong&gt;5443&lt;/strong&gt; for &lt;strong&gt;https&lt;/strong&gt; and &lt;strong&gt;5000&lt;/strong&gt; for &lt;strong&gt;http&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;IdentityServer4 nuget package can be added to this project using following commands&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet add package IdentityServer4 --version 4.1.1  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmyrxurv50ycog5blzruc.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmyrxurv50ycog5blzruc.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;go into &lt;em&gt;startup.cs&lt;/em&gt;  to configure identity server and services  code in ConfigureServices&lt;br&gt;
It has been configured to empty list of Clients, IdentityResources, ApiScopes, ApiResources and Users for now.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;AddDeveloperSigningCredential()&lt;/em&gt; is added here(Dev mode only) because various things in the tokens that identity server delivers for us needs to be signed and this developer signing credential &lt;br&gt;
provides that signing material. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Add identity server into the pipeline &lt;br&gt;
Remember the identity server is a piece of middleware&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;we're now ready to go now at the moment we have no apis defined. we have no clients defined and we have no users&lt;br&gt;
defined but we can still run this.&lt;br&gt;
Application runs at the moment we have no controllers and&lt;br&gt;
viewers here so it's simply printing out hello world.👋 &lt;/p&gt;

&lt;p&gt;if you run&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;dotnet run&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 Our identityserver will run 0n &lt;a href="https://localhost:5001" rel="noopener noreferrer"&gt;https://localhost:5001&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also open-id-connect discovery document can be found here &lt;/p&gt;

&lt;p&gt;&lt;a href="https://localhost:5001/.well-known/openid-configuration" rel="noopener noreferrer"&gt;https://localhost:5001/.well-known/openid-configuration&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "issuer": "https://localhost:5001",
  "jwks_uri": "https://localhost:5001/.well-known/openid-configuration/jwks",
  "authorization_endpoint": "https://localhost:5001/connect/authorize",
  "token_endpoint": "https://localhost:5001/connect/token",
  "userinfo_endpoint": "https://localhost:5001/connect/userinfo",
  "end_session_endpoint": "https://localhost:5001/connect/endsession",
  "check_session_iframe": "https://localhost:5001/connect/checksession",
  "revocation_endpoint": "https://localhost:5001/connect/revocation",
  "introspection_endpoint": "https://localhost:5001/connect/introspect",
  "device_authorization_endpoint": "https://localhost:5001/connect/deviceauthorization",
  "frontchannel_logout_supported": true,
  "frontchannel_logout_session_supported": true,
  "backchannel_logout_supported": true,
  "backchannel_logout_session_supported": true,
  "scopes_supported": [
    "offline_access"
  ],
  "claims_supported": [],
  "grant_types_supported": [
    "authorization_code",
    "client_credentials",
    "refresh_token",
    "implicit",
    "password",
    "urn:ietf:params:oauth:grant-type:device_code"
  ],
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "id_token token",
    "code id_token",
    "code token",
    "code id_token token"
  ],
  "response_modes_supported": [
    "form_post",
    "query",
    "fragment"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "subject_types_supported": [
    "public"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ],
  "request_parameter_supported": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you look carefully at discover endpoint, There's some defaults values for grant types and&lt;br&gt;
default response types but notice there are no&lt;br&gt;
claims here yet and the only supported scope is offline access&lt;/p&gt;

&lt;p&gt;In next post , we will see how our scopes, claims, resources ,clients are changed &lt;/p&gt;

</description>
      <category>identityserver4</category>
    </item>
    <item>
      <title>Persist state and settings in Microsoft office add-ins</title>
      <dc:creator>Dev365</dc:creator>
      <pubDate>Thu, 29 Oct 2020 13:30:10 +0000</pubDate>
      <link>https://dev.to/dev365/persist-state-and-settings-in-microsoft-office-add-ins-2528</link>
      <guid>https://dev.to/dev365/persist-state-and-settings-in-microsoft-office-add-ins-2528</guid>
      <description>&lt;p&gt;The Office JavaScript API provides objects for your add-in to save state across user sessions. &lt;br&gt;
Office js api provides following objects to save state according to user sessions&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Office.CustomProperties&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Office.CustomXmlParts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Office.RoamingSettings&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Office.Settings&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Settings&lt;/strong&gt; office api object is used to store data on the document, workbook, or presentation&lt;br&gt;
&lt;strong&gt;CustomXmlParts&lt;/strong&gt; object is used to store data in a custom XML part of the document or workbook.&lt;br&gt;
&lt;strong&gt;CustomProperties&lt;/strong&gt; and &lt;strong&gt;RoamingSettings&lt;/strong&gt; office api objects are supported MailApp add-ins.data is stored as Data is stored  user's Exchange mailbox as key value pair&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>officejs</category>
    </item>
    <item>
      <title>How to check if requirement sets are supported by your add-in's Office host</title>
      <dc:creator>Dev365</dc:creator>
      <pubDate>Thu, 29 Oct 2020 11:06:01 +0000</pubDate>
      <link>https://dev.to/dev365/how-to-check-if-requirement-sets-are-supported-by-your-add-in-s-office-host-h4l</link>
      <guid>https://dev.to/dev365/how-to-check-if-requirement-sets-are-supported-by-your-add-in-s-office-host-h4l</guid>
      <description>&lt;p&gt;using &lt;code&gt;Office.context.requirements.isSetSupported&lt;/code&gt;, It is possible to programmatically check if requirement sets are supported by your add-in's Office host.&lt;br&gt;
if the Office host doesn't support the requirement set, &lt;code&gt;isSetSupported&lt;/code&gt; returns false&lt;/p&gt;

&lt;p&gt;The following code shows the usage of &lt;code&gt;isSetSupported&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (Office.context.requirements.isSetSupported(RequirementSetName, MinimumVersion)) {
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (Office.context.requirements.isSetSupported('WordApi', '1.1'))
{
    // Run code that provides additional functionality using the Word JavaScript API when the add-in runs in Word 2016 or later.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>office365addin</category>
    </item>
    <item>
      <title>Search and highlight text using word add-in</title>
      <dc:creator>Dev365</dc:creator>
      <pubDate>Mon, 26 Oct 2020 05:50:45 +0000</pubDate>
      <link>https://dev.to/dev365/search-and-highlight-text-using-word-add-in-479m</link>
      <guid>https://dev.to/dev365/search-and-highlight-text-using-word-add-in-479m</guid>
      <description>&lt;p&gt;If you want to search the word document for text and need to highlight with a color, following code can be used&lt;br&gt;
This code sample searches for the text "Office" and ignores punctuation. If the text is found, the matches are bolded, highlighted in yellow, and the font color set to purple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; // Run a batch operation against the Word object model.
Word.run(function (context) {
  // Queue a command to search the document and ignore punctuation.
  var searchResults = context.document.body.search('Office', {ignorePunct: true});

  // Queue a command to load the search results and get the font property values.
  context.load(searchResults, 'font');

  // Synchronize the document state by executing the queued commands,
  // and return a promise to indicate task completion.
  return context.sync().then(function () {
      console.log('Found count: ' + searchResults.items.length);

      // Queue a set of commands to change the font for each found item.
      for (var i = 0; i &amp;lt; searchResults.items.length; i++) {
        searchResults.items[i].font.color = 'purple';
        searchResults.items[i].font.highlightColor = '#FFFF00'; // Yellow
        searchResults.items[i].font.bold = true;
      }

      // Synchronize the document state by executing the queued commands,
      // and return a promise to indicate task completion.
      return context.sync();
  });
})
.catch(function (error) {
  console.log('Error: ' + JSON.stringify(error));
  if (error instanceof OfficeExtension.Error) {
    console.log('Debug info: ' + JSON.stringify(error.debugInfo));
  }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>microsoft365</category>
    </item>
    <item>
      <title>Validating an Office add-in's manifest file</title>
      <dc:creator>Dev365</dc:creator>
      <pubDate>Sun, 25 Oct 2020 18:31:03 +0000</pubDate>
      <link>https://dev.to/dev365/validating-an-office-add-in-s-manifest-file-5akp</link>
      <guid>https://dev.to/dev365/validating-an-office-add-in-s-manifest-file-5akp</guid>
      <description>&lt;p&gt;The Office add-ins manifest validator examines your add-in's manifest file to determine if it's correct and complete. &lt;br&gt;
If you created your add-in project using the Yeoman generator for Office add-ins (version 1.1.17 or later), &lt;br&gt;
you can validate the manifest by running the following command in the root directory of the project.&lt;/p&gt;

&lt;p&gt;Console&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm run validate&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;If you didn't use the Yeoman generator to create your add-in project, you can validate your add-in's manifest by completing the following steps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install Node.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the following command in the root directory of your project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;&lt;br&gt;
Replace &lt;strong&gt;MANIFEST_FILE&lt;/strong&gt; with the name of your manifest file.&lt;/p&gt;

&lt;p&gt;Console&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx office-addin-manifest validate {{MANIFEST_FILE}}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

</description>
      <category>officejs</category>
    </item>
  </channel>
</rss>
