Skip to content

Add minimal Outlook 365 extension#2009

Open
benjaminshafii wants to merge 1 commit into
devfrom
feat/minimal-outlook-extension
Open

Add minimal Outlook 365 extension#2009
benjaminshafii wants to merge 1 commit into
devfrom
feat/minimal-outlook-extension

Conversation

@benjaminshafii
Copy link
Copy Markdown
Member

Summary

  • Add a minimal Outlook 365 built-in extension using Microsoft OAuth PKCE with only openid/profile/email/offline_access/User.Read.
  • Add server status/connect/test/disconnect routes, encrypted local token vault support, and extension action registration.
  • Add Settings UI, client API bindings, docs, and an env-gated mock connection path for automated testing without Microsoft credentials.

Testing

  • pnpm --filter openwork-server test src/extensions/outlook-365.test.ts
  • pnpm --filter openwork-server typecheck
  • pnpm --filter @openwork/app typecheck

Notes

  • Real Microsoft OAuth was not exercised because no Azure app client ID/test Microsoft account credentials were available in this environment.
  • Mock flow can be enabled with OPENWORK_OUTLOOK_365_MOCK=1, OPENWORK_DEV_MODE=1, and OPENWORK_OUTLOOK_365_ALLOW_PLAINTEXT_VAULT=1.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 29, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview, Comment May 29, 2026 11:57pm
openwork-den Ready Ready Preview, Comment May 29, 2026 11:57pm
openwork-den-worker-proxy Ready Ready Preview, Comment May 29, 2026 11:57pm
openwork-landing Ready Ready Preview, Comment, Open in v0 May 29, 2026 11:57pm

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 10 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/outlook-365-oauth.md">

<violation number="1" location="docs/outlook-365-oauth.md:11">
P2: The scope list is missing `offline_access`, which the code actually requests. This scope enables refresh tokens and should be documented since the purpose of this section is to communicate the exact permission set to administrators reviewing the Azure app registration.</violation>
</file>

<file name="apps/server/src/extensions/outlook-365.ts">

<violation number="1" location="apps/server/src/extensions/outlook-365.ts:447">
P2: Guard against duplicate OAuth callbacks by checking `flow.status === "pending"` before exchanging the code. Without this, a browser retry can overwrite a successful connection with a failed status.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread docs/outlook-365-oauth.md
openid
profile
email
User.Read
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The scope list is missing offline_access, which the code actually requests. This scope enables refresh tokens and should be documented since the purpose of this section is to communicate the exact permission set to administrators reviewing the Azure app registration.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docs/outlook-365-oauth.md, line 11:

<comment>The scope list is missing `offline_access`, which the code actually requests. This scope enables refresh tokens and should be documented since the purpose of this section is to communicate the exact permission set to administrators reviewing the Azure app registration.</comment>

<file context>
@@ -0,0 +1,34 @@
+openid
+profile
+email
+User.Read
+```
+
</file context>
Fix with Cubic

await finish(outlook365CallbackPage(400, "Outlook 365 connection failed", error));
return;
}
const returnedState = url.searchParams.get("state") ?? "";
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot May 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Guard against duplicate OAuth callbacks by checking flow.status === "pending" before exchanging the code. Without this, a browser retry can overwrite a successful connection with a failed status.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/server/src/extensions/outlook-365.ts, line 447:

<comment>Guard against duplicate OAuth callbacks by checking `flow.status === "pending"` before exchanging the code. Without this, a browser retry can overwrite a successful connection with a failed status.</comment>

<file context>
@@ -0,0 +1,548 @@
+            await finish(outlook365CallbackPage(400, "Outlook 365 connection failed", error));
+            return;
+          }
+          const returnedState = url.searchParams.get("state") ?? "";
+          const code = url.searchParams.get("code") ?? "";
+          if (returnedState !== flow.state || !code) {
</file context>
Fix with Cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant