torii-backend 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69b936da488f917cf7110687e96fa696678e689e75e82bd209ea829a26ffc73d
4
- data.tar.gz: ce1f78461f54b62eed2a7f926a0aab7d427bef3b6d101ab6c44331da262a0680
3
+ metadata.gz: d43713f485b64b340f948856eb8e19e48d99f2fa4639a2eba92dc52f6381b923
4
+ data.tar.gz: 8b4d67b8747a6bb9661df2e33a7a28c9cd9012658064b0ba10d98720f1ece715
5
5
  SHA512:
6
- metadata.gz: 4a9f56628fc8f49fae8667c8f11d716189853daa1a87bc6b839c93dd75c496ded4a8c47340c3ff682c67ce31eb62c3a775872468bb4538463e74dbf04f0d3bfe
7
- data.tar.gz: 3eab77aaa2315b52295d8ca1bc895d87c44c8569879b45a4183c614c9949c3202da11efb83b16705866ad03f71d5aa44d8117f5c387d2793d1221c5df0cca12e
6
+ metadata.gz: 8ffcc6e59554b47047e23eb835247a5ecd2ed264b526ecf3a85c035e73c1df86b65985962f2919b170de59ce7fcf1a743d3b4ccb3e721a8732634111cd8d7834
7
+ data.tar.gz: e40ec3acd9fcf060ceec79fc83e85f7c1a2a3a98c87f332d61ea5617e0a6d8d323d711e9cfd0b9b5dee6e0a5c6b11de4fa65f33107a25955f542597e14c8e38a
data/README.md CHANGED
@@ -44,8 +44,6 @@ Backend SDK for [torii](https://torii.so) — verify end-user JWTs without a per
44
44
  user = torii.users.get(user_id)
45
45
  ```
46
46
 
47
- Default base URL is `https://api.torii.so`. Override with `api_url:` for staging or self-hosted.
48
-
49
47
  ## Rack middleware (Rails / Sinatra / Roda)
50
48
 
51
49
  ```ruby
data/spec/server-v1.json CHANGED
@@ -1 +1 @@
1
- {"openapi":"3.1.0","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost:52334","description":"Generated server url"}],"tags":[{"name":"Server Users","description":"Server user management endpoints (secret key auth)"},{"name":"Server Sessions","description":"Server session management endpoints (secret key auth)"}],"paths":{"/api/server/v1/users":{"post":{"tags":["Server Users"],"summary":"Create user","description":"Creates an end-user in your environment. All body fields are optional; supply at minimum an email if you want the user to be able to sign in via email + password.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"required":true},"responses":{"201":{"description":"The created user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"400":{"description":"Invalid body (e.g. weak password, malformed email).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Another user with this email already exists in the environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/unban":{"post":{"tags":["Server Users"],"summary":"Unban user","description":"Reverses a previous ban. The user can sign in again on next request.","operationId":"unbanUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to unban.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"The (now active) user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/ban":{"post":{"tags":["Server Users"],"summary":"Ban user","description":"Marks the user as banned and revokes all their active sessions.","operationId":"banUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to ban.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"The (now banned) user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/search":{"post":{"tags":["Server Users"],"summary":"Search users","description":"Returns a cursor-paginated page of end-users in the environment matching the optional filters. Filters use the same tri-state PATCH semantics as `UpdateUserRequest`: omit a field to skip that filter, send a value to require it, send null to require null. Uses POST so the filter body can be sent without URL-encoding.","operationId":"searchUsers","parameters":[{"name":"limit","in":"query","description":"Maximum number of items in the returned page (default 20).","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":50},{"name":"cursor","in":"query","description":"Opaque cursor returned by the previous page's `nextCursor`. Omit to fetch the first page.","required":false,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerUserSearchRequest"}}}},"responses":{"200":{"description":"Page of matching users.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPageResponseUserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}":{"get":{"tags":["Server Users"],"summary":"Get user","description":"Returns the full profile for one end-user.","operationId":"getUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to fetch.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"The user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"delete":{"tags":["Server Users"],"summary":"Delete user","description":"Soft-deletes the user. Not idempotent at the HTTP layer: the authorization grant for the user is revoked on the first successful delete, so a subsequent DELETE for the same id returns 403 rather than 204. Treat 403 from a retry as a confirmation that the user is already deleted.","operationId":"deleteUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to delete.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"204":{"description":"User deleted."},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"patch":{"tags":["Server Users"],"summary":"Update user","description":"Partial update with tri-state PATCH semantics. Every field in `UpdateUserRequest` is tri-state: omit the key to leave the field unchanged, send a non-null value to set it, or send JSON null to clear it.","operationId":"updateUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to update.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}},"required":true},"responses":{"200":{"description":"The updated user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"400":{"description":"Invalid body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/sessions":{"get":{"tags":["Server Sessions"],"summary":"List user sessions","description":"Returns all active (unexpired, unrevoked) sessions for the user, ordered by most recently used.","operationId":"listSessions","parameters":[{"name":"userId","in":"path","description":"Identifier of the user whose sessions to list.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"All active sessions for the user.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserSessionResponse"}}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"delete":{"tags":["Server Sessions"],"summary":"Revoke all sessions","description":"Immediately revokes every active session for the user. Idempotent.","operationId":"revokeAllSessions","parameters":[{"name":"userId","in":"path","description":"Identifier of the user whose sessions to revoke.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"204":{"description":"Sessions revoked."},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/sessions/{sessionId}":{"delete":{"tags":["Server Sessions"],"summary":"Revoke specific session","description":"Revokes a single session by id. Idempotent: returns 204 even if the session was already revoked or expired.","operationId":"revokeSession","parameters":[{"name":"userId","in":"path","description":"Identifier of the user who owns the session.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"},{"name":"sessionId","in":"path","description":"Identifier of the session to revoke.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a74-1234-7000-8000-000000000000"}],"responses":{"204":{"description":"Session revoked."},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User or session belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}}},"components":{"schemas":{"CreateUserRequest":{"type":"object","description":"Request body for creating an end-user in your environment. All fields are optional; supply at minimum an email if you want the user to be able to sign in via email + password.","properties":{"email":{"type":["string","null"],"description":"Primary email for the new user. If omitted, the user is created without a sign-in identity.","example":"ada@example.com"},"password":{"type":["string","null"],"description":"Initial password. Subject to the environment's password policy. Omit to create a passwordless user (e.g. social-only).","example":"correct horse battery staple"},"name":{"type":["string","null"],"description":"Display name to seed on the profile.","example":"Ada Lovelace"},"phone":{"type":["string","null"],"description":"Phone number to seed on the profile.","example":"+15555550100"},"address":{"type":["string","null"],"description":"Postal address to seed on the profile.","example":"221B Baker Street, London"},"dateOfBirth":{"type":["string","null"],"format":"date","description":"Date of birth in ISO-8601 (YYYY-MM-DD).","example":"1815-12-10"}}},"ProblemDetail":{"type":"object","properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer","format":"int32"},"detail":{"type":"string"},"instance":{"type":"string","format":"uri"},"properties":{"type":"object","additionalProperties":{}}}},"UserResponse":{"type":"object","description":"An end-user belonging to one of your environments.","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this user.","example":"01931a73-8b00-7000-8000-000000000000"},"environmentId":{"type":"string","format":"uuid","description":"Identifier of the environment this user belongs to.","example":"01931a72-0000-7000-8000-000000000000"},"name":{"type":["string","null"],"description":"Full name on the profile, if any.","example":"Ada Lovelace"},"phone":{"type":["string","null"],"description":"Phone number on the profile, if any. Not guaranteed to be verified.","example":"+15555550100"},"locale":{"type":["string","null"],"description":"Preferred locale for emails and UI messages.","enum":["en","da"]},"address":{"type":["string","null"],"description":"Free-form address string, if provided.","example":"221B Baker Street, London"},"dateOfBirth":{"type":["string","null"],"format":"date","description":"Date of birth in ISO-8601 (YYYY-MM-DD), if provided.","example":"1815-12-10"},"status":{"type":"string","description":"Lifecycle status of the user (e.g. active, banned).","enum":["pending_verification","active","banned","deleted"]},"createdAt":{"type":"string","format":"date-time","description":"When this user was created (ISO-8601 UTC).","example":"2026-05-16T09:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When this user was last modified (ISO-8601 UTC).","example":"2026-05-16T10:00:00Z"},"email":{"type":["string","null"],"description":"Primary email on the profile, if any. Not guaranteed to be verified.","example":"ada@example.com"},"deletedAt":{"type":["string","null"],"format":"date-time","description":"When this user was deleted, if soft-deleted. Null for active users.","example":"2026-05-20T12:00:00Z"}},"required":["createdAt","environmentId","id","status","updatedAt"]},"ServerUserSearchRequest":{"type":"object","description":"Optional filter body for `POST /users/search`. Every field is tri-state: omit to skip that filter, send a value to require it. Fields whose inner type is nullable (currently `name`, `email`) additionally accept JSON null to filter for users where that column is null; the non-nullable `statuses` field rejects null.","properties":{"name":{"type":["string","null"],"description":"Filter by name (case-insensitive substring match). Send null to require users with no name.","example":"Ada"},"email":{"type":["string","null"],"description":"Filter by primary email (case-insensitive substring match). Send null to require users with no email.","example":"@example.com"},"statuses":{"type":"array","description":"Filter by user status. Returns users matching any of the supplied statuses.","items":{"type":"string","enum":["pending_verification","active","banned","deleted"]},"uniqueItems":true},"createdAfter":{"type":["string","null"],"format":"date-time","description":"Only return users created at or after this instant (ISO-8601 UTC).","example":"2026-01-01T00:00:00Z"},"createdBefore":{"type":["string","null"],"format":"date-time","description":"Only return users created at or before this instant (ISO-8601 UTC).","example":"2026-12-31T23:59:59Z"}}},"CursorPageResponseUserResponse":{"type":"object","description":"A single page of results in a cursor-paginated list. Pass `nextCursor` as the `cursor` query parameter to fetch the following page.","properties":{"items":{"type":"array","description":"Items in this page, in stable order.","items":{"$ref":"#/components/schemas/UserResponse"}},"nextCursor":{"type":["string","null"],"format":"uuid","description":"Cursor to pass to fetch the next page. Null when this is the last page.","example":"01931a73-8b00-7000-8000-000000000000"},"hasMore":{"type":"boolean","description":"True if more pages are available (equivalent to `nextCursor != null`).","example":true}},"required":["hasMore","items"]},"UpdateUserRequest":{"type":"object","description":"PATCH body for updating an end-user. Every field is tri-state: omit the key entirely to leave the field unchanged, send a non-null value to set it, or send JSON null to clear it.","properties":{"name":{"type":["string","null"],"description":"New display name. Send null to clear; omit to leave unchanged.","example":"Ada Lovelace"},"phone":{"type":["string","null"],"description":"New phone number. Send null to clear; omit to leave unchanged.","example":"+15555550100"},"locale":{"type":["string","null"],"description":"New preferred locale. Send null to clear; omit to leave unchanged.","enum":["en","da"]},"address":{"type":["string","null"],"description":"New postal address. Send null to clear; omit to leave unchanged.","example":"221B Baker Street, London"},"dateOfBirth":{"type":["string","null"],"format":"date","description":"New date of birth (YYYY-MM-DD). Send null to clear; omit to leave unchanged.","example":"1815-12-10"}}},"UserSessionResponse":{"type":"object","description":"An active end-user session in your environment.","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this session.","example":"01931a74-1234-7000-8000-000000000000"},"userId":{"type":"string","format":"uuid","description":"Identifier of the end-user this session belongs to.","example":"01931a73-8b00-7000-8000-000000000000"},"environmentId":{"type":"string","format":"uuid","description":"Identifier of the environment this session belongs to.","example":"01931a72-0000-7000-8000-000000000000"},"userAgent":{"type":["string","null"],"description":"Raw User-Agent string captured when the session was created.","example":"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6_0) AppleWebKit/537.36"},"ipAddress":{"type":["string","null"],"description":"IP address captured when the session was created.","example":"203.0.113.42"},"createdAt":{"type":"string","format":"date-time","description":"When this session was created (ISO-8601 UTC).","example":"2026-05-16T09:30:00Z"},"expiresAt":{"type":"string","format":"date-time","description":"When this session expires (ISO-8601 UTC).","example":"2026-05-23T09:30:00Z"},"lastUsedAt":{"type":"string","format":"date-time","description":"When this session was last seen by the API (ISO-8601 UTC).","example":"2026-05-16T11:42:00Z"}},"required":["createdAt","environmentId","expiresAt","id","lastUsedAt","userId"]}}}}
1
+ {"openapi":"3.1.0","info":{"title":"OpenAPI definition","version":"v0"},"servers":[{"url":"http://localhost:50385","description":"Generated server url"}],"tags":[{"name":"Server Users","description":"Server user management endpoints (secret key auth)"},{"name":"Server Sessions","description":"Server session management endpoints (secret key auth)"}],"paths":{"/api/server/v1/users":{"post":{"tags":["Server Users"],"summary":"Create user","description":"Creates an end-user in your environment. All body fields are optional; supply at minimum an email if you want the user to be able to sign in via email + password.","operationId":"createUser","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserRequest"}}},"required":true},"responses":{"201":{"description":"The created user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"400":{"description":"Invalid body (e.g. weak password, malformed email).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"409":{"description":"Another user with this email already exists in the environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/unban":{"post":{"tags":["Server Users"],"summary":"Unban user","description":"Reverses a previous ban. The user can sign in again on next request.","operationId":"unbanUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to unban.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"The (now active) user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/ban":{"post":{"tags":["Server Users"],"summary":"Ban user","description":"Marks the user as banned and revokes all their active sessions.","operationId":"banUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to ban.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"The (now banned) user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/search":{"post":{"tags":["Server Users"],"summary":"Search users","description":"Returns a cursor-paginated page of end-users in the environment matching the optional filters. Filters use the same tri-state PATCH semantics as `UpdateUserRequest`: omit a field to skip that filter, send a value to require it, send null to require null. Uses POST so the filter body can be sent without URL-encoding.","operationId":"searchUsers","parameters":[{"name":"limit","in":"query","description":"Maximum number of items in the returned page (default 20).","required":false,"schema":{"type":"integer","format":"int32","default":20},"example":50},{"name":"cursor","in":"query","description":"Opaque cursor returned by the previous page's `nextCursor`. Omit to fetch the first page.","required":false,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerUserSearchRequest"}}}},"responses":{"200":{"description":"Page of matching users.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPageResponseUserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}":{"get":{"tags":["Server Users"],"summary":"Get user","description":"Returns the full profile for one end-user.","operationId":"getUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to fetch.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"The user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"delete":{"tags":["Server Users"],"summary":"Delete user","description":"Soft-deletes the user. Not idempotent at the HTTP layer: the authorization grant for the user is revoked on the first successful delete, so a subsequent DELETE for the same id returns 403 rather than 204. Treat 403 from a retry as a confirmation that the user is already deleted.","operationId":"deleteUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to delete.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"204":{"description":"User deleted."},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"patch":{"tags":["Server Users"],"summary":"Update user","description":"Partial update with tri-state PATCH semantics. Every field in `UpdateUserRequest` is tri-state: omit the key to leave the field unchanged, send a non-null value to set it, or send JSON null to clear it.","operationId":"updateUser","parameters":[{"name":"userId","in":"path","description":"Identifier of the user to update.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserRequest"}}},"required":true},"responses":{"200":{"description":"The updated user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"400":{"description":"Invalid body.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"404":{"description":"No user with this id.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/sessions":{"get":{"tags":["Server Sessions"],"summary":"List user sessions","description":"Returns all active (unexpired, unrevoked) sessions for the user, ordered by most recently used.","operationId":"listSessions","parameters":[{"name":"userId","in":"path","description":"Identifier of the user whose sessions to list.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"200":{"description":"All active sessions for the user.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserSessionResponse"}}}}},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}},"delete":{"tags":["Server Sessions"],"summary":"Revoke all sessions","description":"Immediately revokes every active session for the user. Idempotent.","operationId":"revokeAllSessions","parameters":[{"name":"userId","in":"path","description":"Identifier of the user whose sessions to revoke.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"}],"responses":{"204":{"description":"Sessions revoked."},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}},"/api/server/v1/users/{userId}/sessions/{sessionId}":{"delete":{"tags":["Server Sessions"],"summary":"Revoke specific session","description":"Revokes a single session by id. Idempotent: returns 204 even if the session was already revoked or expired.","operationId":"revokeSession","parameters":[{"name":"userId","in":"path","description":"Identifier of the user who owns the session.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a73-8b00-7000-8000-000000000000"},{"name":"sessionId","in":"path","description":"Identifier of the session to revoke.","required":true,"schema":{"type":"string","format":"uuid"},"example":"01931a74-1234-7000-8000-000000000000"}],"responses":{"204":{"description":"Session revoked."},"401":{"description":"Missing or invalid secret key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}},"403":{"description":"User or session belongs to a different environment.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetail"}}}}}}}},"components":{"schemas":{"CreateUserRequest":{"type":"object","description":"Request body for creating an end-user in your environment. All fields are optional; supply at minimum an email if you want the user to be able to sign in via email + password.","properties":{"email":{"type":["string","null"],"description":"Primary email for the new user. If omitted, the user is created without a sign-in identity.","example":"ada@example.com"},"password":{"type":["string","null"],"description":"Initial password. Subject to the environment's password policy. Omit to create a passwordless user (e.g. social-only).","example":"correct horse battery staple"},"name":{"type":["string","null"],"description":"Display name to seed on the profile.","example":"Ada Lovelace"},"phone":{"type":["string","null"],"description":"Phone number to seed on the profile.","example":"+15555550100"},"address":{"type":["string","null"],"description":"Postal address to seed on the profile.","example":"221B Baker Street, London"},"dateOfBirth":{"type":["string","null"],"format":"date","description":"Date of birth in ISO-8601 (YYYY-MM-DD).","example":"1815-12-10"}}},"ProblemDetail":{"type":"object","properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer","format":"int32"},"detail":{"type":"string"},"instance":{"type":"string","format":"uri"},"properties":{"type":"object","additionalProperties":{}}}},"UserResponse":{"type":"object","description":"An end-user belonging to one of your environments.","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this user.","example":"01931a73-8b00-7000-8000-000000000000"},"environmentId":{"type":"string","format":"uuid","description":"Identifier of the environment this user belongs to.","example":"01931a72-0000-7000-8000-000000000000"},"name":{"type":["string","null"],"description":"Full name on the profile, if any.","example":"Ada Lovelace"},"phone":{"type":["string","null"],"description":"Phone number on the profile, if any. Not guaranteed to be verified.","example":"+15555550100"},"locale":{"type":["string","null"],"description":"Preferred locale for emails and UI messages.","enum":["en","da"]},"address":{"type":["string","null"],"description":"Free-form address string, if provided.","example":"221B Baker Street, London"},"dateOfBirth":{"type":["string","null"],"format":"date","description":"Date of birth in ISO-8601 (YYYY-MM-DD), if provided.","example":"1815-12-10"},"status":{"type":"string","description":"Lifecycle status of the user (e.g. active, banned).","enum":["active","banned","deleted"]},"createdAt":{"type":"string","format":"date-time","description":"When this user was created (ISO-8601 UTC).","example":"2026-05-16T09:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When this user was last modified (ISO-8601 UTC).","example":"2026-05-16T10:00:00Z"},"email":{"type":["string","null"],"description":"Primary email on the profile, if any. Not guaranteed to be verified.","example":"ada@example.com"},"emailVerifiedAt":{"type":["string","null"],"format":"date-time","description":"When this user's primary email was verified, if it has been verified.","example":"2026-05-16T09:35:00Z"},"deletedAt":{"type":["string","null"],"format":"date-time","description":"When this user was deleted, if soft-deleted. Null for active users.","example":"2026-05-20T12:00:00Z"}},"required":["createdAt","environmentId","id","status","updatedAt"]},"ServerUserSearchRequest":{"type":"object","description":"Optional filter body for `POST /users/search`. Every field is tri-state: omit to skip that filter, send a value to require it. Fields whose inner type is nullable (currently `name`, `email`) additionally accept JSON null to filter for users where that column is null; the non-nullable `statuses` field rejects null.","properties":{"name":{"type":["string","null"],"description":"Filter by name (case-insensitive substring match). Send null to require users with no name.","example":"Ada"},"email":{"type":["string","null"],"description":"Filter by primary email (case-insensitive substring match). Send null to require users with no email.","example":"@example.com"},"statuses":{"type":"array","description":"Filter by user status. Returns users matching any of the supplied statuses.","items":{"type":"string","enum":["active","banned","deleted"]},"uniqueItems":true},"createdAfter":{"type":["string","null"],"format":"date-time","description":"Only return users created at or after this instant (ISO-8601 UTC).","example":"2026-01-01T00:00:00Z"},"createdBefore":{"type":["string","null"],"format":"date-time","description":"Only return users created at or before this instant (ISO-8601 UTC).","example":"2026-12-31T23:59:59Z"}}},"CursorPageResponseUserResponse":{"type":"object","description":"A single page of results in a cursor-paginated list. Pass `nextCursor` as the `cursor` query parameter to fetch the following page.","properties":{"items":{"type":"array","description":"Items in this page, in stable order.","items":{"$ref":"#/components/schemas/UserResponse"}},"nextCursor":{"type":["string","null"],"format":"uuid","description":"Cursor to pass to fetch the next page. Null when this is the last page.","example":"01931a73-8b00-7000-8000-000000000000"},"hasMore":{"type":"boolean","description":"True if more pages are available (equivalent to `nextCursor != null`).","example":true}},"required":["hasMore","items"]},"UpdateUserRequest":{"type":"object","description":"PATCH body for updating an end-user. Every field is tri-state: omit the key entirely to leave the field unchanged, send a non-null value to set it, or send JSON null to clear it.","properties":{"name":{"type":["string","null"],"description":"New display name. Send null to clear; omit to leave unchanged.","example":"Ada Lovelace"},"phone":{"type":["string","null"],"description":"New phone number. Send null to clear; omit to leave unchanged.","example":"+15555550100"},"locale":{"type":["string","null"],"description":"New preferred locale. Send null to clear; omit to leave unchanged.","enum":["en","da"]},"address":{"type":["string","null"],"description":"New postal address. Send null to clear; omit to leave unchanged.","example":"221B Baker Street, London"},"dateOfBirth":{"type":["string","null"],"format":"date","description":"New date of birth (YYYY-MM-DD). Send null to clear; omit to leave unchanged.","example":"1815-12-10"}}},"UserSessionResponse":{"type":"object","description":"An active end-user session in your environment.","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this session.","example":"01931a74-1234-7000-8000-000000000000"},"userId":{"type":"string","format":"uuid","description":"Identifier of the end-user this session belongs to.","example":"01931a73-8b00-7000-8000-000000000000"},"environmentId":{"type":"string","format":"uuid","description":"Identifier of the environment this session belongs to.","example":"01931a72-0000-7000-8000-000000000000"},"userAgent":{"type":["string","null"],"description":"Raw User-Agent string captured when the session was created.","example":"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_6_0) AppleWebKit/537.36"},"ipAddress":{"type":["string","null"],"description":"IP address captured when the session was created.","example":"203.0.113.42"},"createdAt":{"type":"string","format":"date-time","description":"When this session was created (ISO-8601 UTC).","example":"2026-05-16T09:30:00Z"},"expiresAt":{"type":"string","format":"date-time","description":"When this session expires (ISO-8601 UTC).","example":"2026-05-23T09:30:00Z"},"lastUsedAt":{"type":"string","format":"date-time","description":"When this session was last seen by the API (ISO-8601 UTC).","example":"2026-05-16T11:42:00Z"},"activeOrganizationId":{"type":["string","null"],"format":"uuid","description":"Active organization pinned to this session (`org_id` claim on re-mint)."}},"required":["createdAt","environmentId","expiresAt","id","lastUsedAt","userId"]}}}}
@@ -158,7 +158,7 @@ module ToriiBackendGenerated
158
158
 
159
159
  def initialize
160
160
  @scheme = 'http'
161
- @host = 'localhost:52334'
161
+ @host = 'localhost:50385'
162
162
  @base_path = ''
163
163
  @server_index = nil
164
164
  @server_operation_index = {}
@@ -251,7 +251,7 @@ module ToriiBackendGenerated
251
251
  def server_settings
252
252
  [
253
253
  {
254
- url: "http://localhost:52334",
254
+ url: "http://localhost:50385",
255
255
  description: "Generated server url",
256
256
  }
257
257
  ]
@@ -49,6 +49,9 @@ module ToriiBackendGenerated
49
49
  # Primary email on the profile, if any. Not guaranteed to be verified.
50
50
  attr_accessor :email
51
51
 
52
+ # When this user's primary email was verified, if it has been verified.
53
+ attr_accessor :email_verified_at
54
+
52
55
  # When this user was deleted, if soft-deleted. Null for active users.
53
56
  attr_accessor :deleted_at
54
57
 
@@ -88,6 +91,7 @@ module ToriiBackendGenerated
88
91
  :'created_at' => :'createdAt',
89
92
  :'updated_at' => :'updatedAt',
90
93
  :'email' => :'email',
94
+ :'email_verified_at' => :'emailVerifiedAt',
91
95
  :'deleted_at' => :'deletedAt'
92
96
  }
93
97
  end
@@ -116,6 +120,7 @@ module ToriiBackendGenerated
116
120
  :'created_at' => :'Time',
117
121
  :'updated_at' => :'Time',
118
122
  :'email' => :'String',
123
+ :'email_verified_at' => :'Time',
119
124
  :'deleted_at' => :'Time'
120
125
  }
121
126
  end
@@ -129,6 +134,7 @@ module ToriiBackendGenerated
129
134
  :'address',
130
135
  :'date_of_birth',
131
136
  :'email',
137
+ :'email_verified_at',
132
138
  :'deleted_at'
133
139
  ])
134
140
  end
@@ -203,6 +209,10 @@ module ToriiBackendGenerated
203
209
  self.email = attributes[:'email']
204
210
  end
205
211
 
212
+ if attributes.key?(:'email_verified_at')
213
+ self.email_verified_at = attributes[:'email_verified_at']
214
+ end
215
+
206
216
  if attributes.key?(:'deleted_at')
207
217
  self.deleted_at = attributes[:'deleted_at']
208
218
  end
@@ -245,7 +255,7 @@ module ToriiBackendGenerated
245
255
  locale_validator = EnumAttributeValidator.new('String', ["en", "da"])
246
256
  return false unless locale_validator.valid?(@locale)
247
257
  return false if @status.nil?
248
- status_validator = EnumAttributeValidator.new('String', ["pending_verification", "active", "banned", "deleted"])
258
+ status_validator = EnumAttributeValidator.new('String', ["active", "banned", "deleted"])
249
259
  return false unless status_validator.valid?(@status)
250
260
  return false if @created_at.nil?
251
261
  return false if @updated_at.nil?
@@ -285,7 +295,7 @@ module ToriiBackendGenerated
285
295
  # Custom attribute writer method checking allowed values (enum).
286
296
  # @param [Object] status Object to be assigned
287
297
  def status=(status)
288
- validator = EnumAttributeValidator.new('String', ["pending_verification", "active", "banned", "deleted"])
298
+ validator = EnumAttributeValidator.new('String', ["active", "banned", "deleted"])
289
299
  unless validator.valid?(status)
290
300
  fail ArgumentError, "invalid value for \"status\", must be one of #{validator.allowable_values}."
291
301
  end
@@ -328,6 +338,7 @@ module ToriiBackendGenerated
328
338
  created_at == o.created_at &&
329
339
  updated_at == o.updated_at &&
330
340
  email == o.email &&
341
+ email_verified_at == o.email_verified_at &&
331
342
  deleted_at == o.deleted_at
332
343
  end
333
344
 
@@ -340,7 +351,7 @@ module ToriiBackendGenerated
340
351
  # Calculates hash code according to all attributes.
341
352
  # @return [Integer] Hash code
342
353
  def hash
343
- [id, environment_id, name, phone, locale, address, date_of_birth, status, created_at, updated_at, email, deleted_at].hash
354
+ [id, environment_id, name, phone, locale, address, date_of_birth, status, created_at, updated_at, email, email_verified_at, deleted_at].hash
344
355
  end
345
356
 
346
357
  # Builds the object from hash
@@ -40,6 +40,9 @@ module ToriiBackendGenerated
40
40
  # When this session was last seen by the API (ISO-8601 UTC).
41
41
  attr_accessor :last_used_at
42
42
 
43
+ # Active organization pinned to this session (`org_id` claim on re-mint).
44
+ attr_accessor :active_organization_id
45
+
43
46
  # Attribute mapping from ruby-style variable name to JSON key.
44
47
  def self.attribute_map
45
48
  {
@@ -50,7 +53,8 @@ module ToriiBackendGenerated
50
53
  :'ip_address' => :'ipAddress',
51
54
  :'created_at' => :'createdAt',
52
55
  :'expires_at' => :'expiresAt',
53
- :'last_used_at' => :'lastUsedAt'
56
+ :'last_used_at' => :'lastUsedAt',
57
+ :'active_organization_id' => :'activeOrganizationId'
54
58
  }
55
59
  end
56
60
 
@@ -74,7 +78,8 @@ module ToriiBackendGenerated
74
78
  :'ip_address' => :'String',
75
79
  :'created_at' => :'Time',
76
80
  :'expires_at' => :'Time',
77
- :'last_used_at' => :'Time'
81
+ :'last_used_at' => :'Time',
82
+ :'active_organization_id' => :'String'
78
83
  }
79
84
  end
80
85
 
@@ -83,6 +88,7 @@ module ToriiBackendGenerated
83
88
  Set.new([
84
89
  :'user_agent',
85
90
  :'ip_address',
91
+ :'active_organization_id'
86
92
  ])
87
93
  end
88
94
 
@@ -145,6 +151,10 @@ module ToriiBackendGenerated
145
151
  else
146
152
  self.last_used_at = nil
147
153
  end
154
+
155
+ if attributes.key?(:'active_organization_id')
156
+ self.active_organization_id = attributes[:'active_organization_id']
157
+ end
148
158
  end
149
159
 
150
160
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -264,7 +274,8 @@ module ToriiBackendGenerated
264
274
  ip_address == o.ip_address &&
265
275
  created_at == o.created_at &&
266
276
  expires_at == o.expires_at &&
267
- last_used_at == o.last_used_at
277
+ last_used_at == o.last_used_at &&
278
+ active_organization_id == o.active_organization_id
268
279
  end
269
280
 
270
281
  # @see the `==` method
@@ -276,7 +287,7 @@ module ToriiBackendGenerated
276
287
  # Calculates hash code according to all attributes.
277
288
  # @return [Integer] Hash code
278
289
  def hash
279
- [id, user_id, environment_id, user_agent, ip_address, created_at, expires_at, last_used_at].hash
290
+ [id, user_id, environment_id, user_agent, ip_address, created_at, expires_at, last_used_at, active_organization_id].hash
280
291
  end
281
292
 
282
293
  # Builds the object from hash
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Torii
4
4
  module Backend
5
- VERSION = '0.0.2'
5
+ VERSION = '0.0.3'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: torii-backend
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - torii
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-17 00:00:00.000000000 Z
11
+ date: 2026-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt