Problem:
The codebase supports both native gRPC and Connect-RPC protocols, but auth
service was using grpc.SetHeader() which only works for native gRPC. This
caused "failed to set grpc header" errors when using Connect-RPC clients
(browsers using nice-grpc-web).
Solution:
- Created HeaderCarrier pattern for protocol-agnostic header setting
- HeaderCarrier stores headers in context for Connect-RPC requests
- Falls back to grpc.SetHeader for native gRPC requests
- Updated auth service to use SetResponseHeader() instead of grpc.SetHeader()
- Refactored Connect wrappers to use withHeaderCarrier() helper to eliminate
code duplication
Additional fixes:
- Allow public methods when gRPC metadata is missing in ACL interceptor
- Properly handle ParseSessionCookieValue errors instead of ignoring them
- Fix buildSessionCookie to gracefully handle missing metadata
Files changed:
- server/router/api/v1/header_carrier.go: New protocol-agnostic header carrier
- server/router/api/v1/auth_service.go: Use SetResponseHeader, handle missing metadata
- server/router/api/v1/connect_services.go: Use withHeaderCarrier helper
- server/router/api/v1/acl.go: Allow public methods without metadata
- server/router/api/v1/connect_interceptors.go: Handle ParseSessionCookieValue errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements critical OAuth 2.0 security improvements to protect against authorization code interception attacks and improve provider compatibility:
- Add PKCE (RFC 7636) support with SHA-256 code challenge/verifier
- Fix access token extraction to use standard field instead of Extra()
- Add OAuth error parameter handling (access_denied, invalid_scope, etc.)
- Maintain backward compatibility for non-PKCE flows
This brings the OAuth implementation up to modern security standards as recommended by Auth0, Okta, and the OAuth 2.0 Security Best Current Practice (RFC 8252).
Backend changes:
- Add code_verifier parameter to ExchangeToken with PKCE support
- Use token.AccessToken for better provider compatibility
- Update proto definition with optional code_verifier field
Frontend changes:
- Generate cryptographically secure PKCE parameters
- Include code_challenge in authorization requests
- Handle and display OAuth provider errors gracefully
- Pass code_verifier during token exchange
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove work-related terminology by renaming "workspace" to "instance"
across the entire application. This change better reflects that Memos
is a self-hosted tool suitable for personal and non-work use cases.
Breaking Changes:
- API endpoints: /api/v1/workspace/* → /api/v1/instance/*
- gRPC service: WorkspaceService → InstanceService
- Proto types: WorkspaceSetting → InstanceSetting
- Frontend translation keys: workspace-section → instance-section
Backend Changes:
- Renamed proto definitions and regenerated code
- Updated all store layer methods and database drivers
- Renamed service implementations and API handlers
- Updated cache from workspaceSettingCache to instanceSettingCache
Frontend Changes:
- Renamed service client: workspaceServiceClient → instanceServiceClient
- Updated all React components and state management
- Refactored stores: workspace.ts → instance.ts
- Updated all 32 locale translation files
All tests pass and both backend and frontend build successfully.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add comprehensive inline documentation for auth services
- Document session-based and token-based authentication flows
- Clarify authentication priority and validation logic
- Add detailed comments for JWT token structure and claims
- Fix reactions seed data to use memo UIDs instead of numeric IDs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>