Skip to content

feat(marketplace): expose github.clientId from discovery + harden publish auth#271

Open
masonjames wants to merge 3 commits intoemdash-cms:mainfrom
masonjames:marketplace-publish-auth
Open

feat(marketplace): expose github.clientId from discovery + harden publish auth#271
masonjames wants to merge 3 commits intoemdash-cms:mainfrom
masonjames:marketplace-publish-auth

Conversation

@masonjames
Copy link
Copy Markdown

@masonjames masonjames commented Apr 5, 2026

What does this PR do?

Hardens the marketplace GitHub auth discovery/publish flow so partial or missing OAuth configuration fails clearly instead of advertising a broken device-login path.

It also adds the email:status hook to core typing/manifest validation, updates the deploy smoke check to require github.enabled === true, and adds tests covering the discovery and manifest changes.

Type of change

  • Bug fix
  • Feature (requires approved Discussion)
  • Refactor (no behavior change)
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm --silent lint:json | jq '.diagnostics | length' returns 0
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

AI-generated code disclosure

  • This PR includes AI-generated code

Screenshots / test output

  • pnpm --silent lint:quick
  • pnpm --filter @emdash-cms/marketplace exec vitest run tests/publish-e2e.test.ts tests/manifest-schema.test.ts
  • pnpm --filter emdash exec vitest run tests/unit/cli/publish.test.ts tests/unit/plugins/define-plugin.test.ts tests/unit/plugins/manifest-schema.test.ts tests/unit/plugins/hooks.test.ts
  • pnpm typecheck
  • pnpm --silent lint:json | jq '.diagnostics | length'

Copilot AI review requested due to automatic review settings April 5, 2026 14:40
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 5, 2026

🦋 Changeset detected

Latest commit: 072c147

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 5, 2026


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


1 out of 2 committers have signed the CLA.
✅ (masonjames)[https://github.com/masonjames]
❌ @emdashbot[bot]
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates EmDash’s marketplace auth/discovery and publish flow so the CLI can discover the GitHub OAuth app at runtime, while also tightening failure behavior when marketplace auth is misconfigured. It also introduces a new email:status plugin hook type/schema entry and adds targeted unit/e2e coverage.

Changes:

  • Expose github.clientId from GET /api/v1/auth/discovery and harden marketplace GitHub auth routes to return clear 503s when OAuth config is missing.
  • Fix the CLI GitHub Device Flow requests to use application/x-www-form-urlencoded, and add unit tests for encoding + redirect middleware DB fallback.
  • Add email:status to core hook typing, hook pipeline capability gating, and manifest validation; update docs + deploy workflow accordingly.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/marketplace/wrangler.jsonc Documents required Worker secrets for production deploys.
packages/marketplace/tests/publish-e2e.test.ts Adds e2e assertions for discovery payload and 503 behavior when OAuth config is missing.
packages/marketplace/src/routes/public.ts Returns discovery payload including github.clientId.
packages/marketplace/src/routes/author.ts Adds shared GitHub OAuth config validation + clearer 503 errors for misconfigurations.
packages/marketplace/README.md Documents production deploy secret requirements and a post-deploy discovery check.
packages/core/tests/unit/redirects/middleware.test.ts Adds unit coverage for redirect middleware DB fallback behavior.
packages/core/tests/unit/plugins/manifest-schema.test.ts Ensures manifests accept the new email:status hook.
packages/core/tests/unit/plugins/define-plugin.test.ts Ensures definePlugin resolves/retains email:status hooks.
packages/core/tests/unit/cli/publish.test.ts Adds unit test for form-urlencoded encoding used by GitHub device flow.
packages/core/src/plugins/types.ts Introduces EmailStatusEvent + EmailStatusHandler and registers the hook in types.
packages/core/src/plugins/manifest-schema.ts Adds email:status to manifest hook allowlist.
packages/core/src/plugins/hooks.ts Registers email:status in the pipeline and gates it behind email:provide.
packages/core/src/cli/commands/publish.ts Uses discovery github.clientId, fails fast if missing, and switches GitHub device flow to form-urlencoded.
packages/core/src/astro/middleware/redirect.ts Falls back to getDb() when locals.emdash isn’t available for anonymous requests.
docs/src/content/docs/reference/configuration.mdx Updates plugin configuration guidance and “paired trusted/marketplace” guidance.
docs/src/content/docs/plugins/sandbox.mdx Adds guidance on paired trusted + marketplace packages.
docs/src/content/docs/plugins/publishing.mdx Documents paired package strategy for trusted vs sandbox-safe distributions.
docs/src/content/docs/plugins/installing.mdx Adds tip about paired trusted + marketplace packages.
.github/workflows/deploy-marketplace.yml Validates required secrets, pushes Worker secrets, deploys Worker, and smoke-checks discovery before seeding plugins.
.changeset/smooth-bugs-wave.md Adds a patch changeset describing the hook + marketplace auth hardening.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 16 to 21
publicRoutes.get("/auth/discovery", (c) => {
const clientId = typeof c.env.GITHUB_CLIENT_ID === "string" ? c.env.GITHUB_CLIENT_ID : "";
return c.json({
github: {
clientId: c.env.GITHUB_CLIENT_ID,
clientId,
deviceAuthorizationEndpoint: "https://github.com/login/device/code",
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

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

/auth/discovery returns clientId without trimming. If the Worker secret contains trailing whitespace/newlines (common when copy/pasting), discovery will expose a non-empty but invalid clientId, and the CLI will proceed until GitHub rejects the request. Consider .trim() here (matching getGitHubOAuthConfig() in author routes) so whitespace-only values become an empty string.

Copilot uses AI. Check for mistakes.
…lish auth

- Add `email:status` to the core plugin hook type/manifest schema so
  trusted SMTP plugins can subscribe to delivery status events.
- Expose `github.clientId` from `/api/v1/auth/discovery` so `emdash
  plugin login` / device flow can discover the marketplace GitHub OAuth
  app at runtime.
- Harden the CLI publish path and marketplace author/publish routes so
  configuration failures (missing OAuth client, missing seed token)
  surface clearly instead of silently returning an empty discovery
  payload.
- Update deploy-marketplace.yml to validate required secrets up front,
  push Worker secrets via wrangler before deploy, and smoke-check
  discovery after deploy.
- Refresh plugin docs (installing, publishing, sandbox, configuration)
  for the marketplace-publish auth flow.
- Add unit tests for the CLI publish command and redirect middleware.
@masonjames masonjames force-pushed the marketplace-publish-auth branch from daa6df5 to d5ccbd5 Compare April 5, 2026 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants