Skip to content

relayauth server package#10

Merged
khaliqgant merged 11 commits intomainfrom
server-package
Mar 27, 2026
Merged

relayauth server package#10
khaliqgant merged 11 commits intomainfrom
server-package

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

@khaliqgant khaliqgant commented Mar 27, 2026

So cloud can use the server package

Package Publishing

  • Renamed relayauth-server@relayauth/server
  • Version: 0.1.0, removed private: true
  • Added exports map (., ./worker, ./durable-objects)
  • Fixed imports to use package paths instead of relative source paths
  • Refactored worker.ts exports
  • Added exports test
  • Updated publish workflow

Bug Fixes (from PR #9)

  1. Webhook 4xx retry bug — 4xx client errors now fail immediately instead of being retried with exponential backoff
  2. sponsorChain duplication — now appends the new identity's ID instead of duplicating the parent sub
  3. Test assertion — updated to match corrected sponsorChain behavior

Next Steps

Once published, AgentWorkforce/cloud PR #56 will update packages/relayauth/ to import from @relayauth/server instead of using relative path re-exports.

khaliqgant and others added 2 commits March 27, 2026 20:23
…cation)

Cherry-picked from PR #9:
1. audit-webhook-dispatcher: 4xx client errors now fail immediately
   instead of being caught and retried
2. identities.ts: sponsorChain now appends the NEW identity ID instead
   of duplicating the parent sub
3. create-identity.test.ts: Updated assertion accordingly

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
npm replaces workspace:* with the actual version on publish (e.g. ^0.1.2).
Bare * is dangerous — resolves to any version including breaking changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

khaliqgant and others added 2 commits March 27, 2026 21:23
publish.yml: add relayauth to publish-all matrix to prevent version drift
audit-webhook-dispatcher.ts: use regex /status 4\d{2}/ for precise 4xx matching
package.json: regenerate package-lock.json for @agent-relay/sdk 3.2.21
cloudflare.ts: hoist createApp() to module-level singleton for rate limiter persistence
policies.ts: replace permissive IPv6 regex with proper validation

Co-Authored-By: My Senior Dev <dev@myseniordev.com>
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 new potential issues.

View 18 additional findings in Devin Review.

Open in Devin Review

"dev": "wrangler dev",
"build": "tsc",
"typecheck": "tsc --noEmit",
"test": "node --test --import tsx src/__tests__/*.test.ts"
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot Mar 27, 2026

Choose a reason for hiding this comment

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

🔴 Test script silently drops all e2e tests from the test suite

The test script in packages/server/package.json was changed from "node --test --import tsx src/__tests__/*.test.ts src/__tests__/e2e/*.test.ts" to "node --test --import tsx src/__tests__/*.test.ts", removing the src/__tests__/e2e/*.test.ts glob. The e2e test files still exist and are actively modified in this PR (e.g., packages/server/src/__tests__/e2e/rbac.test.ts), but they will no longer be executed when running npm test in the server package. This means RBAC e2e tests—which verify critical authorization flows—are silently excluded from CI.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

OSS @relayauth/server is now runtime-agnostic:
- storage/interface.ts — abstract storage interface
- storage/sqlite.ts — local adapter (Node.js)
- entrypoints/node.ts — Node.js entry point
- No Cloudflare dependencies in OSS

Cloud owns the Cloudflare-specific code:
- storage/cloudflare.ts — D1/KV/DO adapter (moved to cloud)
- entrypoints/cloudflare.ts — Worker entry point (moved to cloud)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

khaliqgant and others added 3 commits March 27, 2026 21:52
Fixed SQLite storage adapter to match Cloudflare adapter behavior:
- Identity CRUD with budget tracking, sponsor chains, auto-suspend
- Audit logging with filtering, pagination, and export
- Role/policy CRUD with org/workspace scoping
- Token revocation
- Removed all Cloudflare references from test helpers
- Two minor type fixes (null vs undefined, string vs IdentityType)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

⚠️ 1 issue in files not directly in the diff

⚠️ Role and policy UPDATE SQL does not update serialized data column, causing stale reads in test infrastructure (packages/server/src/storage/sqlite.ts:324-330)

Both UPDATE_ROLE_SQL (line 324-330) and UPDATE_POLICY_SQL (line 376-384) update individual columns (name, description, scopes_json, etc.) but omit SET data = ?. The INSERT path correctly writes the full JSON to data, but after an UPDATE the data column retains the pre-update JSON blob. The new test infrastructure added in this PR reads directly from the data column to reconstruct scenario state (role-crud.test.ts:437-451, policy-crud.test.ts:528-546, role-assignment.test.ts:344-374), causing tests to operate on stale role/policy data after update operations. The production application reads from individual columns (not data), so this is limited to test correctness.

View 21 additional findings in Devin Review.

Open in Devin Review

- test-helpers.ts: always use SQLite, remove createCloudflareStorage path
- audit-logger.test.ts: query SQLite audit log instead of D1 recording
- worker.ts: remove default app singleton (throws without storage)
- index.ts: remove default app re-export
- package.json: add test:e2e script for e2e tests (separate from unit)
- package-lock.json: regenerated

251 unit tests pass, 0 failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@khaliqgant khaliqgant merged commit eae7dc2 into main Mar 27, 2026
1 check passed
@khaliqgant khaliqgant deleted the server-package branch March 27, 2026 22:29
Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View 23 additional findings in Devin Review.

Open in Devin Review

Comment on lines +25 to +30
export function resolvePolicyStorage(source: PolicyStorageSource): PolicyStorage {
if (typeof source === "object" && source !== null && "policies" in source) {
return (source as Pick<AuthStorage, "policies">).policies;
}
return source as PolicyStorage;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 resolvePolicyStorage and resolveRoleStorage silently mishandle D1Database despite accepting it in their type signatures

The type aliases PolicyStorageSource and RoleStorageSource (used by engine/policies.ts and engine/roles.ts) include D1Database as a valid input, but resolvePolicyStorage and resolveRoleStorage in packages/server/src/storage/compat.ts only detect AuthStorage (via "policies" in source / "roles" in source) and fall through to an unsafe cast return source as PolicyStorage for anything else, including D1Database. If a D1Database were passed (e.g., during a future refactor or from external consumers of the exported engine functions), it would be silently cast to PolicyStorage/RoleStorage and fail at runtime when .create(), .get(), etc. are called. In contrast, resolveAuthStorage and resolveAuditStorage both correctly detect D1Database via "prepare" in source and wrap it.

Prompt for agents
In packages/server/src/storage/compat.ts, add D1Database detection (via "prepare" in source) to both resolvePolicyStorage and resolveRoleStorage, similar to how resolveAuthStorage and resolveAuditStorage handle it. When a D1Database is detected, call createDatabaseStorage(source as D1Database) and extract the .policies or .roles sub-storage respectively. This ensures the type contract (PolicyStorageSource = D1Database | ...) is honored at runtime.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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