feat: add PKCE OAuth boundary
Introduce provider-neutral HTTP contracts and public-client authorization-code orchestration with PKCE S256, strict HTTPS and loopback validation, constant-time state checks, secure OpenSSL entropy, and single-send token exchange semantics. Add independent protocol and adversarial suites covering RFC 7636, RFC3986 encoding, callback failures, response redaction, and no-retry behavior. Concrete networking, browser/listener, token parsing, Secret Service, and Graph integration remain separate follow-up slices.
This commit is contained in:
@@ -164,9 +164,29 @@ Conflict resolution is deterministic: unchanged side wins; otherwise retain
|
||||
both versions and mark a conflict for the user. Network work happens outside the
|
||||
render loop and publishes immutable snapshots to it.
|
||||
|
||||
The first provider-facing step after the cache is verified is an injectable HTTP
|
||||
boundary, browser-based authorization-code flow with PKCE, and fake transports
|
||||
for deterministic authentication and failure tests. Read-only Microsoft Graph
|
||||
calendar discovery and delta synchronization follows. Graph delta links remain
|
||||
opaque and are persisted only through the calendar/window transaction described
|
||||
above; remote writes and conflict resolution come later.
|
||||
### HTTP and OAuth boundary
|
||||
|
||||
Provider code depends on generic request/response and injected transport
|
||||
interfaces rather than a concrete networking library. Deterministic fakes make
|
||||
success, protocol failure, transport failure, cancellation, and malformed input
|
||||
testable without network access. The generic layer performs no automatic
|
||||
retries: only a provider knows whether an operation is idempotent and how to
|
||||
interpret service-specific throttling or retry guidance.
|
||||
|
||||
Microsoft authentication is designed for a public desktop client. It uses the
|
||||
system browser and authorization-code flow, a fresh PKCE verifier and `S256`
|
||||
challenge, and a loopback redirect. The Entra application registration is
|
||||
multitenant and selects the intended organizational and personal Microsoft
|
||||
account audience. The initial read-only Graph scope is the delegated
|
||||
`Calendars.Read` permission. It normally permits user consent, while tenant
|
||||
consent policy remains authoritative and may require administrator approval or
|
||||
block consent. A desktop binary distributed as open source is not a confidential
|
||||
client and must not embed or depend on a client secret.
|
||||
|
||||
This boundary does not yet contain a concrete HTTP transport, system-browser or
|
||||
loopback-listener adapter, token JSON parsing, a Secret Service backend, Graph
|
||||
requests, or usable account setup. Those concrete desktop, HTTP, and secret
|
||||
storage adapters are the next slice. Read-only Microsoft Graph calendar
|
||||
discovery and delta synchronization follows; delta links remain opaque and are
|
||||
persisted only through the calendar/window transaction described above. Remote
|
||||
writes and conflict resolution come later.
|
||||
|
||||
@@ -129,11 +129,25 @@ offline writes, but remote mutation behavior is not part of this phase. OAuth
|
||||
tokens and other credentials never belong in the calendar database; account
|
||||
secrets will be held by the Freedesktop Secret Service.
|
||||
|
||||
This foundation does not make Office 365 usable yet: Nocal currently performs no
|
||||
OAuth flow, HTTP request, or Microsoft Graph synchronization. The next product
|
||||
slice introduces injectable HTTP and PKCE authentication with fake transports,
|
||||
then adds read-only Graph delta synchronization. Remote writes remain gated on
|
||||
the durability and conflict paths being exercised end to end.
|
||||
The Microsoft sign-in design treats Nocal as a public desktop client: sign-in
|
||||
will open the system browser, use the authorization-code flow with PKCE `S256`,
|
||||
and return through a loopback redirect. Its application registration must be
|
||||
multitenant for the intended organizational and personal Microsoft account
|
||||
audience. Initial synchronization requests only delegated `Calendars.Read`, not
|
||||
write access. Users can normally consent to that delegated permission, but
|
||||
their organization's tenant policy may still require administrator consent or
|
||||
deny the application. Nocal never embeds a client secret in its open-source
|
||||
desktop binary.
|
||||
|
||||
The provider-neutral HTTP seam accepts an injected transport and can therefore
|
||||
be exercised with deterministic fakes. It intentionally owns no generic retry
|
||||
policy; provider operations must decide whether a retry is safe. This phase does
|
||||
not make Office 365 usable yet. It includes no concrete HTTP transport, real
|
||||
browser/loopback adapter, token JSON parser, Secret Service backend, Graph call,
|
||||
or usable account setup. The next product slice supplies concrete desktop,
|
||||
network, and secret-storage adapters, followed by read-only Graph calendar
|
||||
discovery and delta synchronization. Remote writes remain gated on the
|
||||
durability and conflict paths being exercised end to end.
|
||||
|
||||
## Local file interchange
|
||||
|
||||
|
||||
@@ -35,10 +35,21 @@ Completed cache foundation:
|
||||
- Normalized event instances for immutable snapshots
|
||||
- Reserved transactional outbox and conflict records for later remote writes
|
||||
|
||||
Completed HTTP/OAuth boundary:
|
||||
|
||||
- Generic injected HTTP transport and deterministic fakes, with retries left to
|
||||
provider operations
|
||||
- Public-desktop OAuth authorization code design with PKCE `S256`, system
|
||||
browser, and loopback redirect
|
||||
- Multitenant Microsoft account audience and delegated least-privilege
|
||||
`Calendars.Read`; tenant policy may still require administrator consent or
|
||||
block user consent
|
||||
- No client secret in the open-source desktop binary
|
||||
|
||||
Next provider-boundary slices:
|
||||
|
||||
- Injectable HTTP, PKCE authentication, and deterministic fake transports
|
||||
- Secret Service credentials; OAuth secrets are never stored in SQLite
|
||||
- Concrete HTTP, browser/loopback, token JSON, and Secret Service adapters
|
||||
- OAuth secrets in Secret Service, never SQLite
|
||||
- Generic `SyncProvider` contract and observable sync status
|
||||
|
||||
## 0.3 — CalDAV
|
||||
@@ -54,10 +65,12 @@ Next provider-boundary slices:
|
||||
ETag-aware remote writes after the conflict boundary is proven
|
||||
- Account/calendar management UI and per-calendar ANSI identity
|
||||
|
||||
The current cache work is only the prerequisite durable boundary. No network,
|
||||
OAuth, or Graph synchronization is implemented in that phase. After the cache
|
||||
passes its verification gates, the immediate sequence is injectable HTTP plus
|
||||
PKCE and fake transports, then read-only Microsoft Graph delta synchronization.
|
||||
The cache and generic HTTP/OAuth boundaries are prerequisites, not usable
|
||||
Microsoft 365 integration. The boundary phase has no concrete HTTP transport,
|
||||
real browser/loopback adapter, token parser, Secret Service backend, Graph call,
|
||||
or account setup. The immediate sequence is concrete desktop, HTTP, and Secret
|
||||
Service adapters, then read-only Microsoft Graph discovery and delta
|
||||
synchronization.
|
||||
|
||||
## 1.0 — distribution quality
|
||||
|
||||
|
||||
Reference in New Issue
Block a user