mirror of
https://github.com/hanzoai/base.git
synced 2026-10-21 03:41:50 +00:00
The five user verbs collapsed onto the user collection and the key half went to the key endpoint, so this client asks the same questions at the addresses that answer them: get-user?accessKey= -> GET /v1/iam/keys/principal (envelope) get-users?field= -> GET /v1/iam/users (the page itself) get-user?owner&email -> GET /v1/iam/users (the page itself) add-user -> POST /v1/iam/users (the record itself) Three things follow from the move rather than accompany it. The credential travels in the Authorization header. A query clientId is not a credential IAM reads, so every one of these reads would have arrived unauthenticated; the plugin installs the application credentials it already holds in Config where the client is built, and each read presents them. The collection narrows on the address and on nothing else. LookupByAttribute answers "email" and refuses any other attribute instead of sending a filter that would be ignored — an ignored filter answers with the org's first page, and every row on it reads as a match. EnsureUser reads before it writes. The create refuses a duplicate username and admits a duplicate address, so creating first would file a second row under one address and leave both unresolvable by it. A username lost to a racing provision still resolves by the address the two agree on. Where an address names two accounts the answer is a refusal, not the first row: that choice is how somebody acts under a colleague's identity. The team invite asks for two for the same reason and stays pending when it sees them. A resolved key carries the account the key endpoint names — owner/name, unique across tenants where a bare username is unique only inside one — and an unresolved one yields no user at all. Co-authored-by: Hanzo Dev <[email protected]>