Public Access
Freeze DodoSSH.Contracts v0.1 (M1)
The second M1 gate. This assembly, not the OpenAPI document, is the client's contract, so PublicApiAnalyzers now tracks all 540 public members: a renamed DTO property becomes a build error rather than a runtime deserialisation failure on someone's laptop. Contract surface: - EncryptedPayload carries the envelope plus the KeyGeneration and AadVersion columns needed to recompute AAD, since AAD is derived from the row rather than transmitted. - Sync: push with per-operation status (Applied/Conflict/Forbidden/Invalid/Duplicate) so one stale item cannot block a whole offline queue; a Conflict returns the server's row for client-side three-way merge, because the server cannot merge ciphertext. - Enrollment: KeyStatement whose hash becomes the OIDC nonce, so the identity provider signs over the public keys and this server cannot fabricate a key for a user who never enrolled. - Meta and .well-known configuration: capability negotiation instead of URL versioning, which is what a self-hosted product needs when client and server upgrade independently. - SyncPlaintextFields deliberately has no label or name field. ACL admin runs client-side where names can be decrypted, so the server never needs a searchable title. Two design problems found by writing the tests rather than assuming: - Hand-constructing JsonSerializerOptions and merely pointing its resolver at the context silently discards every source-generated setting. JsonSerializerDefaults.Web replaces NumberHandling.Strict with AllowReadingFromString, so "1" would be accepted where 1 is meant — invisible until two implementations disagree. Callers now use ResponseOptions or StrictRequestOptions; StrictRequestOptions is derived by copying so it cannot drift. - StrictRequestOptions had a static-initialisation cycle: it read the generated Default property from the same type's initialiser and got null. Now lazy. Requests reject unmapped members so a client typo is a 400; responses tolerate them so an older client can read a newer server. Enums cross the wire as strings, so reordering one cannot silently reinterpret stored data. Also: excluded source-generator output from PublicApiAnalyzers. The JSON generator emits a public member per serialisable type, which would have added hundreds of mechanical entries and drowned the ones describing the actual wire contract. And disabled MA0048's one-type-per-file rule: splitting SyncPullRequest from SyncPullResponse makes a reviewer open two files to understand one endpoint. Verified: 0 warnings, 95 tests pass, format clean.
This commit is contained in:
1 parent
b15af836a3
commit
06d04b490b
12 files changed
+1472
No files matched your search
@@ -0,0 +1,45 @@
|
||||
namespace DodoSSH.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// The kind of vault item a sync change refers to.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Values are persisted in the change log and are part of the wire contract. Append only;
|
||||
/// never renumber. These mirror <c>CryptoSpec.AadResourceType</c> for the item types, but are
|
||||
/// a separate enum because only syncable items appear here.
|
||||
/// </remarks>
|
||||
public enum SyncEntityType
|
||||
{
|
||||
/// <summary>Not a legal value.</summary>
|
||||
Unspecified = 0,
|
||||
|
||||
/// <summary>An SSH host.</summary>
|
||||
Host = 1,
|
||||
|
||||
/// <summary>A credential.</summary>
|
||||
Credential = 2,
|
||||
|
||||
/// <summary>An SSH key pair.</summary>
|
||||
SshKey = 3,
|
||||
|
||||
/// <summary>A host group.</summary>
|
||||
HostGroup = 4,
|
||||
|
||||
/// <summary>A tag.</summary>
|
||||
Tag = 5,
|
||||
|
||||
/// <summary>A host-to-tag association.</summary>
|
||||
HostTag = 6,
|
||||
|
||||
/// <summary>A host-to-credential association.</summary>
|
||||
HostCredential = 7,
|
||||
|
||||
/// <summary>A command snippet.</summary>
|
||||
Snippet = 8,
|
||||
|
||||
/// <summary>A port forward.</summary>
|
||||
PortForward = 9,
|
||||
|
||||
/// <summary>A known SSH host key.</summary>
|
||||
KnownHostKey = 10,
|
||||
}
|
||||
Reference in new issue
Block a user