<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
  ThouShaltNotClick — Outlook Add-in
  Education Technology Professionals LLC
  Manifest schema: Office Add-in MailApp 1.1
  Requirement set: Mailbox 1.5 — see the derivation at the <Requirements> block.

  ⚠️  v23.1106 — this line said "Mailbox 1.10 (universal across Outlook
      web/desktop/mobile)" while BOTH declarations below have said 1.5 since
      v23.1006. It was stale AND its parenthetical was the precise falsehood
      that caused the original defect: 1.10 is not universal, and declaring it
      silently excluded every on-premises/hybrid Exchange (2016, 2019 and
      Subscription Edition all cap at 1.5), LTSC Outlook 2021 (1.9), classic
      Outlook on Mac (1.8) and Outlook on the web against on-prem Exchange
      (1.6) — i.e. much of the K-12 diocese population this product sells to.
      The floor is derived from what the add-in actually CALLS. Do not raise it
      to enable a feature without listing exactly who that excludes.

  ⚠️  THE <Id> GUID BELOW IS THE STABLE PRODUCTION IDENTITY.
  Do NOT regenerate it between versions — M365 admin center treats a new
  GUID as a brand-new add-in (existing installs would not auto-update).
  Bump <Version> in MAJOR.MINOR.BUILD.REVISION format for every release.
-->
<OfficeApp
  xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0"
  xmlns:mailappor="http://schemas.microsoft.com/office/mailappversionoverrides/1.0"
  xsi:type="MailApp">

  <Id>363fd840-de28-405d-955f-fb1fd5c87e94</Id>
  <Version>1.0.5.0</Version>
  <ProviderName>Education Technology Professionals LLC</ProviderName>
  <DefaultLocale>en-US</DefaultLocale>
  <DisplayName DefaultValue="ThouShaltNotClick"/>
  <Description DefaultValue="Catches phishing in Outlook. Real-time AI analysis, link trust scores, and one-click reporting — built on ETP&apos;s 10 years on the front lines of school IT."/>
  <IconUrl DefaultValue="https://outlook.thoushaltnotclick.com/icon-32.png"/>
  <HighResolutionIconUrl DefaultValue="https://outlook.thoushaltnotclick.com/icon-64.png"/>
  <SupportUrl DefaultValue="https://www.thoushaltnotclick.com/help/admin/outlook-addin-setup"/>

  <!-- AppDomains: every cross-origin host the add-in's task pane or auth dialog
       may navigate to. The auth dialog opens www.thoushaltnotclick.com/login.
       Office uses this list to decide whether to open the URL inside the
       embedded browser or pop a system browser. Without the domain listed,
       the auth flow breaks on Outlook desktop. -->
  <AppDomains>
    <AppDomain>https://www.thoushaltnotclick.com</AppDomain>
    <AppDomain>https://thoushaltnotclick.com</AppDomain>
    <AppDomain>https://outlook.thoushaltnotclick.com</AppDomain>
    <AppDomain>https://login.microsoftonline.com</AppDomain>
    <AppDomain>https://accounts.google.com</AppDomain>
  </AppDomains>

  <Hosts>
    <Host Name="Mailbox"/>
  </Hosts>

  <!-- ════════════════════════════════════════════════════════════════════
       MinVersion 1.5 — derived from what this add-in ACTUALLY calls.
       Do not raise it without a matching API that needs the higher set.
       ════════════════════════════════════════════════════════════════════
       Microsoft: "The minimum requirement set specified in the manifest
       determines which Outlook clients can load the add-in. If the Outlook
       client does not support at least the specified version, the add-in will
       not load." So this number is not a formality — it is an exclusion list.

       Our true floor, API by API:
         item.from / .subject / .itemId / .dateTimeCreated   Mailbox 1.1
         item.body.getAsync                                  Mailbox 1.3
         MessageReadCommandSurface / ShowTaskpane /
           ExecuteFunction (the ribbon below)                Mailbox 1.3
         SupportsPinning                                     Mailbox 1.5  &lt;- highest
       Nothing here needs 1.10.

       This previously said 1.10, which silently excluded:
         - EVERY on-premises / hybrid Exchange environment (2016, 2019 and
           Subscription Edition all cap at 1.5) — the add-in cannot be added
           there at all when the manifest asks for more than the server has
         - volume-licensed LTSC Outlook 2021 (caps at 1.9)
         - classic Outlook on Mac (caps at 1.8)
         - classic Outlook on the web against on-prem Exchange (caps at 1.6)
         - classic Outlook on Windows older than Version 2104 / April 2021
       K-12 dioceses are exactly the population still running on-prem or LTSC
       Exchange, so this excluded the customers most likely to need us — and
       it did so invisibly, with no error anyone could report.

       The 1.1-schema fallback comment directly below has always said it
       exists for builds below Mailbox 1.5. With a 1.10 floor that was
       unreachable: the file documented an intent its own requirement blocked.

       Microsoft guidance is explicit: "Developers should use the earliest
       requirement set that contains the critical set of APIs for their
       scenario, without which the add-in will not work." Using a LATER set
       costs nothing at runtime — Office.context.requirements.isSetSupported()
       still gates anything newer we ever add.
       Source: learn.microsoft.com/javascript/api/requirement-sets/outlook/
               outlook-api-requirement-sets (checked 2026-09-01) -->
  <Requirements>
    <Sets>
      <Set Name="Mailbox" MinVersion="1.5"/>
    </Sets>
  </Requirements>

  <!-- 1.1-schema fallback. Modern clients use VersionOverrides below; older
       Outlook builds (anything < Mailbox 1.5) read this. We declare a Read-mode
       task pane so even a downlevel client gets the verdict panel via Outlook's
       "Get Add-ins" classic ribbon.

       ⚠️  v23.990 — the task pane is /taskpane.html (a STATIC page), NOT the
       /taskpane Next.js route. Do not "tidy" this back. Outlook Classic on the
       desktop would not run the Next route: Office.js loaded, _host_Info was
       present on the URL, and Office.onReady never fired, so the pane never
       received a mailbox. The cause is that a Next App Router nested layout
       renders into <body>, so office.js sat in <body>; Microsoft requires it in
       <head>, and commands.html — which has always worked on the same machine —
       loads it from <head>. /taskpane.html is a static shell we control that
       loads office.js from <head> with the same React app bundled in.
       Outlook on the web and New Outlook are browser-based and tolerate the
       <body> placement, which is why this stayed hidden until someone tried
       Classic. Both URLs below must point at the .html file. -->
  <FormSettings>
    <Form xsi:type="ItemRead">
      <DesktopSettings>
        <SourceLocation DefaultValue="https://outlook.thoushaltnotclick.com/taskpane.html"/>
        <RequestedHeight>450</RequestedHeight>
      </DesktopSettings>
    </Form>
  </FormSettings>

  <!-- v23.907 — least privilege: the add-in only reads the open item (from/
       subject/body) and writes notification banners (item.notificationMessages),
       both covered by ReadWriteItem. It calls NO ReadWriteMailbox-only API (no
       makeEwsRequestAsync / cross-mailbox REST), so the higher tier only added
       a broader tenant-admin consent prompt. -->
  <Permissions>ReadWriteItem</Permissions>

  <!-- Activation rule. Show the add-in for any read message item — this is the
       broadest sensible scope. We explicitly do NOT include appointment/meeting
       items in v1 since the panel UX is email-centric. -->
  <Rule xsi:type="ItemIs" ItemType="Message" FormType="Read"/>

  <DisableEntityHighlighting>false</DisableEntityHighlighting>

  <!-- ════════════════════════════════════════════════════════════════════
       VersionOverrides 1.1 — modern Outlook clients (web, desktop ≥2016,
       mobile). Adds the explicit ribbon group with three buttons:
         1. Open TSNC Panel    (ShowTaskpane action)
         2. Report Phishing    (ExecuteFunction action — no UI)
         3. Mark as Safe       (ExecuteFunction action — no UI)
       The two ExecuteFunction buttons run handlers in commands.html that
       call our existing /report-phishing and /report-safe endpoints, then
       surface a notification on the email itself.
       ════════════════════════════════════════════════════════════════════ -->
  <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides" xsi:type="VersionOverridesV1_0">
    <VersionOverrides xmlns="http://schemas.microsoft.com/office/mailappversionoverrides/1.1" xsi:type="VersionOverridesV1_1">
      <!-- 1.5, matching the top-level Requirements block. This one gates the
           ribbon + task pane below; add-in commands need 1.3 and
           SupportsPinning needs 1.5, so 1.5 is the real floor here too.
           Keep the two blocks in step: a VersionOverrides floor higher than
           the top-level one means downlevel clients install the add-in and
           then get no ribbon button, which looks like a broken install. -->
      <Requirements>
        <bt:Sets DefaultMinVersion="1.5">
          <bt:Set Name="Mailbox" MinVersion="1.5"/>
        </bt:Sets>
      </Requirements>

      <Hosts>
        <Host xsi:type="MailHost">
          <DesktopFormFactor>
            <!-- The hidden function file that hosts our ExecuteFunction
                 handlers. Loaded into a sandboxed background runtime,
                 NOT visible to the user. -->
            <FunctionFile resid="Commands.Url"/>

            <!-- Read message ribbon -->
            <ExtensionPoint xsi:type="MessageReadCommandSurface">
              <OfficeTab id="TabDefault">
                <Group id="msgReadTsncGroup">
                  <Label resid="GroupLabel"/>

                  <!-- Button 1: open the TSNC task pane -->
                  <Control xsi:type="Button" id="msgReadOpenPanelBtn">
                    <Label resid="OpenPanel.Label"/>
                    <Supertip>
                      <Title resid="OpenPanel.Label"/>
                      <Description resid="OpenPanel.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Icon.16"/>
                      <bt:Image size="32" resid="Icon.32"/>
                      <bt:Image size="80" resid="Icon.80"/>
                    </Icon>
                    <Action xsi:type="ShowTaskpane">
                      <SourceLocation resid="Taskpane.Url"/>
                      <SupportsPinning>true</SupportsPinning>
                    </Action>
                  </Control>

                  <!-- Button 1b: "Trust Score" — score the CURRENTLY-selected email and
                       show the verdict as a banner. ExecuteFunction = fresh activation on
                       the focused message, so this is the reliable "view live score for
                       THIS email" on New Outlook (the task pane freezes on its launch email). -->
                  <Control xsi:type="Button" id="msgReadTrustScoreBtn">
                    <Label resid="TrustScore.Label"/>
                    <Supertip>
                      <Title resid="TrustScore.Label"/>
                      <Description resid="TrustScore.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="Icon.16"/>
                      <bt:Image size="32" resid="Icon.32"/>
                      <bt:Image size="80" resid="Icon.80"/>
                    </Icon>
                    <Action xsi:type="ExecuteFunction">
                      <FunctionName>quickTrustScore</FunctionName>
                    </Action>
                  </Control>

                  <!-- Button 2: quick-report phishing (no UI; notification only) -->
                  <Control xsi:type="Button" id="msgReadReportPhishingBtn">
                    <Label resid="ReportPhishing.Label"/>
                    <Supertip>
                      <Title resid="ReportPhishing.Label"/>
                      <Description resid="ReportPhishing.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="IconPhish.16"/>
                      <bt:Image size="32" resid="IconPhish.32"/>
                      <bt:Image size="80" resid="IconPhish.80"/>
                    </Icon>
                    <Action xsi:type="ExecuteFunction">
                      <FunctionName>quickReportPhishing</FunctionName>
                    </Action>
                  </Control>

                  <!-- Button 3: quick-mark safe (no UI; notification only) -->
                  <Control xsi:type="Button" id="msgReadReportSafeBtn">
                    <Label resid="ReportSafe.Label"/>
                    <Supertip>
                      <Title resid="ReportSafe.Label"/>
                      <Description resid="ReportSafe.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="IconSafe.16"/>
                      <bt:Image size="32" resid="IconSafe.32"/>
                      <bt:Image size="80" resid="IconSafe.80"/>
                    </Icon>
                    <Action xsi:type="ExecuteFunction">
                      <FunctionName>quickReportSafe</FunctionName>
                    </Action>
                  </Control>

                  <!-- Button 4: quick Community Alert (no UI; notification only).
                       ExecuteFunction = a FRESH activation on the CURRENTLY-selected
                       message, so it always alerts the email in focus (unlike the
                       pane, which freezes on New Outlook). Server-gated to org admins
                       + Org Reporters; others get a 403 with guidance in a banner. -->
                  <Control xsi:type="Button" id="msgReadCommunityAlertBtn">
                    <Label resid="CommunityAlert.Label"/>
                    <Supertip>
                      <Title resid="CommunityAlert.Label"/>
                      <Description resid="CommunityAlert.Tooltip"/>
                    </Supertip>
                    <Icon>
                      <bt:Image size="16" resid="IconPhish.16"/>
                      <bt:Image size="32" resid="IconPhish.32"/>
                      <bt:Image size="80" resid="IconPhish.80"/>
                    </Icon>
                    <Action xsi:type="ExecuteFunction">
                      <FunctionName>quickCommunityAlert</FunctionName>
                    </Action>
                  </Control>
                </Group>
              </OfficeTab>
            </ExtensionPoint>
          </DesktopFormFactor>
        </Host>
      </Hosts>

      <Resources>
        <bt:Images>
          <bt:Image id="Icon.16"      DefaultValue="https://outlook.thoushaltnotclick.com/icon-16.png"/>
          <bt:Image id="Icon.32"      DefaultValue="https://outlook.thoushaltnotclick.com/icon-32.png"/>
          <bt:Image id="Icon.80"      DefaultValue="https://outlook.thoushaltnotclick.com/icon-80.png"/>
          <bt:Image id="IconPhish.16" DefaultValue="https://outlook.thoushaltnotclick.com/icon-phish-16.png"/>
          <bt:Image id="IconPhish.32" DefaultValue="https://outlook.thoushaltnotclick.com/icon-phish-32.png"/>
          <bt:Image id="IconPhish.80" DefaultValue="https://outlook.thoushaltnotclick.com/icon-phish-80.png"/>
          <bt:Image id="IconSafe.16"  DefaultValue="https://outlook.thoushaltnotclick.com/icon-safe-16.png"/>
          <bt:Image id="IconSafe.32"  DefaultValue="https://outlook.thoushaltnotclick.com/icon-safe-32.png"/>
          <bt:Image id="IconSafe.80"  DefaultValue="https://outlook.thoushaltnotclick.com/icon-safe-80.png"/>
        </bt:Images>
        <bt:Urls>
          <bt:Url id="Commands.Url" DefaultValue="https://outlook.thoushaltnotclick.com/commands.html"/>
          <bt:Url id="Taskpane.Url" DefaultValue="https://outlook.thoushaltnotclick.com/taskpane.html"/>
        </bt:Urls>
        <bt:ShortStrings>
          <bt:String id="GroupLabel"           DefaultValue="ThouShaltNotClick"/>
          <bt:String id="OpenPanel.Label"      DefaultValue="TSNC Panel"/>
          <bt:String id="TrustScore.Label"     DefaultValue="Trust Score"/>
          <bt:String id="ReportPhishing.Label" DefaultValue="Report Phishing"/>
          <bt:String id="ReportSafe.Label"     DefaultValue="Mark as Safe"/>
          <bt:String id="CommunityAlert.Label" DefaultValue="Community Alert"/>
        </bt:ShortStrings>
        <bt:LongStrings>
          <bt:String id="OpenPanel.Tooltip"      DefaultValue="Open the ThouShaltNotClick analysis panel for this email."/>
          <bt:String id="TrustScore.Tooltip"     DefaultValue="Get the ThouShaltNotClick trust score for the email you have selected. Shows the verdict as a banner on the message."/>
          <bt:String id="ReportPhishing.Tooltip" DefaultValue="Report this email as phishing or suspicious. Sends to your school admin."/>
          <bt:String id="ReportSafe.Tooltip"     DefaultValue="Confirm this email is safe (you've verified the sender)."/>
          <bt:String id="CommunityAlert.Tooltip" DefaultValue="Instantly warn everyone in your organization about this sender. Org admins and Org Reporters only."/>
        </bt:LongStrings>
      </Resources>
    </VersionOverrides>
  </VersionOverrides>
</OfficeApp>
