From 1f8bd0239844d30c54611847ab050665f7a79fb0 Mon Sep 17 00:00:00 2001 From: Nawwar Elnarsh Date: Sun, 16 Aug 2026 14:36:53 +0200 Subject: [PATCH 1/9] feat!: complete control and application platform contracts --- AGENTS.md | 2 +- README.md | 16 +- api/openapi/platform93.openapi30.yaml | 15414 +++++++++- api/openapi/platform93.yaml | 15493 +++++++++- cmd/platform93/main.go | 4 + conformance/jwt.json | 12 +- conformance/webhook.json | 4 +- docs/adr/0003-synchronized-release-train.md | 2 +- docs/adr/0005-application-workspace-model.md | 6 +- docs/application-configuration.md | 25 +- docs/architecture.md | 24 +- docs/authorization.md | 58 + docs/invitations.md | 32 + docs/migrating-from-supaapps-platform.md | 82 + docs/native-mobile-auth.md | 52 + docs/notifications.md | 34 +- docs/organization-management.md | 10 +- docs/platform-user-authentication.md | 40 + docs/provider-inheritance.md | 8 +- internal/authorization/permission.go | 195 + internal/authorization/permission_test.go | 62 + internal/database/database.go | 24 + internal/generated/openapi.gen.go | 23290 +++++++++++----- internal/httpapi/admin_assets_test.go | 13 + internal/httpapi/apple_auth.go | 11 +- internal/httpapi/application_config.go | 76 +- internal/httpapi/application_config_test.go | 12 +- .../httpapi/application_config_unit_test.go | 22 + internal/httpapi/application_flow_config.go | 64 +- ...application_invitation_integration_test.go | 203 + internal/httpapi/application_redirect_test.go | 56 + .../application_workspace_invariants_test.go | 12 +- internal/httpapi/auth_provider_config.go | 174 +- .../httpapi/auth_provider_inheritance_test.go | 8 +- internal/httpapi/authorization.go | 319 +- .../httpapi/authorization_security_test.go | 102 + internal/httpapi/billing.go | 86 +- internal/httpapi/billing_lifecycle.go | 38 +- internal/httpapi/billing_profiles.go | 4 +- internal/httpapi/billing_stripe_events.go | 175 +- .../httpapi/billing_stripe_events_test.go | 39 +- .../catalog_entitlement_defaults_test.go | 2 +- internal/httpapi/control.go | 21 +- internal/httpapi/control_auth_events.go | 39 + internal/httpapi/control_auth_policy.go | 191 + internal/httpapi/control_external_auth.go | 441 + .../control_external_auth_integration_test.go | 181 + internal/httpapi/control_invitation_test.go | 10 +- internal/httpapi/control_lifecycle_test.go | 6 +- internal/httpapi/control_members.go | 197 +- internal/httpapi/control_origin_test.go | 22 + internal/httpapi/control_rename_test.go | 12 +- internal/httpapi/control_retirement_test.go | 22 +- internal/httpapi/control_user_account.go | 201 + internal/httpapi/control_user_account_test.go | 224 + .../httpapi/control_user_boundary_test.go | 165 + internal/httpapi/control_user_invitations.go | 220 + internal/httpapi/control_user_sessions.go | 109 + internal/httpapi/cors.go | 171 + internal/httpapi/cors_test.go | 99 + internal/httpapi/delegations.go | 65 +- internal/httpapi/entitlements.go | 177 +- internal/httpapi/event_types.go | 2 +- internal/httpapi/event_types_test.go | 5 +- .../httpapi/external_auth_callback_test.go | 80 + internal/httpapi/google_auth.go | 53 +- internal/httpapi/idempotency_test.go | 4 +- internal/httpapi/identity.go | 319 +- ...ators.go => installation_control_users.go} | 74 +- internal/httpapi/invitations.go | 706 + internal/httpapi/issuer_lifecycle.go | 31 + internal/httpapi/lifecycle_worker.go | 96 + .../local_entitlement_snapshot_test.go | 28 +- .../httpapi/migration_parity_unit_test.go | 47 + internal/httpapi/notification_lifecycle.go | 2 +- internal/httpapi/notification_management.go | 26 + .../notification_provider_scope_test.go | 12 +- internal/httpapi/notification_reporting.go | 3 + internal/httpapi/notification_system.go | 22 +- .../notification_template_variables.go | 17 +- internal/httpapi/oauth.go | 63 +- internal/httpapi/operations.go | 2 +- internal/httpapi/operator_account.go | 174 - internal/httpapi/operator_account_test.go | 107 - internal/httpapi/operator_boundary_test.go | 106 - internal/httpapi/operator_sessions.go | 108 - internal/httpapi/organization_policy.go | 2 +- internal/httpapi/permission_grants.go | 357 + .../provider_inheritance_updates_test.go | 12 +- internal/httpapi/provider_scope.go | 4 +- .../provider_scope_authorization_test.go | 16 +- internal/httpapi/server.go | 177 +- internal/httpapi/service_api.go | 96 + internal/httpapi/setup.go | 225 +- internal/httpapi/storage_objects.go | 2 +- .../system_notification_templates_test.go | 10 +- internal/httpapi/webhooks.go | 2 +- internal/httpapi/workspace_management.go | 65 +- internal/httpapi/workspace_management_test.go | 4 +- internal/identity/token.go | 100 +- internal/identity/token_test.go | 8 +- internal/jobs/runner.go | 17 + internal/jobs/smtp.go | 6 +- migrations/00001_foundation.sql | 3530 ++- .../00002_product_entitlement_defaults.sql | 15 - migrations/00003_event_type_registry.sql | 52 - migrations/00004_provider_inheritance.sql | 85 - .../00005_organization_notifications.sql | 10 - .../00006_system_notification_templates.sql | 77 - migrations/00007_free_form_features.sql | 22 - .../00008_application_configuration.sql | 35 - migrations/00009_event_contracts.sql | 80 - migrations/00010_operator_passwords.sql | 5 - migrations/00011_organization_management.sql | 59 - .../00012_notification_localization.sql | 9 - migrations/00013_object_storage.sql | 172 - package.json | 9 +- pnpm-lock.yaml | 38 +- .../events/migration-parity-1.0.schema.json | 132 + scripts/check-route-contract.mjs | 2 +- scripts/project-openapi-30.mjs | 35 +- scripts/set-release-version.mjs | 2 +- sdk/go/auth/auth.go | 127 +- sdk/go/auth/conformance_test.go | 32 +- sdk/go/client/client.go | 364 + sdk/go/client/client_test.go | 54 + sdk/go/webhooks/webhooks.go | 87 + sdk/php/README.md | 9 + sdk/php/src/Claims.php | 4 +- sdk/php/src/Laravel/Platform93User.php | 2 +- sdk/php/src/MachineClient.php | 202 + sdk/php/src/Permission.php | 61 + sdk/php/src/Verifier.php | 5 +- sdk/php/src/Webhook.php | 15 + sdk/php/tests/auth_conformance.php | 19 +- sdk/python/auth/README.md | 5 + .../auth/src/platform93_auth/__init__.py | 37 +- .../auth/src/platform93_auth/machine.py | 295 + .../auth/src/platform93_auth/verifier.py | 71 +- sdk/python/auth/tests/conformance.py | 21 +- .../src/platform93_webhooks/__init__.py | 4 + .../src/platform93_webhooks/verifier.py | 49 + sdk/typescript/auth/src/index.ts | 85 +- sdk/typescript/auth/test/auth.test.mjs | 46 + sdk/typescript/events/src/index.ts | 55 +- sdk/typescript/expo/README.md | 31 + sdk/typescript/expo/package.json | 42 + sdk/typescript/expo/src/index.ts | 105 + sdk/typescript/expo/test/expo.test.mjs | 46 + sdk/typescript/expo/tsconfig.json | 5 + sdk/typescript/sdk/src/generated/index.ts | 4 +- sdk/typescript/sdk/src/generated/sdk.gen.ts | 1729 +- sdk/typescript/sdk/src/generated/types.gen.ts | 7594 +++-- sdk/typescript/sdk/src/index.ts | 32 +- sdk/typescript/server/README.md | 25 + sdk/typescript/server/package.json | 1 + sdk/typescript/server/src/index.ts | 167 +- .../server/test/conformance.test.mjs | 21 +- sdk/typescript/server/test/machine.test.mjs | 24 + web/app/page.tsx | 660 +- web/app/styles.css | 205 +- web/e2e/bootstrap.spec.ts | 97 +- 162 files changed, 63931 insertions(+), 14943 deletions(-) create mode 100644 docs/authorization.md create mode 100644 docs/invitations.md create mode 100644 docs/migrating-from-supaapps-platform.md create mode 100644 docs/native-mobile-auth.md create mode 100644 docs/platform-user-authentication.md create mode 100644 internal/authorization/permission.go create mode 100644 internal/authorization/permission_test.go create mode 100644 internal/httpapi/application_config_unit_test.go create mode 100644 internal/httpapi/application_invitation_integration_test.go create mode 100644 internal/httpapi/application_redirect_test.go create mode 100644 internal/httpapi/authorization_security_test.go create mode 100644 internal/httpapi/control_auth_events.go create mode 100644 internal/httpapi/control_auth_policy.go create mode 100644 internal/httpapi/control_external_auth.go create mode 100644 internal/httpapi/control_external_auth_integration_test.go create mode 100644 internal/httpapi/control_origin_test.go create mode 100644 internal/httpapi/control_user_account.go create mode 100644 internal/httpapi/control_user_account_test.go create mode 100644 internal/httpapi/control_user_boundary_test.go create mode 100644 internal/httpapi/control_user_invitations.go create mode 100644 internal/httpapi/control_user_sessions.go create mode 100644 internal/httpapi/cors.go create mode 100644 internal/httpapi/cors_test.go create mode 100644 internal/httpapi/external_auth_callback_test.go rename internal/httpapi/{installation_operators.go => installation_control_users.go} (56%) create mode 100644 internal/httpapi/invitations.go create mode 100644 internal/httpapi/lifecycle_worker.go create mode 100644 internal/httpapi/migration_parity_unit_test.go delete mode 100644 internal/httpapi/operator_account.go delete mode 100644 internal/httpapi/operator_account_test.go delete mode 100644 internal/httpapi/operator_boundary_test.go delete mode 100644 internal/httpapi/operator_sessions.go create mode 100644 internal/httpapi/permission_grants.go create mode 100644 internal/httpapi/service_api.go delete mode 100644 migrations/00002_product_entitlement_defaults.sql delete mode 100644 migrations/00003_event_type_registry.sql delete mode 100644 migrations/00004_provider_inheritance.sql delete mode 100644 migrations/00005_organization_notifications.sql delete mode 100644 migrations/00006_system_notification_templates.sql delete mode 100644 migrations/00007_free_form_features.sql delete mode 100644 migrations/00008_application_configuration.sql delete mode 100644 migrations/00009_event_contracts.sql delete mode 100644 migrations/00010_operator_passwords.sql delete mode 100644 migrations/00011_organization_management.sql delete mode 100644 migrations/00012_notification_localization.sql delete mode 100644 migrations/00013_object_storage.sql create mode 100644 schemas/events/migration-parity-1.0.schema.json create mode 100644 sdk/go/client/client.go create mode 100644 sdk/go/client/client_test.go create mode 100644 sdk/php/README.md create mode 100644 sdk/php/src/MachineClient.php create mode 100644 sdk/php/src/Permission.php create mode 100644 sdk/python/auth/src/platform93_auth/machine.py create mode 100644 sdk/typescript/expo/README.md create mode 100644 sdk/typescript/expo/package.json create mode 100644 sdk/typescript/expo/src/index.ts create mode 100644 sdk/typescript/expo/test/expo.test.mjs create mode 100644 sdk/typescript/expo/tsconfig.json create mode 100644 sdk/typescript/server/test/machine.test.mjs diff --git a/AGENTS.md b/AGENTS.md index cc0aef4..d8f48eb 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -6,7 +6,7 @@ This is the public Platform93 source repository. - Never commit credentials, tokens, private keys, environment dumps, production data, or customer-specific context. - Do not copy private commercial plans or managed-service operations into this repository. - Public contracts must be represented in OpenAPI or versioned JSON Schema. -- Preserve explicit separation between installation operators and application users. +- Preserve explicit separation between Platform users and application users. - Add migrations for schema changes; never rely on automatic production synchronization. - Add tests for authorization, application isolation, idempotency, and public contract changes. - Refer to integrations generically as existing applications or other applications. diff --git a/README.md b/README.md index 67c7e2f..5a85823 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ the only required runtime service. It keeps authoritative security and commercial state outside application code and exposes it through versioned APIs, events, and generated SDKs. +Authorization uses strict relative permission keys, reusable roles, and optional +identity-specific direct grants. See [application authorization](docs/authorization.md). + > The control plane outside your app. Platform93 targets fresh installations and new contracts. It does not include @@ -57,13 +60,17 @@ go build ./cmd/platform93 - `@supaapps/platform93-sdk`: generated TypeScript API client. - `@supaapps/platform93-auth`: headless browser authentication and token storage adapters. +- `@supaapps/platform93-expo`: Expo/React Native auth sessions with SecureStore-backed refresh credentials. - `@supaapps/platform93-react`: React provider and authentication hooks. - `@supaapps/platform93-server`: strict Node.js JWT/JWKS verification. - `@supaapps/platform93-events`: event contracts and webhook verification. - `supaapps/platform93`: Composer authentication/webhook package with optional Laravel guard. - `supaapps-platform93-auth`: Python verifier with FastAPI, Django, and Flask adapters. - `supaapps-platform93-webhooks`: Python webhook signature verification. -- `github.com/supaapps/platform93/sdk/go`: Go authentication, webhook, and direct-storage packages. +- `github.com/supaapps/platform93/sdk/go`: Go authentication, machine-client, webhook, and direct-storage packages. + +Native applications can register exact custom-scheme callbacks on public clients; see +[Native mobile authentication](docs/native-mobile-auth.md). ## Principles @@ -75,13 +82,20 @@ go build ./cmd/platform93 - The repository never contains deployment credentials or private application data. See [Architecture Principles](docs/architecture.md), +[Platform User Authentication](docs/platform-user-authentication.md), [Application Configuration](docs/application-configuration.md), +[Application And Workspace Invitations](docs/invitations.md), [Catalog And Entitlements](docs/catalog-entitlements.md), [Notification Templates](docs/notifications.md), [Provider Inheritance](docs/provider-inheritance.md), [Organization Management And Governance](docs/organization-management.md), [Events And Webhooks](docs/events-webhooks.md), [Optional Object Storage](docs/object-storage.md), +[Migration From Supaapps Platform](docs/migrating-from-supaapps-platform.md), +[Helm deployment](deploy/helm/platform93/README.md), +[Upgrades](docs/upgrades.md), +[Release process](docs/releasing.md), +[v0.1.0 security review record](docs/security-review-0.1.0.md), [Contributing](CONTRIBUTING.md), and [Security Policy](SECURITY.md). ## License diff --git a/api/openapi/platform93.openapi30.yaml b/api/openapi/platform93.openapi30.yaml index a80c148..efac5d2 100644 --- a/api/openapi/platform93.openapi30.yaml +++ b/api/openapi/platform93.openapi30.yaml @@ -3,1367 +3,14827 @@ openapi: 3.0.3 info: title: Platform93 API version: 0.1.0 - license: { name: Apache-2.0, identifier: Apache-2.0 } + license: + name: Apache-2.0 + identifier: Apache-2.0 description: Public contract for fresh Platform93 installations. -servers: [{ url: / }] -security: [{ bearerAuth: [] }] +servers: + - url: / +security: + - bearerAuth: [] tags: - - { name: System, description: Process health and build information. } - - { name: Setup, description: One-time installation bootstrap. } - - { name: Control, description: "Installation operators, organizations, and applications." } - - { name: Management, description: "Machine-only installation provisioning and organization governance." } - - { name: Identity, description: Application-user authentication and profiles. } - - { name: Catalog, description: "Features, products, and immutable prices." } - - { name: Entitlements, description: Grants and local entitlement requests. } - - { name: Billing, description: Provider connections and billing lifecycle. } - - { name: Storage, description: Optional tenant-aware S3-compatible object storage. } - - { name: Events, description: "Domain events, outgoing webhooks, and audit." } + - name: System + description: Process health and build information. + - name: Setup + description: One-time installation bootstrap. + - name: Control + description: Platform users, organizations, and applications. + - name: Management + description: Machine-only installation provisioning and organization governance. + - name: Identity + description: Application-user authentication and profiles. + - name: Catalog + description: Features, products, and immutable prices. + - name: Entitlements + description: Grants and local entitlement requests. + - name: Billing + description: Provider connections and billing lifecycle. + - name: Storage + description: Optional tenant-aware S3-compatible object storage. + - name: Events + description: Domain events, outgoing webhooks, and audit. paths: /healthz: - get: { operationId: health, tags: [System], security: [], responses: { "200": { description: Process is alive } } } + get: + operationId: health + tags: + - System + security: [] + responses: + '200': + description: Process is alive + content: + application/json: + schema: + $ref: '#/components/schemas/HealthStatus' /readyz: - get: { operationId: readiness, tags: [System], security: [], responses: { "200": { description: Process is ready }, "503": { $ref: "#/components/responses/Problem" } } } + get: + operationId: readiness + tags: + - System + security: [] + responses: + '200': + description: Process is ready + content: + application/json: + schema: + $ref: '#/components/schemas/HealthStatus' + '503': + $ref: '#/components/responses/Problem' /version: - get: { operationId: version, tags: [System], security: [], responses: { "200": { description: Build information, content: { application/json: { schema: { type: object } } } } } } + get: + operationId: version + tags: + - System + security: [] + responses: + '200': + description: Build information + content: + application/json: + schema: + $ref: '#/components/schemas/VersionInfo' /v1/setup/status: - get: { operationId: setupStatus, tags: [Setup], security: [], responses: { "200": { description: Setup and operator login availability, content: { application/json: { schema: { type: object, required: [available, operator_email_login_available], properties: { available: { type: boolean }, operator_email_login_available: { type: boolean } } } } } } } } + get: + operationId: setupStatus + tags: + - Setup + security: [] + responses: + '200': + description: Setup and Platform user login availability + content: + application/json: + schema: + $ref: '#/components/schemas/SetupStatus' /v1/setup/bootstrap: post: operationId: bootstrap - tags: [Setup] + tags: + - Setup security: [] - requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/BootstrapRequest" } } } } - responses: { "201": { description: Setup-only operator session }, "401": { $ref: "#/components/responses/Problem" } } + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BootstrapRequest' + responses: + '201': + description: Setup-only Platform user session + content: + application/json: + schema: + $ref: '#/components/schemas/SetupSession' + '401': + $ref: '#/components/responses/Problem' /v1/setup/complete: - post: { operationId: completeSetup, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Setup completed }, "409": { $ref: "#/components/responses/Problem" } } } + post: + operationId: completeSetup + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/CompleteSetup' + responses: + '200': + description: Setup completed + content: + application/json: + schema: + $ref: '#/components/schemas/SetupCompletion' + '409': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' /v1/setup/notification-providers: - post: { operationId: createSetupNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: Installation SMTP provider stored } } } + post: + operationId: createSetupNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: Installation SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/auth/email/start: - post: { operationId: startOperatorEmailLogin, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [email], properties: { email: { type: string, format: email }, delivery: { enum: [code, link, both] } } } } } }, responses: { "202": { description: Enumeration-safe operator challenge accepted } } } + post: + operationId: startControlUserEmailLogin + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlEmailStart' + responses: + '202': + description: Enumeration-safe Platform user challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/control/auth/email/verify: - post: { operationId: verifyOperatorEmailLogin, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/EmailVerify" } } } }, responses: { "200": { description: Operator cookie session created } } } + post: + operationId: verifyControlUserEmailLogin + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailVerify' + responses: + '200': + description: Platform user cookie session created + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' /v1/control/auth/password: - post: { operationId: loginOperatorWithPassword, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/OperatorPasswordLogin" } } } }, responses: { "200": { description: Operator cookie session created }, "401": { $ref: "#/components/responses/Problem" } } } - put: { operationId: changeOperatorPassword, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/OperatorPasswordChange" } } } }, responses: { "204": { description: Password stored and other operator sessions revoked }, "409": { $ref: "#/components/responses/Problem" } } } + post: + operationId: loginControlUserWithPassword + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserPasswordLogin' + responses: + '200': + description: Platform user cookie session created + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '401': + $ref: '#/components/responses/Problem' + put: + operationId: changeControlUserPassword + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserPasswordChange' + responses: + '204': + description: Password stored and other Platform user sessions revoked + '409': + $ref: '#/components/responses/Problem' /v1/control/auth/me: - get: { operationId: getOperatorAccount, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Current operator profile and sign-in methods } } } - patch: { operationId: updateOperatorAccount, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [display_name], properties: { display_name: { type: string, minLength: 1, maxLength: 200 } }, additionalProperties: false } } } }, responses: { "204": { description: Operator profile updated } } } + get: + operationId: getControlUserAccount + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Current Platform user profile and sign-in methods + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserAccount' + patch: + operationId: updateControlUserAccount + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateControlUserAccount' + responses: + '204': + description: Platform user profile updated /v1/control/auth/logout: - post: { operationId: logoutOperator, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Operator session revoked } } } + post: + operationId: logoutControlUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Platform user session revoked /v1/control/auth/token/refresh: - post: { operationId: refreshOperatorSession, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Operator session credential rotated } } } + post: + operationId: refreshControlUserSession + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Platform user session credential rotated + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' /v1/control/auth/sessions: - get: { operationId: listOperatorSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listControlUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listControlUserSessions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SessionPage' /v1/control/auth/sessions/{session_id}: - parameters: [{ name: session_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeOperatorSession, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Operator session revoked } } } + parameters: + - name: session_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeControlUserSession + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Platform user session revoked /v1/control/auth/logout-all: - post: { operationId: logoutAllOperatorSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: All operator sessions revoked } } } - /v1/control/organization-invitations/accept: - post: { operationId: acceptOrganizationInvitation, tags: [Control], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/AcceptOrganizationInvitation" } } } }, responses: { "200": { description: Invitation accepted and operator cookie issued }, "401": { $ref: "#/components/responses/Problem" } } } + post: + operationId: logoutAllControlUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: All Platform user sessions revoked + /v1/control/auth/methods: + get: + operationId: getControlAuthMethods + tags: + - Identity + security: [] + responses: + '200': + description: Available Platform user sign-in methods + content: + application/json: + schema: + $ref: '#/components/schemas/ControlAuthMethods' + /v1/control/auth/providers/{provider}/start: + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + post: + operationId: startControlExternalLogin + tags: + - Identity + security: [] + responses: + '201': + description: External Platform sign-in started + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/control/auth/providers/{provider}/link: + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + post: + operationId: linkControlExternalIdentity + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '201': + description: External Platform identity link started + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/control/auth/identities/{identity_id}: + parameters: + - name: identity_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: unlinkControlExternalIdentity + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: External Platform identity unlinked + '409': + $ref: '#/components/responses/Problem' + /v1/control/invitations/accept: + post: + operationId: acceptControlUserInvitation + tags: + - Control + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AcceptControlUserInvitation' + responses: + '200': + description: Invitation accepted and Platform user cookie issued + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '401': + $ref: '#/components/responses/Problem' + /v1/control/invitations/providers/{provider}/start: + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + post: + operationId: startControlInvitationExternalLogin + tags: + - Control + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlInvitationProviderStart' + responses: + '201': + description: Provider-backed invitation acceptance started + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' /v1/control/installation/notification-providers: - get: { operationId: listInstallationNotificationProviders, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: Installation SMTP provider stored } } } + get: + operationId: listInstallationNotificationProviders + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationNotificationProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProviderPage' + post: + operationId: createInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: Installation SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/installation/notification-providers/{provider_id}: - parameters: [{ name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation notification provider metadata }, "404": { $ref: "#/components/responses/Problem" } } } - patch: { operationId: updateInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Installation notification provider updated }, "404": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation notification provider disabled }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation notification provider metadata + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + '404': + $ref: '#/components/responses/Problem' + patch: + operationId: updateInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateSMTPProvider' + responses: + '200': + description: Installation notification provider updated + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + '404': + $ref: '#/components/responses/Problem' + delete: + operationId: disableInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation notification provider disabled + '404': + $ref: '#/components/responses/Problem' /v1/control/installation/notification-providers/{provider_id}/verify: - parameters: [{ name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: SMTP connectivity and credentials verified }, "502": { $ref: "#/components/responses/Problem" } } } + parameters: + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: SMTP connectivity and credentials verified + '502': + $ref: '#/components/responses/Problem' /v1/control/installation/notification-providers/{provider_id}/test: - parameters: [{ name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Installation SMTP test queued }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TestNotificationProvider' + responses: + '202': + description: Installation SMTP test queued + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationQueued' + '404': + $ref: '#/components/responses/Problem' /v1/control/installation/auth/providers: - get: { operationId: listInstallationAuthProviders, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listInstallationAuthProviders + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/control/installation/auth/providers/{provider}: - parameters: [{ name: provider, in: path, required: true, schema: { type: string, enum: [google, apple] } }] - put: { operationId: configureInstallationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Installation authentication provider configured } } } - patch: { operationId: updateInstallationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/ProviderInheritance" }, responses: { "204": { description: Installation authentication provider inheritance updated }, "404": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableInstallationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation authentication provider disabled } } } + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + put: + operationId: configureInstallationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Installation authentication provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' + patch: + operationId: updateInstallationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateInstallationAuthProvider' + responses: + '204': + description: Installation authentication provider settings updated + '404': + $ref: '#/components/responses/Problem' + delete: + operationId: disableInstallationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation authentication provider disabled /v1/control/installation/billing/providers: - get: { operationId: listInstallationBillingProviders, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateBillingProvider" } } } }, responses: { "201": { description: Installation billing provider configured } } } + get: + operationId: listInstallationBillingProviders + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationBillingProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderPage' + post: + operationId: createInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBillingProvider' + responses: + '201': + description: Installation billing provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' /v1/control/installation/billing/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free installation billing provider } } } - patch: { operationId: updateInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Installation billing provider updated } } } - delete: { operationId: disableInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation billing provider disabled } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free installation billing provider + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' + patch: + operationId: updateInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProvider' + responses: + '204': + description: Installation billing provider updated + delete: + operationId: disableInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation billing provider disabled /v1/control/installation/billing/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation billing provider credentials verified } } } - /v1/control/installation/operators: - get: { operationId: listInstallationOperators, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationOperator, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Installation operator and role created } } } - /v1/control/installation/operators/{operator_id}: - parameters: [{ name: operator_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateInstallationOperator, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Installation role updated } } } - delete: { operationId: deleteInstallationOperator, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation role removed and sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation billing provider credentials verified + /v1/control/installation/users: + get: + operationId: listInstallationControlUsers + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationControlUsers response. + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserPage' + /v1/control/installation/users/{control_user_id}: + parameters: + - name: control_user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateInstallationControlUser + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MembershipRole' + responses: + '204': + description: Installation role updated + delete: + operationId: deleteInstallationControlUser + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation role removed and sessions revoked + /v1/control/installation/invitations: + get: + operationId: listInstallationControlUserInvitations + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationControlUserInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitationPage' + post: + operationId: createInstallationControlUserInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateControlUserInvitation' + responses: + '201': + description: Platform user invitation created and credential returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' + /v1/control/installation/invitations/{invitation_id}/resend: + parameters: + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendInstallationControlUserInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateControlInvitationMethod' + responses: + '200': + description: Platform user invitation rotated + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' + /v1/control/installation/invitations/{invitation_id}: + parameters: + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeInstallationControlUserInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Platform user invitation revoked + /v1/control/installation/auth-policy: + get: + operationId: getControlAuthPolicy + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Platform authentication policy + content: + application/json: + schema: + $ref: '#/components/schemas/ControlAuthPolicy' + patch: + operationId: updateControlAuthPolicy + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateControlAuthPolicy' + responses: + '204': + description: Platform authentication policy updated + '409': + $ref: '#/components/responses/Problem' /v1/control/installation/signing-keys: - get: { operationId: listSigningKeys, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listSigningKeys + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listSigningKeys response. + content: + application/json: + schema: + $ref: '#/components/schemas/SigningKeyPage' /v1/control/installation/signing-keys/rotate: - post: { operationId: rotateSigningKey, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "201": { description: New installation signing key activated } } } + post: + operationId: rotateSigningKey + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '201': + description: New installation signing key activated + content: + application/json: + schema: + $ref: '#/components/schemas/SigningKey' /v1/control/installation/management-api: - get: { operationId: getManagementAPIStatus, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Management API installation status, content: { application/json: { schema: { $ref: "#/components/schemas/ManagementAPIStatus" } } } } } } - patch: { operationId: updateManagementAPIStatus, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [enabled], properties: { enabled: { type: boolean } }, additionalProperties: false } } } }, responses: { "200": { description: Management API status updated } } } + get: + operationId: getManagementAPIStatus + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Management API installation status + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementAPIStatus' + patch: + operationId: updateManagementAPIStatus + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateManagementAPI' + responses: + '200': + description: Management API status updated + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementAPIStatus' /v1/control/installation/management-clients: - get: { operationId: listManagementClients, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createManagementClient, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateManagementClient" } } } }, responses: { "201": { description: Management client created and secret returned once }, "409": { $ref: "#/components/responses/Problem" } } } + get: + operationId: listManagementClients + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listManagementClients response. + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementClientPage' + post: + operationId: createManagementClient + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateManagementClient' + responses: + '201': + description: Management client created and secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementClient' + '409': + $ref: '#/components/responses/Problem' /v1/control/installation/management-clients/{management_client_id}/rotate-secret: - parameters: [{ name: management_client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: rotateManagementClientSecret, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Management client secret rotated and returned once } } } + parameters: + - name: management_client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: rotateManagementClientSecret + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Management client secret rotated and returned once + content: + application/json: + schema: + $ref: '#/components/schemas/SecretCredential' /v1/control/installation/management-clients/{management_client_id}: - parameters: [{ name: management_client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: disableManagementClient, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Management client disabled and all of its tokens invalidated } } } + parameters: + - name: management_client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: disableManagementClient + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Management client disabled and all of its tokens invalidated /v1/control/installation/organizations/{organization_id}/policy: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - put: { operationId: updateOrganizationPolicy, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateOrganizationPolicy" } } } }, responses: { "204": { description: Installation-owned organization policy updated }, "412": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + put: + operationId: updateOrganizationPolicy + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOrganizationPolicy' + responses: + '204': + description: Installation-owned organization policy updated + '412': + $ref: '#/components/responses/Problem' /v1/control/organizations: - get: { operationId: listOrganizations, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { description: Accessible organizations and the current installation role, content: { application/json: { schema: { $ref: "#/components/schemas/OrganizationPage" } } } } } } - post: { operationId: createOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Organization created }, "409": { $ref: "#/components/responses/Problem" } } } + get: + operationId: listOrganizations + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Accessible organizations and the current installation role + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPage' + post: + operationId: createOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Organization created + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' + '409': + $ref: '#/components/responses/Problem' /v1/control/organizations/{organization_id}/applications: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listApplications, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Application created } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listApplications + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Successful listApplications response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationPage' + post: + operationId: createApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Application created + content: + application/json: + schema: + $ref: '#/components/schemas/Application' /v1/control/organizations/{organization_id}/applications/{application_resource_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Application renamed }, "412": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: retireApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application retired and live credentials revoked } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Application renamed + '412': + $ref: '#/components/responses/Problem' + delete: + operationId: retireApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application retired and live credentials revoked /v1/control/organizations/{organization_id}/applications/{application_resource_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: restoreApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application restored without restoring revoked credentials } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: restoreApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application restored without restoring revoked credentials /v1/control/organizations/{organization_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: getOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Organization details } } } - patch: { operationId: updateOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Organization renamed }, "412": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: retireOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization and active descendants retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: getOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Organization details + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' + patch: + operationId: updateOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Organization renamed + '412': + $ref: '#/components/responses/Problem' + delete: + operationId: retireOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization and active descendants retired /v1/control/organizations/{organization_id}/policy: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: getOrganizationPolicy, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Organization policy and current usage, content: { application/json: { schema: { $ref: "#/components/schemas/OrganizationPolicy" } } } } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: getOrganizationPolicy + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Organization policy and current usage + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPolicy' /v1/control/organizations/{organization_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - post: { operationId: restoreOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization restored; descendants remain retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + post: + operationId: restoreOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization restored; descendants remain retired /v1/control/organizations/{organization_id}/members: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationMembers, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationMembers + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationMembers response. + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationMemberPage' /v1/control/organizations/{organization_id}/members/{member_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: member_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateOrganizationMember, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Organization role updated } } } - delete: { operationId: deleteOrganizationMember, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization member removed } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: member_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateOrganizationMember + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MembershipRole' + responses: + '204': + description: Organization role updated + delete: + operationId: deleteOrganizationMember + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization member removed /v1/control/organizations/{organization_id}/invitations: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationInvitations, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Invitation queued and credential returned once } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationInvitations + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitationPage' + post: + operationId: createOrganizationInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateControlUserInvitation' + responses: + '201': + description: Invitation queued and credential returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' /v1/control/organizations/{organization_id}/invitations/{invitation_id}/resend: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: resendOrganizationInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Invitation credential rotated and delivery queued } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendOrganizationInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Invitation credential rotated and delivery queued + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' /v1/control/organizations/{organization_id}/invitations/{invitation_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeOrganizationInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Pending invitation revoked } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeOrganizationInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Pending invitation revoked /v1/control/organizations/{organization_id}/audit-logs: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationAuditLogs, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationAuditLogs + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationAuditLogs response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuditRecordPage' /v1/control/organizations/{organization_id}/auth/providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationAuthProviders, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationAuthProviders + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/control/organizations/{organization_id}/auth/providers/{provider}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider, in: path, required: true, schema: { type: string, enum: [google, apple] } }] - put: { operationId: configureOrganizationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Organization authentication provider configured } } } - patch: { operationId: updateOrganizationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/ProviderInheritance" }, responses: { "204": { description: Organization authentication provider inheritance updated }, "404": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableOrganizationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization authentication provider disabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + put: + operationId: configureOrganizationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Organization authentication provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' + patch: + operationId: updateOrganizationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/ProviderInheritance' + responses: + '204': + description: Organization authentication provider inheritance updated + '404': + $ref: '#/components/responses/Problem' + delete: + operationId: disableOrganizationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization authentication provider disabled /v1/control/organizations/{organization_id}/notification-providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationNotificationProviders, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: Organization SMTP provider stored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationNotificationProviders + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationNotificationProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProviderPage' + post: + operationId: createOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: Organization SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/organizations/{organization_id}/notification-providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Redacted organization SMTP provider } } } - patch: { operationId: updateOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Organization SMTP provider updated } } } - delete: { operationId: disableOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization SMTP provider disabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Redacted organization SMTP provider + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + patch: + operationId: updateOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateSMTPProvider' + responses: + '200': + description: Organization SMTP provider updated + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + delete: + operationId: disableOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization SMTP provider disabled /v1/control/organizations/{organization_id}/notification-providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization SMTP provider verified } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization SMTP provider verified /v1/control/organizations/{organization_id}/notification-providers/{provider_id}/test: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Organization SMTP test queued } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TestNotificationProvider' + responses: + '202': + description: Organization SMTP test queued + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationQueued' /v1/control/organizations/{organization_id}/billing/providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationBillingProviders, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateBillingProvider" } } } }, responses: { "201": { description: Organization billing provider configured } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationBillingProviders + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationBillingProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderPage' + post: + operationId: createOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBillingProvider' + responses: + '201': + description: Organization billing provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' /v1/control/organizations/{organization_id}/billing/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free organization billing provider } } } - patch: { operationId: updateOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Organization billing provider updated } } } - delete: { operationId: disableOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization billing provider disabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free organization billing provider + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' + patch: + operationId: updateOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProvider' + responses: + '204': + description: Organization billing provider updated + delete: + operationId: disableOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization billing provider disabled /v1/control/organizations/{organization_id}/billing/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization billing provider credentials verified } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization billing provider credentials verified /v1/applications/{application_id}/public-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: publicConfig, tags: [Control], security: [], responses: { "200": { description: Secret-free runtime configuration, content: { application/json: { schema: { $ref: "#/components/schemas/RuntimeConfig" } } } } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: publicConfig + tags: + - Control + security: [] + responses: + '200': + description: Secret-free runtime configuration + content: + application/json: + schema: + $ref: '#/components/schemas/RuntimeConfig' /v1/control/applications/{application_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Application details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Application details + content: + application/json: + schema: + $ref: '#/components/schemas/Application' /v1/control/applications/{application_id}/statistics: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getApplicationStatistics, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Application identity, catalog, billing, and delivery counts" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getApplicationStatistics + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Application identity, catalog, billing, and delivery counts + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationStatistics' /v1/control/applications/{application_id}/public-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - patch: { operationId: updatePublicApplicationConfig, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/PublicApplicationConfig" }, responses: { "204": { description: Explicitly public runtime configuration replaced }, "412": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + patch: + operationId: updatePublicApplicationConfig + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/PublicApplicationConfig' + responses: + '204': + description: Explicitly public runtime configuration replaced + '412': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/internal-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - patch: { operationId: updateInternalApplicationConfig, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/InternalApplicationConfig" }, responses: { "204": { description: Internal application policy updated and disabled credentials revoked }, "412": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + patch: + operationId: updateInternalApplicationConfig + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/InternalApplicationConfig' + responses: + '204': + description: Internal application policy updated and disabled credentials revoked + '412': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/auth-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - patch: { operationId: updateAuthConfig, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/ApplicationAuthConfig" }, responses: { "204": { description: Authentication configuration and PKCE application redirects updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + patch: + operationId: updateAuthConfig + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/ApplicationAuthConfig' + responses: + '204': + description: Authentication configuration and PKCE application redirects updated /v1/control/applications/{application_id}/auth/providers/google: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - put: { operationId: configureGoogleProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Google client configured and callback URI returned } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + put: + operationId: configureGoogleProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Google client configured and callback URI returned + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' /v1/control/applications/{application_id}/auth/providers/apple: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - put: { operationId: configureAppleProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Apple client configured and callback URI returned } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + put: + operationId: configureAppleProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Apple client configured and callback URI returned + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' /v1/control/applications/{application_id}/auth/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationAuthProviders, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationAuthProviders + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/control/applications/{application_id}/auth/providers/{provider}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider, in: path, required: true, schema: { type: string, enum: [google, apple] } }] - delete: { operationId: disableApplicationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application authentication provider disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + delete: + operationId: disableApplicationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application authentication provider disabled /v1/control/applications/{application_id}/domains: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationDomains, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createApplicationDomain, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Domain added and DNS proof returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationDomains + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationDomains response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationDomainPage' + post: + operationId: createApplicationDomain + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateApplicationDomain' + responses: + '201': + description: Domain added and DNS proof returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationDomain' /v1/control/applications/{application_id}/domains/{domain_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: domain_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: deleteApplicationDomain, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Domain removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: domain_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: deleteApplicationDomain + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Domain removed /v1/control/applications/{application_id}/domains/{domain_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: domain_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyApplicationDomain, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: DNS ownership verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: domain_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyApplicationDomain + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: DNS ownership verified /v1/control/applications/{application_id}/clients: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listClients, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createClient, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Client created and secret returned once when applicable } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listClients + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listClients response. + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthClientPage' + post: + operationId: createClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateClient' + responses: + '201': + description: Client created and secret returned once when applicable + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthClient' /v1/control/applications/{application_id}/clients/{client_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: client_id, in: path, required: true, schema: { type: string } }] - patch: { operationId: updateClient, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Client updated } } } - delete: { operationId: disableClient, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Client and active OAuth grants disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: client_id + in: path + required: true + schema: + type: string + get: + operationId: getClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Client detail + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthClient' + patch: + operationId: updateClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateClient' + responses: + '204': + description: Client updated + delete: + operationId: disableClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Client and active OAuth grants disabled /v1/control/applications/{application_id}/clients/{client_id}/rotate-secret: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: client_id, in: path, required: true, schema: { type: string } }] - post: { operationId: rotateClientSecret, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Replacement client secret returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: client_id + in: path + required: true + schema: + type: string + post: + operationId: rotateClientSecret + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Replacement client secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/SecretCredential' /v1/control/applications/{application_id}/roles: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listRoles, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Role created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listRoles + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listRoles response. + content: + application/json: + schema: + $ref: '#/components/schemas/RolePage' + post: + operationId: createRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateRole' + responses: + '201': + description: Role created + content: + application/json: + schema: + $ref: '#/components/schemas/Role' + '422': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/roles/{role_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: role_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Role details }, "404": { $ref: "#/components/responses/Problem" } } } - patch: { operationId: updateRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Role updated }, "409": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: deleteRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Unassigned custom role deleted }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: role_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Role details + content: + application/json: + schema: + $ref: '#/components/schemas/Role' + '404': + $ref: '#/components/responses/Problem' + patch: + operationId: updateRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateRole' + responses: + '204': + description: Role updated + '409': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' + delete: + operationId: deleteRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Unassigned custom role deleted + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/workspaces: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWorkspaces, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listWorkspaces + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWorkspaces response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspacePage' + post: + operationId: createWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkspace' + responses: + '201': + description: Workspace created + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' /v1/control/applications/{application_id}/workspaces/{workspace_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Workspace details } } } - patch: { operationId: updateWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace updated } } } - delete: { operationId: deleteWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Workspace retired and memberships removed }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Workspace details + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' + patch: + operationId: updateWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateWorkspace' + responses: + '204': + description: Workspace updated + delete: + operationId: deleteWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Workspace retired and memberships removed + '404': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/workspaces/{workspace_id}/owner-transfer: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: recoverWorkspaceOwnership, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/OwnershipTransfer" }, responses: { "200": { $ref: "#/components/responses/OwnershipTransferResult" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: recoverWorkspaceOwnership + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/OwnershipTransfer' + responses: + '200': + $ref: '#/components/responses/OwnershipTransferResult' /v1/control/applications/{application_id}/workspaces/{workspace_id}/members: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listWorkspaceMembers, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listWorkspaceMembers + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWorkspaceMembers response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMemberPage' /v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - put: { operationId: replaceWorkspaceMemberRoles, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Workspace member roles replaced atomically } } } - delete: { operationId: deleteWorkspaceMember, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Workspace membership removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + put: + operationId: replaceWorkspaceMemberRoles + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ReplaceWorkspaceMemberRoles' + responses: + '200': + description: Workspace member roles replaced atomically + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMember' + delete: + operationId: deleteWorkspaceMember + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Workspace membership removed /v1/control/applications/{application_id}/role-assignments: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listRoleAssignments, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createRoleAssignment, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/RoleAssignment" }, responses: { "201": { description: User or machine-client role assignment created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listRoleAssignments + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listRoleAssignments response. + content: + application/json: + schema: + $ref: '#/components/schemas/RoleAssignmentPage' + post: + operationId: createRoleAssignment + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/RoleAssignment' + responses: + '201': + description: User or machine-client role assignment created + content: + application/json: + schema: + $ref: '#/components/schemas/RoleAssignmentRecord' /v1/control/applications/{application_id}/role-assignments/{assignment_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: assignment_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: deleteRoleAssignment, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Role assignment deleted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: assignment_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: deleteRoleAssignment + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Role assignment deleted + /v1/control/applications/{application_id}/permission-grants: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/OptionalPermissionSubjectType' + - $ref: '#/components/parameters/OptionalPermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + - $ref: '#/components/parameters/PermissionGrantStatus' + get: + operationId: listControlPermissionGrants + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listControlPermissionGrants response. + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrantPage' + post: + operationId: createControlPermissionGrant + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/PermissionGrantBody' + responses: + '201': + description: Direct permission grant created + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + '422': + $ref: '#/components/responses/Problem' + /v1/control/applications/{application_id}/permission-grants/effective: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PermissionSubjectType' + - $ref: '#/components/parameters/PermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + get: + operationId: getControlEffectiveAccess + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Effective roles and scopes + content: + application/json: + schema: + $ref: '#/components/schemas/EffectiveAccess' + /v1/control/applications/{application_id}/permission-grants/{grant_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: grant_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getControlPermissionGrant + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Direct permission grant + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + delete: + operationId: revokeControlPermissionGrant + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + responses: + '204': + description: Direct permission grant revoked + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/delegations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listDelegations, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createDelegation, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Short-lived one-time delegation exchange credential } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listDelegations + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listDelegations response. + content: + application/json: + schema: + $ref: '#/components/schemas/DelegationPage' + post: + operationId: createDelegation + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateDelegation' + responses: + '201': + description: Short-lived one-time delegation exchange credential + content: + application/json: + schema: + $ref: '#/components/schemas/Delegation' /v1/control/applications/{application_id}/delegations/{delegation_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delegation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getDelegation, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Delegation details and lifecycle state } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delegation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getDelegation + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Delegation details and lifecycle state + content: + application/json: + schema: + $ref: '#/components/schemas/Delegation' /v1/applications/{application_id}/delegations/{delegation_id}/exchange: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delegation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: exchangeDelegation, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Non-refreshable delegated access token } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delegation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: exchangeDelegation + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExchangeDelegation' + responses: + '200': + description: Non-refreshable delegated access token + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + /v1/applications/{application_id}/notifications: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequiredIdempotencyKey' + post: + operationId: sendMachineNotification + tags: + - Events + description: Machine-client-only template notification delivery. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/QueueNotification' + responses: + '202': + description: Notification queued or suppressed + content: + application/json: + schema: + $ref: '#/components/schemas/QueuedNotification' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/permission-grants: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/OptionalPermissionSubjectType' + - $ref: '#/components/parameters/OptionalPermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + - $ref: '#/components/parameters/PermissionGrantStatus' + get: + operationId: listPermissionGrants + tags: + - Control + responses: + '200': + description: Successful listPermissionGrants response. + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrantPage' + '403': + $ref: '#/components/responses/Problem' + post: + operationId: createPermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/PermissionGrantBody' + responses: + '201': + description: Direct permission grant created + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + '403': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/permission-grants/effective: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PermissionSubjectType' + - $ref: '#/components/parameters/PermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + get: + operationId: getEffectiveAccess + tags: + - Control + responses: + '200': + description: Effective roles and scopes + content: + application/json: + schema: + $ref: '#/components/schemas/EffectiveAccess' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/permission-grants/{grant_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: grant_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getPermissionGrant + tags: + - Control + responses: + '200': + description: Direct permission grant + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + delete: + operationId: revokePermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/IfMatch' + responses: + '204': + description: Direct permission grant revoked + '409': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/invitations: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationInvitations + tags: + - Control + responses: + '200': + description: Successful listApplicationInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' + post: + operationId: createApplicationInvitationMachine + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateInvitation' + responses: + '201': + description: Invitation created and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + /v1/applications/{application_id}/invitations/{invitation_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getApplicationInvitation + tags: + - Control + responses: + '200': + description: Invitation detail + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + delete: + operationId: revokeApplicationInvitation + tags: + - Control + responses: + '204': + description: Pending invitation revoked + /v1/applications/{application_id}/invitations/{invitation_id}/resend: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendApplicationInvitation + tags: + - Control + responses: + '202': + description: Invitation credentials rotated and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationResent' + '429': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/users: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: serviceListApplicationUsers + tags: + - Identity + responses: + '200': + description: Successful serviceListApplicationUsers response. + content: + application/json: + schema: + $ref: '#/components/schemas/UserPage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/users/{user_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetApplicationUser + tags: + - Identity + responses: + '200': + description: Redacted application user + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/workspaces: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: serviceListApplicationWorkspaces + tags: + - Control + responses: + '200': + description: Successful serviceListApplicationWorkspaces response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspacePage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/service/workspaces/{workspace_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetApplicationWorkspace + tags: + - Control + responses: + '200': + description: Workspace detail + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/service/workspaces/{workspace_id}/access: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceListApplicationWorkspaceAccess + tags: + - Control + responses: + '200': + description: Successful serviceListApplicationWorkspaceAccess response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceAccessPage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: subject_type + in: path + required: true + schema: + enum: + - user + - workspace + - name: subject_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetSubjectEntitlements + tags: + - Entitlements + responses: + '200': + description: Successful serviceGetSubjectEntitlements response. + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrantPage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: subject_type + in: path + required: true + schema: + enum: + - user + - workspace + - name: subject_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetSubjectBilling + tags: + - Billing + responses: + '200': + description: Subject billing profile and subscription summary + content: + application/json: + schema: + $ref: '#/components/schemas/BillingSummary' + '403': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/delegations/{delegation_id}/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delegation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeDelegation, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Delegation and delegated sessions revoked } } } - /v1/control/applications/{application_id}/workspace-invitations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWorkspaceInvitations, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWorkspaceInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace invitation created and credential returned once } } } - /v1/control/applications/{application_id}/workspace-invitations/{invitation_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeWorkspaceInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Pending workspace invitation revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delegation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeDelegation + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Delegation and delegated sessions revoked + /v1/control/applications/{application_id}/invitations: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationInvitationsControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationInvitationsControl response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' + post: + operationId: createApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateInvitation' + responses: + '201': + description: Application or workspace invitation created and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + /v1/control/applications/{application_id}/invitations/{invitation_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Invitation detail + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + delete: + operationId: revokeApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Pending invitation revoked + /v1/control/applications/{application_id}/invitations/{invitation_id}/resend: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '202': + description: Invitation credentials rotated and localized email queued + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationResent' + '429': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/users: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listUsers, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: User created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listUsers + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listUsers response. + content: + application/json: + schema: + $ref: '#/components/schemas/UserPage' + post: + operationId: createUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateUser' + responses: + '201': + description: User created + content: + application/json: + schema: + $ref: '#/components/schemas/User' /v1/control/applications/{application_id}/users/{user_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: User details } } } - patch: { operationId: updateUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: User details + content: + application/json: + schema: + $ref: '#/components/schemas/User' + patch: + operationId: updateUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateUser' + responses: + '204': + description: User updated /v1/control/applications/{application_id}/users/{user_id}/suspend: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: suspendUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User suspended and active grants revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: suspendUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User suspended and active grants revoked /v1/control/applications/{application_id}/users/{user_id}/restore: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: restoreUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Suspended user restored without restoring old sessions } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: restoreUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Suspended user restored without restoring old sessions /v1/control/applications/{application_id}/users/{user_id}/verify-email: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyUserEmail, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User email administratively verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyUserEmail + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User email administratively verified /v1/control/applications/{application_id}/users/{user_id}/unverify-email: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: unverifyUserEmail, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User email verification removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: unverifyUserEmail + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User email verification removed /v1/control/applications/{application_id}/users/{user_id}/verify-organization: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyUserOrganization, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User organization administratively verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyUserOrganization + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User organization administratively verified /v1/control/applications/{application_id}/users/{user_id}/unverify-organization: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: unverifyUserOrganization, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User organization verification removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: unverifyUserOrganization + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User organization verification removed /v1/control/applications/{application_id}/users/{user_id}/sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listUserSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listUserSessions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SessionPage' /v1/control/applications/{application_id}/users/{user_id}/sessions/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeUserSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: All active user sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: All active user sessions revoked + content: + application/json: + schema: + $ref: '#/components/schemas/RevokedSessionCount' /v1/control/applications/{application_id}/users/{user_id}/addresses: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listUserAddresses, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listUserAddresses + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listUserAddresses response. + content: + application/json: + schema: + $ref: '#/components/schemas/AddressPage' /v1/control/applications/{application_id}/oauth-consents: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listOAuthConsents, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listOAuthConsents + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOAuthConsents response. + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthConsentPage' /v1/control/applications/{application_id}/oauth-consents/{user_id}/{client_id}/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeOAuthConsent, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Consent and active grants revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeOAuthConsent + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Consent and active grants revoked /v1/control/applications/{application_id}/features: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listFeatures, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createFeature, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateFeature" } } } }, responses: { "201": { description: Feature created }, "422": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listFeatures + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listFeatures response. + content: + application/json: + schema: + $ref: '#/components/schemas/FeaturePage' + post: + operationId: createFeature + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFeature' + responses: + '201': + description: Feature created + content: + application/json: + schema: + $ref: '#/components/schemas/Feature' + '422': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/password/sign-up: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordSignUp, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PasswordSignUp" } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "403": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordSignUp + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordSignUp' + responses: + '200': + $ref: '#/components/responses/Tokens' + '403': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/password/sign-in: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordSignIn, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PasswordSignIn" } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "401": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordSignIn + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordSignIn' + responses: + '200': + $ref: '#/components/responses/Tokens' + '401': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/methods: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: authMethods, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Enumeration-safe enabled authentication methods } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: authMethods + tags: + - Identity + security: [] + responses: + '200': + description: Enumeration-safe enabled authentication methods + content: + application/json: + schema: + $ref: '#/components/schemas/AuthMethods' /v1/applications/{application_id}/auth/email/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailStart, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/EmailStart" } } } }, responses: { "202": { description: Enumeration-safe challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailStart + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailStart' + responses: + '202': + description: Enumeration-safe challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/auth/email/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailVerify, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/EmailVerify" } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailVerify + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailVerify' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/token/refresh: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: refresh, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [refresh_token], properties: { refresh_token: { type: string, writeOnly: true } } } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: refresh + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RefreshToken' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/password/reset/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordResetStart, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Enumeration-safe reset challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordResetStart + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordResetStart' + responses: + '202': + description: Enumeration-safe reset challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/auth/password/reset/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordResetVerify, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordResetVerify + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordResetVerify' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listAuthProviders, tags: [Identity], security: [], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listAuthProviders + tags: + - Identity + security: [] + responses: + '200': + description: Successful listAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/applications/{application_id}/auth/providers/google/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startGoogleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: "Google authorization URL with state, nonce, and S256 PKCE" } } } - /v1/applications/{application_id}/auth/providers/google/callback: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: googleAuthCallback, tags: [Identity], security: [], responses: { "302": { description: Redirect with one-time Platform93 exchange credential } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startGoogleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Google authorization URL with state, nonce, and S256 PKCE + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/auth/providers/google/callback: + get: + operationId: googleAuthCallback + tags: + - Identity + security: [] + responses: + '302': + description: Installation-wide callback that resolves the application from protected OAuth state and redirects with a one-time Platform93 exchange credential /v1/applications/{application_id}/auth/providers/google/exchange: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: exchangeGoogleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: exchangeGoogleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthExchange' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/providers/apple/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startAppleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Apple authorization URL with state and nonce } } } - /v1/applications/{application_id}/auth/providers/apple/callback: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: appleAuthCallback, tags: [Identity], security: [], requestBody: { required: false, content: { application/x-www-form-urlencoded: { schema: { type: object, properties: { code: { type: string }, state: { type: string }, user: { type: string }, error: { type: string } } } } } }, responses: { "302": { description: Redirect with one-time Platform93 exchange credential } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startAppleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Apple authorization URL with state and nonce + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/auth/providers/apple/callback: + post: + operationId: appleAuthCallback + tags: + - Identity + security: [] + requestBody: + required: false + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + code: + type: string + state: + type: string + user: + type: string + error: + type: string + responses: + '302': + description: Installation-wide callback that resolves the application from protected OAuth state and redirects with a one-time Platform93 exchange credential /v1/applications/{application_id}/auth/providers/apple/exchange: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: exchangeAppleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: exchangeAppleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthExchange' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/mfa/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: verifyMFA, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "401": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: verifyMFA + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VerifyMFA' + responses: + '200': + $ref: '#/components/responses/Tokens' + '401': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/mfa/webauthn/options: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: beginWebAuthnAuthentication, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: WebAuthn assertion options and opaque ceremony identifier } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: beginWebAuthnAuthentication + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BeginWebAuthnAuthentication' + responses: + '201': + description: WebAuthn assertion options and opaque ceremony identifier + content: + application/json: + schema: + $ref: '#/components/schemas/WebAuthnChallenge' /v1/applications/{application_id}/auth/mfa/webauthn/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: finishWebAuthnAuthentication, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "401": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: finishWebAuthnAuthentication + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FinishWebAuthnCeremony' + responses: + '200': + $ref: '#/components/responses/Tokens' + '401': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/auth/invitations/exchange: + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: exchangeApplicationInvitation + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExchangeInvitation' + responses: + '200': + description: Invitation accepted and a short-lived PKCE-bound authorization code returned + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationExchangeResult' + '401': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/auth/invitations/token: + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: redeemApplicationInvitation + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RedeemInvitation' + responses: + '200': + description: Authentication completed or MFA challenge returned + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '401': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/me: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getCurrentUser, tags: [Identity], responses: { "200": { description: Current user, content: { application/json: { schema: { $ref: "#/components/schemas/User" } } } } } } - patch: { operationId: updateCurrentUser, tags: [Identity], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateUserProfile" } } } }, responses: { "204": { description: Profile updated } } } - delete: { operationId: deleteMyAccount, tags: [Identity], responses: { "204": { description: Account deleted and credentials revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getCurrentUser + tags: + - Identity + responses: + '200': + description: Current user + content: + application/json: + schema: + $ref: '#/components/schemas/User' + patch: + operationId: updateCurrentUser + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateUserProfile' + responses: + '204': + description: Profile updated + delete: + operationId: deleteMyAccount + tags: + - Identity + responses: + '204': + description: Account deleted and credentials revoked /v1/applications/{application_id}/auth/logout: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: logoutCurrentSession, tags: [Identity], responses: { "204": { description: Current interactive session revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: logoutCurrentSession + tags: + - Identity + responses: + '204': + description: Current interactive session revoked /v1/applications/{application_id}/me/api-keys: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listPersonalAPIKeys, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" }, "403": { $ref: "#/components/responses/Problem" } } } - post: { operationId: createPersonalAPIKey, tags: [Identity], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreatePersonalAPIKey" } } } }, responses: { "201": { description: Key created and secret returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listPersonalAPIKeys + tags: + - Identity + responses: + '200': + description: Successful listPersonalAPIKeys response. + content: + application/json: + schema: + $ref: '#/components/schemas/PersonalAPIKeyPage' + '403': + $ref: '#/components/responses/Problem' + post: + operationId: createPersonalAPIKey + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePersonalAPIKey' + responses: + '201': + description: Key created and secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/PersonalAPIKeyCreated' /v1/applications/{application_id}/catalog/products: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: publicCatalog, tags: [Catalog], security: [], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: publicCatalog + tags: + - Catalog + security: [] + responses: + '200': + description: Successful publicCatalog response. + content: + application/json: + schema: + $ref: '#/components/schemas/ProductPage' /v1/control/applications/{application_id}/products: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listProducts, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createProduct, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateProduct" } } } }, responses: { "201": { description: Product created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listProducts + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listProducts response. + content: + application/json: + schema: + $ref: '#/components/schemas/ProductPage' + post: + operationId: createProduct + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateProduct' + responses: + '201': + description: Product created + content: + application/json: + schema: + $ref: '#/components/schemas/Product' /v1/control/applications/{application_id}/products/{product_id}/prices: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: product_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listPrices, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createPrice, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreatePrice" } } } }, responses: { "201": { description: Immutable price created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: product_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listPrices + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listPrices response. + content: + application/json: + schema: + $ref: '#/components/schemas/PricePage' + post: + operationId: createPrice + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePrice' + responses: + '201': + description: Immutable price created + content: + application/json: + schema: + $ref: '#/components/schemas/Price' /v1/control/applications/{application_id}/products/{product_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: product_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getProduct, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Product details } } } - patch: { operationId: updateProduct, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateProduct" } } } }, responses: { "204": { description: Product updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: product_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getProduct + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Product details + content: + application/json: + schema: + $ref: '#/components/schemas/Product' + patch: + operationId: updateProduct + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateProduct' + responses: + '204': + description: Product updated /v1/control/applications/{application_id}/entitlements: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listEntitlements, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Entitlement grant created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listEntitlements + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listEntitlements response. + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrantPage' + post: + operationId: createEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEntitlement' + responses: + '201': + description: Entitlement grant created + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrant' /v1/control/applications/{application_id}/entitlements/{entitlement_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: entitlement_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Entitlement grant, effective state, and append-only actions" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Entitlement grant, effective state, and append-only actions + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrant' /v1/control/applications/{application_id}/entitlements/{entitlement_id}/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: entitlement_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Append-only revocation recorded } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Append-only revocation recorded + /v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: adjustEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AdjustEntitlement' + responses: + '204': + description: Append-only expiry adjustment recorded /v1/control/applications/{application_id}/entitlements/{entitlement_id}/restore: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: entitlement_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: restoreEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Append-only restoration recorded } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: restoreEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Append-only restoration recorded /v1/control/applications/{application_id}/local-entitlement-requests: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listLocalEntitlementRequests, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listLocalEntitlementRequests + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listLocalEntitlementRequests response. + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequestPage' /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - get: { operationId: getLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Local request with immutable snapshots and action history } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + get: + operationId: getLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Local request with immutable snapshots and action history + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequest' /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/approve: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: approveLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Request approved exactly once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: approveLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '200': + description: Request approved exactly once + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementApproval' /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/reject: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: rejectLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Request rejected } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: rejectLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Request rejected /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/reopen: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: reopenLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Rejected or canceled request reopened for review } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: reopenLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Rejected or canceled request reopened for review /v1/applications/{application_id}/local-entitlement-checkouts: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: localEntitlementCheckout, tags: [Entitlements], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/LocalCheckout" } } } }, responses: { "201": { description: Pending local entitlement request } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: localEntitlementCheckout + tags: + - Entitlements + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LocalCheckout' + responses: + '201': + description: Pending local entitlement request + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequest' /v1/applications/{application_id}/me/local-entitlement-requests: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyLocalEntitlementRequests, tags: [Entitlements], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyLocalEntitlementRequests + tags: + - Entitlements + responses: + '200': + description: Successful listMyLocalEntitlementRequests response. + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequestPage' /v1/applications/{application_id}/me/local-entitlement-requests/{request_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - get: { operationId: getMyLocalEntitlementRequest, tags: [Entitlements], responses: { "200": { description: Own local request with immutable snapshots and action history } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + get: + operationId: getMyLocalEntitlementRequest + tags: + - Entitlements + responses: + '200': + description: Own local request with immutable snapshots and action history + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequest' /v1/applications/{application_id}/me/local-entitlement-requests/{request_id}/cancel: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: cancelMyLocalEntitlementRequest, tags: [Entitlements], responses: { "204": { description: Pending request canceled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: cancelMyLocalEntitlementRequest + tags: + - Entitlements + responses: + '204': + description: Pending request canceled /v1/applications/{application_id}/me/entitlements: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceIDQuery" }] - get: { operationId: listMyEntitlements, tags: [Entitlements], responses: { "200": { description: "Effective user entitlements, optionally merged with one accessible workspace and full provenance" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + get: + operationId: listMyEntitlements + tags: + - Entitlements + responses: + '200': + description: Effective user entitlements, optionally merged with one accessible workspace and full provenance + content: + application/json: + schema: + $ref: '#/components/schemas/EffectiveEntitlements' /v1/control/applications/{application_id}/billing/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listBillingProviders, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateBillingProvider" } } } }, responses: { "201": { description: Billing provider configured } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listBillingProviders + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listBillingProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderPage' + post: + operationId: createBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBillingProvider' + responses: + '201': + description: Billing provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' /v1/control/applications/{application_id}/billing/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free provider connection } } } - patch: { operationId: updateBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Provider credentials or metadata updated } } } - delete: { operationId: disableBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Provider disabled }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free provider connection + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' + patch: + operationId: updateBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProvider' + responses: + '204': + description: Provider credentials or metadata updated + delete: + operationId: disableBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Provider disabled + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/billing/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Provider credentials verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Provider credentials verified /v1/applications/{application_id}/billing/checkout-sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createCheckoutSession, tags: [Billing], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateCheckout" } } } }, responses: { "201": { description: Provider checkout created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createCheckoutSession + tags: + - Billing + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateCheckout' + responses: + '201': + description: Provider checkout created + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutSession' /v1/applications/{application_id}/billing/checkout-sessions/{session_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SessionID" }] - get: { operationId: getCheckoutSession, tags: [Billing], responses: { "200": { description: Checkout status and redirect URI } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SessionID' + get: + operationId: getCheckoutSession + tags: + - Billing + responses: + '200': + description: Checkout status and redirect URI + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutSession' /v1/applications/{application_id}/billing/portal-sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createBillingPortalSession, tags: [Billing], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Customer portal session created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createBillingPortalSession + tags: + - Billing + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePortalSession' + responses: + '201': + description: Customer portal session created + content: + application/json: + schema: + $ref: '#/components/schemas/PortalSession' /v1/control/applications/{application_id}/billing/subscriptions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listSubscriptions, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listSubscriptions + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listSubscriptions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SubscriptionPage' /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }] - get: { operationId: getSubscription, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Subscription details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + get: + operationId: getSubscription + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Subscription details + content: + application/json: + schema: + $ref: '#/components/schemas/Subscription' /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/cancel: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: cancelSubscription, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Subscription cancellation scheduled or applied } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: cancelSubscription + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CancelSubscription' + responses: + '204': + description: Subscription cancellation scheduled or applied /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/resume: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: resumeSubscription, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Scheduled cancellation removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: resumeSubscription + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Scheduled cancellation removed /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/change-price: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: changeSubscriptionPrice, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [price_id], properties: { price_id: { $ref: "#/components/schemas/UUID" }, proration_behavior: { enum: [create_prorations, always_invoice, none], default: create_prorations } } } } } }, responses: { "200": { description: Subscription price changed and synchronized } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: changeSubscriptionPrice + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ChangeSubscriptionPrice' + responses: + '200': + description: Subscription price changed and synchronized + content: + application/json: + schema: + $ref: '#/components/schemas/Subscription' /v1/control/applications/{application_id}/billing/invoices: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listInvoices, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listInvoices + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInvoices response. + content: + application/json: + schema: + $ref: '#/components/schemas/InvoicePage' /v1/control/applications/{application_id}/billing/invoices/{invoice_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: invoice_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getInvoice, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized invoice details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invoice_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getInvoice + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized invoice details + content: + application/json: + schema: + $ref: '#/components/schemas/Invoice' /v1/control/applications/{application_id}/billing/payments: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listPayments, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listPayments + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listPayments response. + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentPage' /v1/control/applications/{application_id}/billing/payments/{payment_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/PaymentID" }] - get: { operationId: getPayment, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized payment details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PaymentID' + get: + operationId: getPayment + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized payment details + content: + application/json: + schema: + $ref: '#/components/schemas/Payment' /v1/control/applications/{application_id}/billing/payments/{payment_id}/refunds: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/PaymentID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: createRefund, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Full or partial refund created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PaymentID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: createRefund + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateRefund' + responses: + '201': + description: Full or partial refund created + content: + application/json: + schema: + $ref: '#/components/schemas/Refund' /v1/control/applications/{application_id}/billing/refunds: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listRefunds, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listRefunds + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listRefunds response. + content: + application/json: + schema: + $ref: '#/components/schemas/RefundPage' /v1/control/applications/{application_id}/billing/refunds/{refund_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: refund_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getRefund, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized refund details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: refund_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getRefund + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized refund details + content: + application/json: + schema: + $ref: '#/components/schemas/Refund' /v1/control/applications/{application_id}/billing/disputes: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listDisputes, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listDisputes + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listDisputes response. + content: + application/json: + schema: + $ref: '#/components/schemas/DisputePage' /v1/control/applications/{application_id}/billing/disputes/{dispute_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: dispute_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getDispute, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized dispute details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: dispute_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getDispute + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized dispute details + content: + application/json: + schema: + $ref: '#/components/schemas/Dispute' /v1/control/applications/{application_id}/billing/statistics: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: from, in: query, schema: { type: string, format: date-time } }, { name: to, in: query, schema: { type: string, format: date-time } }] - get: { operationId: getBillingStatistics, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Bounded revenue, refund, and lifecycle statistics" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: from + in: query + schema: + type: string + format: date-time + - name: to + in: query + schema: + type: string + format: date-time + get: + operationId: getBillingStatistics + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Bounded revenue, refund, and lifecycle statistics + content: + application/json: + schema: + $ref: '#/components/schemas/BillingStatistics' /v1/control/applications/{application_id}/billing/provider-events: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listBillingProviderEvents, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listBillingProviderEvents + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listBillingProviderEvents response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderEventPage' /v1/control/applications/{application_id}/billing/provider-events/{event_id}/replay: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: event_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: replayBillingProviderEvent, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Stored provider event replayed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: event_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: replayBillingProviderEvent + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Stored provider event replayed /v1/control/applications/{application_id}/billing/providers/{provider_id}/reconciliation-runs: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: createBillingReconciliationRun, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "202": { description: Reconciliation queued transactionally } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: createBillingReconciliationRun + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '202': + description: Reconciliation queued transactionally + content: + application/json: + schema: + $ref: '#/components/schemas/ReconciliationAccepted' /v1/control/applications/{application_id}/billing/reconciliation-runs: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listBillingReconciliationRuns, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listBillingReconciliationRuns + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listBillingReconciliationRuns response. + content: + application/json: + schema: + $ref: '#/components/schemas/ReconciliationRunPage' /v1/control/applications/{application_id}/billing/reconciliation-runs/{run_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: run_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getBillingReconciliationRun, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Reconciliation findings, repairs, and status" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: run_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getBillingReconciliationRun + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Reconciliation findings, repairs, and status + content: + application/json: + schema: + $ref: '#/components/schemas/ReconciliationRun' /v1/applications/{application_id}/me/billing: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getMyBillingSummary, tags: [Billing], responses: { "200": { description: Current billing resource counts } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getMyBillingSummary + tags: + - Billing + responses: + '200': + description: Current billing resource counts + content: + application/json: + schema: + $ref: '#/components/schemas/BillingSummary' /v1/applications/{application_id}/me/subscriptions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMySubscriptions, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMySubscriptions + tags: + - Billing + responses: + '200': + description: Successful listMySubscriptions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SubscriptionPage' /v1/applications/{application_id}/me/invoices: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyInvoices, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyInvoices + tags: + - Billing + responses: + '200': + description: Successful listMyInvoices response. + content: + application/json: + schema: + $ref: '#/components/schemas/InvoicePage' /v1/applications/{application_id}/me/payments: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyPayments, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyPayments + tags: + - Billing + responses: + '200': + description: Successful listMyPayments response. + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentPage' /v1/applications/{application_id}/me/sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMySessions, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMySessions + tags: + - Identity + responses: + '200': + description: Successful listMySessions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SessionPage' /v1/applications/{application_id}/me/email-verification/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailVerificationStart, tags: [Identity], responses: { "202": { description: Verification challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailVerificationStart + tags: + - Identity + responses: + '202': + description: Verification challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/me/email-verification/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailVerificationVerify, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Email verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailVerificationVerify + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccountChallenge' + responses: + '204': + description: Email verified /v1/applications/{application_id}/me/email-change/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailChangeStart, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Email change challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailChangeStart + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailAddress' + responses: + '202': + description: Email change challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/me/email-change/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailChangeVerify, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Email changed and other sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailChangeVerify + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccountChallenge' + responses: + '204': + description: Email changed and other sessions revoked /v1/applications/{application_id}/me/password/change: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordChange, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Password changed and other sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordChange + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordChange' + responses: + '204': + description: Password changed and other sessions revoked /v1/applications/{application_id}/me/export: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: exportMyAccount, tags: [Identity], responses: { "200": { description: Portable account export } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: exportMyAccount + tags: + - Identity + responses: + '200': + description: Portable account export + content: + application/json: + schema: + $ref: '#/components/schemas/AccountExport' /v1/applications/{application_id}/me/anonymize: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: anonymizeMyAccount, tags: [Identity], responses: { "204": { description: Personal account data anonymized and credentials revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: anonymizeMyAccount + tags: + - Identity + responses: + '204': + description: Personal account data anonymized and credentials revoked /v1/applications/{application_id}/me/mfa/methods: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyMFAMethods, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyMFAMethods + tags: + - Identity + responses: + '200': + description: Successful listMyMFAMethods response. + content: + application/json: + schema: + $ref: '#/components/schemas/MFAMethodPage' /v1/applications/{application_id}/me/mfa/totp: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startTOTPEnrollment, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: One-time TOTP secret and provisioning URI } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startTOTPEnrollment + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/StartTOTP' + responses: + '201': + description: One-time TOTP secret and provisioning URI + content: + application/json: + schema: + $ref: '#/components/schemas/MFAEnrollment' /v1/applications/{application_id}/me/mfa/totp/{method_id}/activate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: method_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: activateTOTPEnrollment, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: TOTP activated and recovery codes returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: method_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: activateTOTPEnrollment + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ActivateTOTP' + responses: + '200': + description: TOTP activated and recovery codes returned once + content: + application/json: + schema: + $ref: '#/components/schemas/MFAActivation' /v1/applications/{application_id}/me/mfa/webauthn/options: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: beginWebAuthnRegistration, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: WebAuthn credential creation options and opaque ceremony identifier } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: beginWebAuthnRegistration + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BeginWebAuthnRegistration' + responses: + '201': + description: WebAuthn credential creation options and opaque ceremony identifier + content: + application/json: + schema: + $ref: '#/components/schemas/WebAuthnChallenge' /v1/applications/{application_id}/me/mfa/webauthn/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: finishWebAuthnRegistration, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: WebAuthn credential activated and recovery codes returned once when created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: finishWebAuthnRegistration + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FinishWebAuthnCeremony' + responses: + '200': + description: WebAuthn credential activated and recovery codes returned once when created + content: + application/json: + schema: + $ref: '#/components/schemas/MFAActivation' /v1/applications/{application_id}/me/mfa/methods/{method_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: method_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: disableMFAMethod, tags: [Identity], responses: { "204": { description: MFA method disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: method_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: disableMFAMethod + tags: + - Identity + responses: + '204': + description: MFA method disabled /v1/applications/{application_id}/me/mfa/recovery-codes/regenerate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: regenerateRecoveryCodes, tags: [Identity], responses: { "200": { description: Replacement recovery codes returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: regenerateRecoveryCodes + tags: + - Identity + responses: + '200': + description: Replacement recovery codes returned once + content: + application/json: + schema: + $ref: '#/components/schemas/RecoveryCodes' /v1/applications/{application_id}/me/auth/providers/google/link: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startGoogleLink, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Authenticated Google account-link authorization URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startGoogleLink + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Authenticated Google account-link authorization URL + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' /v1/applications/{application_id}/me/auth/providers/apple/link: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startAppleLink, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Authenticated Apple account-link authorization URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startAppleLink + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Authenticated Apple account-link authorization URL + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' /v1/applications/{application_id}/me/auth/identities: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyIdentities, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyIdentities + tags: + - Identity + responses: + '200': + description: Successful listMyIdentities response. + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalIdentityPage' /v1/applications/{application_id}/me/auth/identities/{identity_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: identity_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: unlinkMyIdentity, tags: [Identity], responses: { "204": { description: Linked identity removed while preserving a usable login method } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: identity_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: unlinkMyIdentity + tags: + - Identity + responses: + '204': + description: Linked identity removed while preserving a usable login method /v1/applications/{application_id}/me/sessions/{session_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: session_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeMySession, tags: [Identity], responses: { "204": { description: Session revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: session_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeMySession + tags: + - Identity + responses: + '204': + description: Session revoked /v1/applications/{application_id}/me/logout-all: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: logoutAll, tags: [Identity], responses: { "204": { description: All user sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: logoutAll + tags: + - Identity + responses: + '204': + description: All user sessions revoked /v1/applications/{application_id}/me/api-keys/{key_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: key_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokePersonalAPIKey, tags: [Identity], responses: { "204": { description: Personal API key revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: key_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokePersonalAPIKey + tags: + - Identity + responses: + '204': + description: Personal API key revoked /v1/applications/{application_id}/me/addresses: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyAddresses, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createMyAddress, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Address created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyAddresses + tags: + - Identity + responses: + '200': + description: Successful listMyAddresses response. + content: + application/json: + schema: + $ref: '#/components/schemas/AddressPage' + post: + operationId: createMyAddress + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAddress' + responses: + '201': + description: Address created + content: + application/json: + schema: + $ref: '#/components/schemas/Address' /v1/applications/{application_id}/me/addresses/{address_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateMyAddress, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Address updated with optimistic concurrency } } } - delete: { operationId: deleteMyAddress, tags: [Identity], responses: { "204": { description: Inactive address deleted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateMyAddress + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAddress' + responses: + '204': + description: Address updated with optimistic concurrency + delete: + operationId: deleteMyAddress + tags: + - Identity + responses: + '204': + description: Inactive address deleted /v1/applications/{application_id}/me/addresses/{address_id}/activate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: activateMyAddress, tags: [Identity], responses: { "204": { description: Address atomically selected as active } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: activateMyAddress + tags: + - Identity + responses: + '204': + description: Address atomically selected as active /v1/applications/{application_id}/me/billing-profile: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getMyBillingProfile, tags: [Billing], responses: { "200": { description: Current user billing profile } } } - patch: { operationId: updateMyBillingProfile, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Current user billing profile updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getMyBillingProfile + tags: + - Billing + responses: + '200': + description: Current user billing profile + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProfile' + patch: + operationId: updateMyBillingProfile + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProfile' + responses: + '204': + description: Current user billing profile updated /v1/applications/{application_id}/me/workspaces: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyWorkspaces, tags: [Control], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createMyWorkspace, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace created with the current user as owner } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyWorkspaces + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaces response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspacePage' + post: + operationId: createMyWorkspace + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkspace' + responses: + '201': + description: Workspace created with the current user as owner + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' /v1/applications/{application_id}/workspaces/{workspace_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getMyWorkspace, tags: [Control], responses: { "200": { description: Accessible workspace details } } } - patch: { operationId: updateMyWorkspace, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace updated } } } - delete: { operationId: archiveMyWorkspace, tags: [Control], responses: { "204": { description: Owned workspace archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getMyWorkspace + tags: + - Control + responses: + '200': + description: Accessible workspace details + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' + patch: + operationId: updateMyWorkspace + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateWorkspace' + responses: + '204': + description: Workspace updated + delete: + operationId: archiveMyWorkspace + tags: + - Control + responses: + '204': + description: Owned workspace archived /v1/applications/{application_id}/workspaces/{workspace_id}/members: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listMyWorkspaceMembers, tags: [Control], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listMyWorkspaceMembers + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaceMembers response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMemberPage' /v1/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - put: { operationId: replaceMyWorkspaceMemberRoles, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Workspace member roles replaced } } } - delete: { operationId: removeMyWorkspaceMember, tags: [Control], responses: { "204": { description: Workspace member removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + put: + operationId: replaceMyWorkspaceMemberRoles + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ReplaceWorkspaceMemberRoles' + responses: + '200': + description: Workspace member roles replaced + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMember' + delete: + operationId: removeMyWorkspaceMember + tags: + - Control + responses: + '204': + description: Workspace member removed /v1/applications/{application_id}/workspaces/{workspace_id}/owner-transfer: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: transferMyWorkspaceOwnership, tags: [Control], requestBody: { $ref: "#/components/requestBodies/OwnershipTransfer" }, responses: { "200": { $ref: "#/components/responses/OwnershipTransferResult" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: transferMyWorkspaceOwnership + tags: + - Control + requestBody: + $ref: '#/components/requestBodies/OwnershipTransfer' + responses: + '200': + $ref: '#/components/responses/OwnershipTransferResult' /v1/applications/{application_id}/workspaces/{workspace_id}/membership: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: leaveWorkspace, tags: [Control], responses: { "204": { description: Current membership removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: leaveWorkspace + tags: + - Control + responses: + '204': + description: Current membership removed /v1/applications/{application_id}/workspaces/{workspace_id}/invitations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: createMyWorkspaceInvitation, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace invitation created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listMyWorkspaceInvitations + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaceInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' + post: + operationId: createMyWorkspaceInvitation + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateInvitation' + responses: + '201': + description: Workspace invitation created and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeMyWorkspaceInvitation + tags: + - Control + responses: + '204': + description: Pending workspace invitation revoked + /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendMyWorkspaceInvitation + tags: + - Control + responses: + '202': + description: Workspace invitation credentials rotated and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationResent' + '429': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/workspaces/{workspace_id}/access: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listMyWorkspaceAccess + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaceAccess response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceAccessPage' + /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/OptionalPermissionSubjectType' + - $ref: '#/components/parameters/OptionalPermissionSubjectID' + - $ref: '#/components/parameters/PermissionGrantStatus' + get: + operationId: listWorkspacePermissionGrants + tags: + - Control + responses: + '200': + description: Successful listWorkspacePermissionGrants response. + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrantPage' + '403': + $ref: '#/components/responses/Problem' + post: + operationId: createWorkspacePermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/PermissionGrantBody' + responses: + '201': + description: Workspace direct permission grant created + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - name: grant_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWorkspacePermissionGrant + tags: + - Control + responses: + '200': + description: Workspace direct permission grant + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + delete: + operationId: revokeWorkspacePermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/IfMatch' + responses: + '204': + description: Workspace direct permission grant revoked + '409': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/workspaces/{workspace_id}/billing-profile: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWorkspaceBillingProfile, tags: [Billing], responses: { "200": { description: Workspace billing profile } } } - patch: { operationId: updateWorkspaceBillingProfile, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace billing profile updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWorkspaceBillingProfile + tags: + - Billing + responses: + '200': + description: Workspace billing profile + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProfile' + patch: + operationId: updateWorkspaceBillingProfile + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProfile' + responses: + '204': + description: Workspace billing profile updated /v1/applications/{application_id}/workspaces/{workspace_id}/addresses: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listWorkspaceAddresses, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWorkspaceAddress, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace billing address created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listWorkspaceAddresses + tags: + - Billing + responses: + '200': + description: Successful listWorkspaceAddresses response. + content: + application/json: + schema: + $ref: '#/components/schemas/AddressPage' + post: + operationId: createWorkspaceAddress + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAddress' + responses: + '201': + description: Workspace billing address created + content: + application/json: + schema: + $ref: '#/components/schemas/Address' /v1/applications/{application_id}/workspaces/{workspace_id}/addresses/{address_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateWorkspaceAddress, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace billing address updated } } } - delete: { operationId: deleteWorkspaceAddress, tags: [Billing], responses: { "204": { description: Inactive workspace billing address deleted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateWorkspaceAddress + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAddress' + responses: + '204': + description: Workspace billing address updated + delete: + operationId: deleteWorkspaceAddress + tags: + - Billing + responses: + '204': + description: Inactive workspace billing address deleted /v1/applications/{application_id}/workspaces/{workspace_id}/addresses/{address_id}/activate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: activateWorkspaceAddress, tags: [Billing], responses: { "204": { description: Workspace billing address selected as active } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: activateWorkspaceAddress + tags: + - Billing + responses: + '204': + description: Workspace billing address selected as active /v1/applications/{application_id}/me/workspace-invitations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyWorkspaceInvitations, tags: [Control], responses: { "200": { $ref: "#/components/responses/Page" } } } - /v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: acceptMyWorkspaceInvitation, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Workspace invitation accepted atomically } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyPendingInvitations + tags: + - Control + responses: + '200': + description: Successful listMyPendingInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' /v1/applications/{application_id}/me/permissions/check: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: checkMyPermissions, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Permission decisions with role explanations } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: checkMyPermissions + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionCheck' + responses: + '200': + description: Permission decisions with role explanations + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionCheckResult' /v1/applications/{application_id}/me/oauth-consents: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyOAuthConsents, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyOAuthConsents + tags: + - Identity + responses: + '200': + description: Successful listMyOAuthConsents response. + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthConsentPage' /v1/applications/{application_id}/me/oauth-consents/{client_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeMyOAuthConsent, tags: [Identity], responses: { "204": { description: Own consent and active grants revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeMyOAuthConsent + tags: + - Identity + responses: + '204': + description: Own consent and active grants revoked /v1/applications/{application_id}/events: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: publishCustomEvent, tags: [Events], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PublishCustomEvent" } } } }, responses: { "202": { description: Custom event and transactional outbox record accepted, content: { application/json: { schema: { $ref: "#/components/schemas/EventEnvelope" } } } }, "403": { $ref: "#/components/responses/Problem" }, "422": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: publishCustomEvent + tags: + - Events + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PublishCustomEvent' + responses: + '202': + description: Custom event and transactional outbox record accepted + content: + application/json: + schema: + $ref: '#/components/schemas/EventEnvelope' + '403': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/events: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listEvents, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listEvents + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listEvents response. + content: + application/json: + schema: + $ref: '#/components/schemas/EventPage' /v1/control/applications/{application_id}/events/{event_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: event_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getEvent, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: CloudEvents-compatible event detail, content: { application/json: { schema: { $ref: "#/components/schemas/EventEnvelope" } } } } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: event_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getEvent + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: CloudEvents-compatible event detail + content: + application/json: + schema: + $ref: '#/components/schemas/EventEnvelope' /v1/control/applications/{application_id}/event-types: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listEventTypes, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateEventType" } } } }, responses: { "201": { description: Application event type registered }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listEventTypes + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listEventTypes response. + content: + application/json: + schema: + $ref: '#/components/schemas/EventTypePage' + post: + operationId: createEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEventType' + responses: + '201': + description: Application event type registered + content: + application/json: + schema: + $ref: '#/components/schemas/EventTypeDefinition' + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/event-types/{event_type_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: event_type_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Versioned event contract with a complete webhook example, content: { application/json: { schema: { $ref: "#/components/schemas/EventTypeDefinition" } } } } } } - patch: { operationId: updateEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateEventType" } } } }, responses: { "204": { description: Event type definition updated }, "409": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: archiveEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application event type archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: event_type_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Versioned event contract with a complete webhook example + content: + application/json: + schema: + $ref: '#/components/schemas/EventTypeDefinition' + patch: + operationId: updateEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateEventType' + responses: + '204': + description: Event type definition updated + '409': + $ref: '#/components/responses/Problem' + delete: + operationId: archiveEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application event type archived /v1/control/applications/{application_id}/audit-logs: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listAuditLogs, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listAuditLogs + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listAuditLogs response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuditRecordPage' /v1/control/applications/{application_id}/audit-logs/{audit_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: audit_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getAuditLog, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Audit record detail } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: audit_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getAuditLog + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Audit record detail + content: + application/json: + schema: + $ref: '#/components/schemas/AuditRecord' /v1/control/applications/{application_id}/audit-exports: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createAuditExport, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Encrypted one-hour audit export created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createAuditExport + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditExport' + responses: + '201': + description: Encrypted one-hour audit export created + content: + application/json: + schema: + $ref: '#/components/schemas/AuditExportRecord' /v1/control/applications/{application_id}/audit-exports/{export_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: export_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getAuditExport, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Decrypted audit export before expiry } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: export_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getAuditExport + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Decrypted audit export before expiry + content: + application/json: + schema: + $ref: '#/components/schemas/AuditExportRecord' /v1/control/applications/{application_id}/webhooks: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWebhooks, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Webhook created and secret returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listWebhooks + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWebhooks response. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookPage' + post: + operationId: createWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWebhook' + responses: + '201': + description: Webhook created and secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/Webhook' /v1/control/applications/{application_id}/webhooks/{webhook_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: webhook_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Webhook endpoint and delivery statistics }, "404": { $ref: "#/components/responses/Problem" } } } - patch: { operationId: updateWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Webhook endpoint updated }, "409": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Webhook disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: webhook_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Webhook endpoint and delivery statistics + content: + application/json: + schema: + $ref: '#/components/schemas/Webhook' + '404': + $ref: '#/components/responses/Problem' + patch: + operationId: updateWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateWebhook' + responses: + '204': + description: Webhook endpoint updated + '409': + $ref: '#/components/responses/Problem' + delete: + operationId: disableWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Webhook disabled /v1/control/applications/{application_id}/webhooks/{webhook_id}/test: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: webhook_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "202": { description: Targeted signed test delivery queued }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: webhook_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '202': + description: Targeted signed test delivery queued + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookTestAccepted' + '404': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/webhooks/{webhook_id}/rotate-secret: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: webhook_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: rotateWebhookSecret, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Webhook secret rotated and returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: webhook_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: rotateWebhookSecret + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Webhook secret rotated and returned once + content: + application/json: + schema: + $ref: '#/components/schemas/SecretCredential' /v1/control/applications/{application_id}/webhook-deliveries: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWebhookDeliveries, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listWebhookDeliveries + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWebhookDeliveries response. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookDeliveryPage' /v1/control/applications/{application_id}/webhook-deliveries/{delivery_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delivery_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWebhookDelivery, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Webhook delivery history detail }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delivery_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWebhookDelivery + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Webhook delivery history detail + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookDelivery' + '404': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/webhook-deliveries/{delivery_id}/replay: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delivery_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: replayWebhookDelivery, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Delivery queued for replay } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delivery_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: replayWebhookDelivery + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Delivery queued for replay /v1/control/applications/{application_id}/notification-providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotificationProviders, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: SMTP provider stored } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotificationProviders + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listNotificationProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProviderPage' + post: + operationId: createNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/applications/{application_id}/notification-providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Redacted provider configuration and health } } } - patch: { operationId: updateNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Redacted updated provider configuration } } } - delete: { operationId: disableNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Notification provider disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Redacted provider configuration and health + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + patch: + operationId: updateNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateSMTPProvider' + responses: + '200': + description: Redacted updated provider configuration + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + delete: + operationId: disableNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Notification provider disabled /v1/control/applications/{application_id}/notification-providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: SMTP connectivity and authentication verified }, "502": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: SMTP connectivity and authentication verified + '502': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/notification-providers/{provider_id}/test: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Provider-specific test notification queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TestNotificationProvider' + responses: + '202': + description: Provider-specific test notification queued + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationQueued' /v1/control/applications/{application_id}/sender-identities: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listSenderIdentities, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createSenderIdentity, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Sender identity created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listSenderIdentities + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listSenderIdentities response. + content: + application/json: + schema: + $ref: '#/components/schemas/SenderIdentityPage' + post: + operationId: createSenderIdentity + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateSenderIdentity' + responses: + '201': + description: Sender identity created + content: + application/json: + schema: + $ref: '#/components/schemas/SenderIdentity' /v1/control/applications/{application_id}/sender-identities/{sender_id}/default: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: sender_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: setDefaultSenderIdentity, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Default sender selected } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: sender_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: setDefaultSenderIdentity + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Default sender selected /v1/control/installation/notification-templates: - get: { operationId: listInstallationNotificationTemplates, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Installation template draft created } } } + get: + operationId: listInstallationNotificationTemplates + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationNotificationTemplates response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePage' + post: + operationId: createInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateNotificationTemplate' + responses: + '201': + description: Installation template draft created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/installation/notification-template-variables: - get: { operationId: listInstallationNotificationTemplateVariables, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation template variables and samples } } } + get: + operationId: listInstallationNotificationTemplateVariables + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation template variables and samples + content: + application/json: + schema: + $ref: '#/components/schemas/TemplateVariables' /v1/control/installation/notification-templates/{template_id}: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation template and immutable history } } } - patch: { operationId: updateInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: New installation template draft version created } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation template and immutable history + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' + patch: + operationId: updateInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNotificationTemplate' + responses: + '201': + description: New installation template draft version created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/installation/notification-templates/{template_id}/preview: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: previewInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Safely rendered installation template preview } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: previewInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PreviewNotificationTemplate' + responses: + '200': + description: Safely rendered installation template preview + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePreview' /v1/control/installation/notification-templates/{template_id}/publish: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: publishInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation template published } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: publishInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation template published /v1/control/installation/notification-templates/{template_id}/archive: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: archiveInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation template archived } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: archiveInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation template archived /v1/control/applications/{application_id}/notification-templates: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotificationTemplates, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Immutable draft template version created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotificationTemplates + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listNotificationTemplates response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePage' + post: + operationId: createNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateNotificationTemplate' + responses: + '201': + description: Immutable draft template version created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/applications/{application_id}/notification-template-variables: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotificationTemplateVariables, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Built-in notification template variables and sample values } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotificationTemplateVariables + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Built-in notification template variables and sample values + content: + application/json: + schema: + $ref: '#/components/schemas/TemplateVariables' /v1/control/applications/{application_id}/notification-templates/{template_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Template version and immutable version history } } } - patch: { operationId: updateNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: New immutable draft version created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Template version and immutable version history + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' + patch: + operationId: updateNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNotificationTemplate' + responses: + '201': + description: New immutable draft version created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/applications/{application_id}/notification-templates/{template_id}/preview: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: previewNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Safely rendered preview without delivery } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: previewNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PreviewNotificationTemplate' + responses: + '200': + description: Safely rendered preview without delivery + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePreview' /v1/control/applications/{application_id}/notification-templates/{template_id}/publish: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: publishNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Template version published and predecessor archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: publishNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Template version published and predecessor archived /v1/control/applications/{application_id}/notification-templates/{template_id}/archive: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: archiveNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Template version archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: archiveNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Template version archived /v1/control/applications/{application_id}/notifications: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotifications, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: queueNotification, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/QueueNotification" } } } }, responses: { "202": { description: Rendered locale-aware template snapshot queued or suppressed by preference, content: { application/json: { schema: { $ref: "#/components/schemas/QueuedNotification" } } } } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotifications + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listNotifications response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationPage' /v1/control/applications/{application_id}/notifications/statistics: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getNotificationStatistics, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Notification and attempt status totals } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getNotificationStatistics + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Notification and attempt status totals + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationStatistics' /v1/control/applications/{application_id}/notifications/{notification_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: notification_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getNotification, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Notification metadata, attachment metadata, and attempts without encrypted payload" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: notification_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getNotification + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Notification metadata, attachment metadata, and attempts without encrypted payload + content: + application/json: + schema: + $ref: '#/components/schemas/Notification' /v1/control/applications/{application_id}/notifications/{notification_id}/retry: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: notification_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: retryNotification, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Notification queued for retry } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: notification_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: retryNotification + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Notification queued for retry /v1/applications/{application_id}/me/notification-preferences: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyNotificationPreferences, tags: [Events], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyNotificationPreferences + tags: + - Events + responses: + '200': + description: Successful listMyNotificationPreferences response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationPreferencePage' /v1/applications/{application_id}/me/notification-preferences/{category}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: category, in: path, required: true, schema: { enum: [transactional, billing, product, marketing] } }] - put: { operationId: updateMyNotificationPreference, tags: [Events], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Email preference updated; security remains mandatory } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: category + in: path + required: true + schema: + enum: + - transactional + - billing + - product + - marketing + put: + operationId: updateMyNotificationPreference + tags: + - Events + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNotificationPreference' + responses: + '204': + description: Email preference updated; security remains mandatory /v1/control/installation/storage/providers: - get: { operationId: listInstallationStorageProviders, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/StorageProvider" }, responses: { "201": { description: Storage provider stored without exposing credentials } } } + get: + operationId: listInstallationStorageProviders + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationStorageProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderPage' + post: + operationId: createInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/StorageProviderBody' + responses: + '201': + description: Storage provider stored without exposing credentials + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' /v1/control/installation/storage/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free storage provider } } } - patch: { operationId: updateInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Storage provider updated and marked unverified } } } - delete: { operationId: disableInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ConfirmAffectedObjects" }], responses: { "204": { description: Provider disabled in Platform93 }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free storage provider + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + patch: + operationId: updateInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateStorageProvider' + responses: + '200': + description: Storage provider updated and marked unverified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + delete: + operationId: disableInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ConfirmAffectedObjects' + responses: + '204': + description: Provider disabled in Platform93 + '409': + $ref: '#/components/responses/Problem' /v1/control/installation/storage/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Credentials and bucket visibility verified }, "502": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Credentials and bucket visibility verified + '502': + $ref: '#/components/responses/Problem' /v1/control/installation/storage/providers/{provider_id}/enable: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - post: { operationId: enableInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Provider re-enabled } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + post: + operationId: enableInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Provider re-enabled + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderStatus' /v1/control/organizations/{organization_id}/storage/providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationStorageProviders, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/StorageProvider" }, responses: { "201": { description: Organization storage override stored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationStorageProviders + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationStorageProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderPage' + post: + operationId: createOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/StorageProviderBody' + responses: + '201': + description: Organization storage override stored + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' /v1/control/organizations/{organization_id}/storage/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free storage provider } } } - patch: { operationId: updateOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Storage provider updated and marked unverified } } } - delete: { operationId: disableOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ConfirmAffectedObjects" }], responses: { "204": { description: Provider disabled in Platform93 }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free storage provider + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + patch: + operationId: updateOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateStorageProvider' + responses: + '200': + description: Storage provider updated and marked unverified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + delete: + operationId: disableOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ConfirmAffectedObjects' + responses: + '204': + description: Provider disabled in Platform93 + '409': + $ref: '#/components/responses/Problem' /v1/control/organizations/{organization_id}/storage/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Credentials and bucket visibility verified } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Credentials and bucket visibility verified /v1/control/organizations/{organization_id}/storage/providers/{provider_id}/enable: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: enableOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Provider re-enabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: enableOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Provider re-enabled + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderStatus' /v1/control/applications/{application_id}/storage/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationStorageProviders, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/StorageProvider" }, responses: { "201": { description: Application storage override stored } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationStorageProviders + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationStorageProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderPage' + post: + operationId: createApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/StorageProviderBody' + responses: + '201': + description: Application storage override stored + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' /v1/control/applications/{application_id}/storage/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free storage provider } } } - patch: { operationId: updateApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Storage provider updated and marked unverified } } } - delete: { operationId: disableApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ConfirmAffectedObjects" }], responses: { "204": { description: Provider disabled in Platform93 }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free storage provider + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + patch: + operationId: updateApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateStorageProvider' + responses: + '200': + description: Storage provider updated and marked unverified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + delete: + operationId: disableApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ConfirmAffectedObjects' + responses: + '204': + description: Provider disabled in Platform93 + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/storage/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Credentials and bucket visibility verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Credentials and bucket visibility verified /v1/control/applications/{application_id}/storage/providers/{provider_id}/enable: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: enableApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Provider re-enabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: enableApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Provider re-enabled + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderStatus' /v1/control/installation/storage/uploads: - post: { operationId: createInstallationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned installation asset upload, content: { application/json: { schema: { $ref: "#/components/schemas/StorageUploadAuthorization" } } } } } } + post: + operationId: createInstallationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned installation asset upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/control/installation/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeInstallationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeInstallationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/control/installation/storage/objects: - get: { operationId: listInstallationStorageObjects, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listInstallationStorageObjects + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/control/installation/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getInstallationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation asset metadata } } } - delete: { operationId: deleteInstallationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ForceDelete" }], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getInstallationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation asset metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteInstallationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ForceDelete' + responses: + '204': + description: Deletion queued /v1/control/installation/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadInstallationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadInstallationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/control/organizations/{organization_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationStorageObjects, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationStorageObjects + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/control/organizations/{organization_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getOrganizationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Organization object metadata } } } - delete: { operationId: deleteOrganizationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ForceDelete" }], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getOrganizationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Organization object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteOrganizationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ForceDelete' + responses: + '204': + description: Deletion queued /v1/control/organizations/{organization_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadOrganizationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadOrganizationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/control/applications/{application_id}/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createControlApplicationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned application asset upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createControlApplicationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned application asset upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/control/applications/{application_id}/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeControlApplicationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeControlApplicationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/control/applications/{application_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listControlApplicationStorageObjects, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listControlApplicationStorageObjects + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listControlApplicationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/control/applications/{application_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getControlApplicationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Application object metadata } } } - delete: { operationId: deleteControlApplicationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ForceDelete" }], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getControlApplicationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Application object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteControlApplicationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ForceDelete' + responses: + '204': + description: Deletion queued /v1/control/applications/{application_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadControlApplicationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadControlApplicationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/applications/{application_id}/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createApplicationStorageUpload, tags: [Storage], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned application-owned upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createApplicationStorageUpload + tags: + - Storage + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned application-owned upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/applications/{application_id}/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeApplicationStorageUpload, tags: [Storage], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeApplicationStorageUpload + tags: + - Storage + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/applications/{application_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationStorageObjects, tags: [Storage], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationStorageObjects + tags: + - Storage + responses: + '200': + description: Successful listApplicationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/applications/{application_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getApplicationStorageObject, tags: [Storage], responses: { "200": { description: Application object metadata } } } - delete: { operationId: deleteApplicationStorageObject, tags: [Storage], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getApplicationStorageObject + tags: + - Storage + responses: + '200': + description: Application object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteApplicationStorageObject + tags: + - Storage + responses: + '204': + description: Deletion queued /v1/applications/{application_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadApplicationStorageObject, tags: [Storage], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadApplicationStorageObject + tags: + - Storage + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/applications/{application_id}/me/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createMyStorageUpload, tags: [Storage], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned user-owned upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createMyStorageUpload + tags: + - Storage + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned user-owned upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/applications/{application_id}/me/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeMyStorageUpload, tags: [Storage], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeMyStorageUpload + tags: + - Storage + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/applications/{application_id}/me/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyStorageObjects, tags: [Storage], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyStorageObjects + tags: + - Storage + responses: + '200': + description: Successful listMyStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/applications/{application_id}/me/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getMyStorageObject, tags: [Storage], responses: { "200": { description: User object metadata } } } - delete: { operationId: deleteMyStorageObject, tags: [Storage], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getMyStorageObject + tags: + - Storage + responses: + '200': + description: User object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteMyStorageObject + tags: + - Storage + responses: + '204': + description: Deletion queued /v1/applications/{application_id}/me/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadMyStorageObject, tags: [Storage], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadMyStorageObject + tags: + - Storage + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }] - post: { operationId: createWorkspaceStorageUpload, tags: [Storage], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned workspace-owned upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + post: + operationId: createWorkspaceStorageUpload + tags: + - Storage + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned workspace-owned upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeWorkspaceStorageUpload, tags: [Storage], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeWorkspaceStorageUpload + tags: + - Storage + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }] - get: { operationId: listWorkspaceStorageObjects, tags: [Storage], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + get: + operationId: listWorkspaceStorageObjects + tags: + - Storage + responses: + '200': + description: Successful listWorkspaceStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getWorkspaceStorageObject, tags: [Storage], responses: { "200": { description: Workspace object metadata } } } - delete: { operationId: deleteWorkspaceStorageObject, tags: [Storage], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getWorkspaceStorageObject + tags: + - Storage + responses: + '200': + description: Workspace object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteWorkspaceStorageObject + tags: + - Storage + responses: + '204': + description: Deletion queued /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadWorkspaceStorageObject, tags: [Storage], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadWorkspaceStorageObject + tags: + - Storage + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /oidc/.well-known/openid-configuration: - get: { operationId: oidcDiscovery, tags: [Identity], security: [], responses: { "200": { description: OpenID Provider metadata } } } + get: + operationId: oidcDiscovery + tags: + - Identity + security: [] + responses: + '200': + description: OpenID Provider metadata + content: + application/json: + schema: + $ref: '#/components/schemas/OIDCDiscovery' /oidc/jwks.json: - get: { operationId: oidcJWKS, tags: [Identity], security: [], responses: { "200": { description: Active and retiring JSON Web Keys } } } + get: + operationId: oidcJWKS + tags: + - Identity + security: [] + responses: + '200': + description: Active and retiring JSON Web Keys + content: + application/json: + schema: + $ref: '#/components/schemas/JWKS' /oidc/authorize: - get: { operationId: beginOIDCAuthorization, tags: [Identity], security: [], parameters: [{ $ref: "#/components/parameters/OAuthClientID" }, { $ref: "#/components/parameters/OAuthRedirectURI" }, { $ref: "#/components/parameters/OAuthResponseType" }, { $ref: "#/components/parameters/OAuthScope" }, { $ref: "#/components/parameters/OAuthState" }, { $ref: "#/components/parameters/OAuthCodeChallenge" }, { $ref: "#/components/parameters/OAuthCodeChallengeMethod" }], responses: { "200": { description: Headless consent interaction }, "302": { description: Authorization response redirect } } } - post: { operationId: decideOIDCAuthorization, tags: [Identity], security: [{ bearerAuth: [] }], requestBody: { $ref: "#/components/requestBodies/OAuthAuthorizationDecision" }, responses: { "200": { description: Headless authorization response containing redirect_to when JSON is requested }, "302": { description: Authorization response redirect } } } + get: + operationId: beginOIDCAuthorization + tags: + - Identity + security: [] + parameters: + - $ref: '#/components/parameters/OAuthClientID' + - $ref: '#/components/parameters/OAuthRedirectURI' + - $ref: '#/components/parameters/OAuthResponseType' + - $ref: '#/components/parameters/OAuthScope' + - $ref: '#/components/parameters/OAuthState' + - $ref: '#/components/parameters/OAuthCodeChallenge' + - $ref: '#/components/parameters/OAuthCodeChallengeMethod' + responses: + '200': + description: Headless consent interaction + content: + application/json: + schema: + $ref: '#/components/schemas/AuthorizationRedirect' + '302': + description: Authorization response redirect + post: + operationId: decideOIDCAuthorization + tags: + - Identity + security: + - bearerAuth: [] + requestBody: + $ref: '#/components/requestBodies/OAuthAuthorizationDecision' + responses: + '200': + description: Headless authorization response containing redirect_to when JSON is requested + content: + application/json: + schema: + $ref: '#/components/schemas/AuthorizationRedirect' + '302': + description: Authorization response redirect /oidc/token: - post: { operationId: exchangeOIDCToken, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/OAuthToken" }, responses: { "200": { description: OAuth token response }, "400": { description: OAuth error response } } } + post: + operationId: exchangeOIDCToken + tags: + - Identity + security: [] + requestBody: + $ref: '#/components/requestBodies/OAuthToken' + responses: + '200': + description: OAuth token response + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '400': + description: OAuth error response /oidc/revoke: - post: { operationId: revokeOIDCToken, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/OAuthTokenCredential" }, responses: { "200": { description: Token revoked or already inactive } } } + post: + operationId: revokeOIDCToken + tags: + - Identity + security: [] + requestBody: + $ref: '#/components/requestBodies/OAuthTokenCredential' + responses: + '200': + description: Token revoked or already inactive + content: + application/json: + schema: + $ref: '#/components/schemas/EmptyResponse' /oidc/introspect: - post: { operationId: introspectOIDCToken, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/OAuthTokenCredential" }, responses: { "200": { description: RFC 7662 token state } } } + post: + operationId: introspectOIDCToken + tags: + - Identity + security: [] + requestBody: + $ref: '#/components/requestBodies/OAuthTokenCredential' + responses: + '200': + description: RFC 7662 token state + content: + application/json: + schema: + $ref: '#/components/schemas/TokenIntrospection' /oidc/userinfo: - get: { operationId: oidcUserinfo, tags: [Identity], security: [{ bearerAuth: [] }], responses: { "200": { description: OpenID Connect claims }, "401": { $ref: "#/components/responses/Problem" } } } + get: + operationId: oidcUserinfo + tags: + - Identity + security: + - bearerAuth: [] + responses: + '200': + description: OpenID Connect claims + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + '401': + $ref: '#/components/responses/Problem' /provider-webhooks/stripe/{connection_public_id}: - post: { operationId: stripeWebhook, tags: [Billing], security: [], parameters: [{ name: connection_public_id, in: path, required: true, schema: { type: string } }, { name: Stripe-Signature, in: header, required: true, schema: { type: string } }], requestBody: { required: true, content: { application/json: { schema: {} } } }, responses: { "200": { description: Event stored and processed }, "400": { $ref: "#/components/responses/Problem" } } } + post: + operationId: stripeWebhook + tags: + - Billing + security: [] + parameters: + - name: connection_public_id + in: path + required: true + schema: + type: string + - name: Stripe-Signature + in: header + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: {} + responses: + '200': + description: Event stored and processed + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookAcknowledgement' + '400': + $ref: '#/components/responses/Problem' /v1/management/organizations: - get: { operationId: managementListOrganizations, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: managementCreateOrganization, tags: [Management], security: [{ managementBearer: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Organization provisioned without an operator membership } } } + get: + operationId: managementListOrganizations + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Successful managementListOrganizations response. + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPage' + post: + operationId: managementCreateOrganization + tags: + - Management + security: + - managementBearer: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Organization provisioned without a Platform user membership + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' /v1/management/organizations/{organization_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: managementGetOrganization, tags: [Management], security: [{ managementBearer: [] }], responses: { "200": { description: Organization details } } } - patch: { operationId: managementUpdateOrganization, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Organization renamed } } } - delete: { operationId: managementRetireOrganization, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Organization retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: managementGetOrganization + tags: + - Management + security: + - managementBearer: [] + responses: + '200': + description: Organization details + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' + patch: + operationId: managementUpdateOrganization + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Organization renamed + delete: + operationId: managementRetireOrganization + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Organization retired /v1/management/organizations/{organization_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - post: { operationId: managementRestoreOrganization, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Organization restored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + post: + operationId: managementRestoreOrganization + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Organization restored /v1/management/organizations/{organization_id}/policy: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: managementGetOrganizationPolicy, tags: [Management], security: [{ managementBearer: [] }], responses: { "200": { description: Organization policy and usage, content: { application/json: { schema: { $ref: "#/components/schemas/OrganizationPolicy" } } } } } } - put: { operationId: managementUpdateOrganizationPolicy, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateOrganizationPolicy" } } } }, responses: { "204": { description: Organization policy updated } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: managementGetOrganizationPolicy + tags: + - Management + security: + - managementBearer: [] + responses: + '200': + description: Organization policy and usage + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPolicy' + put: + operationId: managementUpdateOrganizationPolicy + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOrganizationPolicy' + responses: + '204': + description: Organization policy updated /v1/management/organizations/{organization_id}/applications: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: managementListApplications, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: managementCreateApplication, tags: [Management], security: [{ managementBearer: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Application provisioned }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: managementListApplications + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Successful managementListApplications response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationPage' + post: + operationId: managementCreateApplication + tags: + - Management + security: + - managementBearer: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Application provisioned + content: + application/json: + schema: + $ref: '#/components/schemas/Application' + '409': + $ref: '#/components/responses/Problem' /v1/management/organizations/{organization_id}/applications/{application_resource_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: managementUpdateApplication, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Application renamed } } } - delete: { operationId: managementRetireApplication, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Application retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: managementUpdateApplication + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Application renamed + delete: + operationId: managementRetireApplication + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Application retired /v1/management/organizations/{organization_id}/applications/{application_resource_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: managementRestoreApplication, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Application restored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: managementRestoreApplication + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Application restored components: securitySchemes: - bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT-or-PAT } - operatorBearer: { type: http, scheme: bearer, bearerFormat: JWT } - operatorCookie: { type: apiKey, in: cookie, name: p93_operator_access } - managementBearer: { type: http, scheme: bearer, bearerFormat: Platform93-management-JWT, description: "Short-lived client-credentials token with actor_type=management_client and audience platform93:control." } + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT-or-PAT + controlBearer: + type: http + scheme: bearer + bearerFormat: JWT + controlCookie: + type: apiKey + in: cookie + name: p93_control_access + managementBearer: + type: http + scheme: bearer + bearerFormat: Platform93-management-JWT + description: Short-lived client-credentials token with actor_type=management_client and audience platform93:control. parameters: - ApplicationID: { name: application_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - WorkspaceID: { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - ObjectID: { name: object_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - ConfirmAffectedObjects: { name: confirm_affected_objects, in: query, required: false, schema: { type: boolean, default: false }, description: Required when disabling a provider pinned by live objects. } - ForceDelete: { name: force, in: query, required: false, schema: { type: boolean, default: false }, description: Break managed email-template references; requires X-Audit-Reason. } - WorkspaceIDQuery: { name: workspace_id, in: query, required: false, description: Explicit accessible workspace whose grants are merged with the current user's grants., schema: { $ref: "#/components/schemas/UUID" } } - OrganizationID: { name: organization_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - IncludeRetired: { name: include_retired, in: query, schema: { type: boolean, default: false } } - IfMatch: { name: If-Match, in: header, required: true, schema: { type: string }, description: Current resource ETag. } - IdempotencyKey: { name: Idempotency-Key, in: header, required: false, schema: { type: string, minLength: 8, maxLength: 255 } } - RequiredIdempotencyKey: { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 8, maxLength: 255 } } - ProviderID: { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - SessionID: { name: session_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - SubscriptionID: { name: subscription_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - PaymentID: { name: payment_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - RequestID: { name: request_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - OAuthClientID: { name: client_id, in: query, required: true, schema: { type: string } } - OAuthRedirectURI: { name: redirect_uri, in: query, required: true, schema: { type: string, format: uri } } - OAuthResponseType: { name: response_type, in: query, required: true, schema: { type: string, enum: [code] } } - OAuthScope: { name: scope, in: query, required: true, schema: { type: string } } - OAuthState: { name: state, in: query, required: true, schema: { type: string, minLength: 8 } } - OAuthCodeChallenge: { name: code_challenge, in: query, required: true, schema: { type: string, minLength: 43, maxLength: 128 } } - OAuthCodeChallengeMethod: { name: code_challenge_method, in: query, required: true, schema: { type: string, enum: [S256] } } + ApplicationID: + name: application_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + WorkspaceID: + name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + ObjectID: + name: object_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + ConfirmAffectedObjects: + name: confirm_affected_objects + in: query + required: false + schema: + type: boolean + default: false + description: Required when disabling a provider pinned by live objects. + ForceDelete: + name: force + in: query + required: false + schema: + type: boolean + default: false + description: Break managed email-template references; requires X-Audit-Reason. + WorkspaceIDQuery: + name: workspace_id + in: query + required: false + description: Explicit accessible workspace whose grants are merged with the current user's grants. + schema: + $ref: '#/components/schemas/UUID' + PermissionSubjectType: + name: subject_type + in: query + required: true + schema: + type: string + enum: + - user + - client + PermissionSubjectID: + name: subject_id + in: query + required: true + schema: + $ref: '#/components/schemas/UUID' + OrganizationID: + name: organization_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + IncludeRetired: + name: include_retired + in: query + schema: + type: boolean + default: false + IfMatch: + name: If-Match + in: header + required: true + schema: + type: string + description: Current resource ETag. + IdempotencyKey: + name: Idempotency-Key + in: header + required: false + schema: + type: string + minLength: 8 + maxLength: 255 + RequiredIdempotencyKey: + name: Idempotency-Key + in: header + required: true + schema: + type: string + minLength: 8 + maxLength: 255 + ProviderID: + name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + SessionID: + name: session_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + SubscriptionID: + name: subscription_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + PaymentID: + name: payment_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + RequestID: + name: request_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + OAuthClientID: + name: client_id + in: query + required: true + schema: + type: string + OAuthRedirectURI: + name: redirect_uri + in: query + required: true + schema: + type: string + format: uri + OAuthResponseType: + name: response_type + in: query + required: true + schema: + type: string + enum: + - code + OAuthScope: + name: scope + in: query + required: true + schema: + type: string + OAuthState: + name: state + in: query + required: true + schema: + type: string + minLength: 8 + OAuthCodeChallenge: + name: code_challenge + in: query + required: true + schema: + type: string + minLength: 43 + maxLength: 128 + OAuthCodeChallengeMethod: + name: code_challenge_method + in: query + required: true + schema: + type: string + enum: + - S256 + OptionalPermissionSubjectType: + name: subject_type + in: query + required: false + schema: + type: string + enum: + - user + - client + OptionalPermissionSubjectID: + name: subject_id + in: query + required: false + schema: + $ref: '#/components/schemas/UUID' + PermissionGrantStatus: + name: status + in: query + required: false + schema: + type: string + enum: + - active + - revoked requestBodies: - Named: { required: true, content: { application/json: { schema: { type: object, required: [name, slug], properties: { name: { type: string }, slug: { type: string, pattern: "^[a-z][a-z0-9-]{1,62}[a-z0-9]$" } } } } } } - Rename: { required: true, content: { application/json: { schema: { type: object, required: [name], properties: { name: { type: string, minLength: 1, maxLength: 255 } }, additionalProperties: false } } } } - Object: { required: true, content: { application/json: { schema: { type: object } } } } - ProviderInheritance: { required: true, content: { application/json: { schema: { type: object, required: [inheritable], properties: { inheritable: { type: boolean, description: Allow child scopes to resolve this provider. } }, additionalProperties: false } } } } - ApplicationAuthConfig: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ApplicationAuthConfig" } } } } - PublicApplicationConfig: { required: true, content: { application/json: { schema: { type: object, additionalProperties: true, description: "This entire object is returned by the unauthenticated runtime-config endpoint. Secrets are forbidden." } } } } - InternalApplicationConfig: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ApplicationInternalConfig" } } } } - RoleAssignment: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/RoleAssignment" } } } } - OwnershipTransfer: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/OwnershipTransfer" } } } } - SMTPProvider: { required: true, content: { application/json: { schema: { type: object, required: [name, host, port, tls_mode, sender_email], properties: { name: { type: string }, host: { type: string }, port: { type: integer, minimum: 1, maximum: 65535 }, username: { type: string }, password: { type: string, writeOnly: true }, tls_mode: { enum: [starttls, implicit_tls] }, sender_email: { type: string, format: email }, sender_name: { type: string }, inheritable: { type: boolean, default: false } } } } } } - StorageProvider: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateStorageProvider" } } } } - StorageUpload: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateStorageUpload" } } } } - OAuthAuthorizationDecision: { required: true, content: { application/x-www-form-urlencoded: { schema: { type: object, required: [client_id, redirect_uri, response_type, scope, state, code_challenge, code_challenge_method, decision], properties: { client_id: { type: string }, redirect_uri: { type: string, format: uri }, response_type: { type: string, enum: [code] }, scope: { type: string }, state: { type: string }, nonce: { type: string }, code_challenge: { type: string }, code_challenge_method: { type: string, enum: [S256] }, decision: { enum: [grant, deny] } } } } } } - OAuthToken: { required: true, content: { application/x-www-form-urlencoded: { schema: { type: object, required: [grant_type], properties: { grant_type: { enum: [authorization_code, refresh_token, client_credentials] }, code: { type: string }, redirect_uri: { type: string, format: uri }, code_verifier: { type: string }, refresh_token: { type: string }, client_id: { type: string }, client_secret: { type: string, writeOnly: true }, scope: { type: string } } } } } } - OAuthTokenCredential: { required: true, content: { application/x-www-form-urlencoded: { schema: { type: object, required: [token], properties: { token: { type: string, writeOnly: true }, token_type_hint: { enum: [access_token, refresh_token] }, client_id: { type: string }, client_secret: { type: string, writeOnly: true } } } } } } + Named: + required: true + content: + application/json: + schema: + type: object + required: + - name + - slug + properties: + name: + type: string + slug: + type: string + pattern: ^[a-z][a-z0-9-]{1,62}[a-z0-9]$ + Rename: + required: true + content: + application/json: + schema: + type: object + required: + - name + properties: + name: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false + ProviderInheritance: + required: true + content: + application/json: + schema: + type: object + required: + - inheritable + properties: + inheritable: + type: boolean + description: Allow child scopes to resolve this provider. + additionalProperties: false + ApplicationAuthConfig: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationAuthConfig' + PublicApplicationConfig: + required: true + content: + application/json: + schema: + type: object + additionalProperties: true + description: This entire object is returned by the unauthenticated runtime-config endpoint. Secrets are forbidden. + InternalApplicationConfig: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInternalConfig' + RoleAssignment: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RoleAssignment' + PermissionGrantBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePermissionGrant' + OwnershipTransfer: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/OwnershipTransfer' + SMTPProvider: + required: true + content: + application/json: + schema: + type: object + required: + - name + - host + - port + - tls_mode + - sender_email + properties: + name: + type: string + host: + type: string + port: + type: integer + minimum: 1 + maximum: 65535 + username: + type: string + password: + type: string + writeOnly: true + tls_mode: + enum: + - starttls + - implicit_tls + sender_email: + type: string + format: email + sender_name: + type: string + inheritable: + type: boolean + default: false + StorageProviderBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateStorageProvider' + StorageUpload: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateStorageUpload' + OAuthAuthorizationDecision: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - client_id + - redirect_uri + - response_type + - scope + - state + - code_challenge + - code_challenge_method + - decision + properties: + client_id: + type: string + redirect_uri: + type: string + format: uri + response_type: + type: string + enum: + - code + scope: + type: string + state: + type: string + nonce: + type: string + code_challenge: + type: string + code_challenge_method: + type: string + enum: + - S256 + decision: + enum: + - grant + - deny + OAuthToken: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - grant_type + properties: + grant_type: + enum: + - authorization_code + - refresh_token + - client_credentials + code: + type: string + redirect_uri: + type: string + format: uri + code_verifier: + type: string + refresh_token: + type: string + client_id: + type: string + client_secret: + type: string + writeOnly: true + scope: + type: string + OAuthTokenCredential: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - token + properties: + token: + type: string + writeOnly: true + token_type_hint: + enum: + - access_token + - refresh_token + client_id: + type: string + client_secret: + type: string + writeOnly: true responses: - Problem: { description: RFC 9457 problem, content: { application/problem+json: { schema: { $ref: "#/components/schemas/Problem" } } } } - Page: { description: Cursor page, content: { application/json: { schema: { $ref: "#/components/schemas/Page" } } } } - Tokens: { description: Rotating user session, content: { application/json: { schema: { $ref: "#/components/schemas/TokenResponse" } } } } - OwnershipTransferResult: { description: Workspace ownership transferred atomically, content: { application/json: { schema: { $ref: "#/components/schemas/OwnershipTransferResult" } } } } + Problem: + description: RFC 9457 problem + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + Tokens: + description: Rotating user session + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + OwnershipTransferResult: + description: Workspace ownership transferred atomically + content: + application/json: + schema: + $ref: '#/components/schemas/OwnershipTransferResult' schemas: - ManagementAPIStatus: + HealthStatus: type: object - required: [enabled, can_manage, active_clients, token_endpoint, api_base] + required: + - status properties: - enabled: { type: boolean } - can_manage: { type: boolean } - active_clients: { type: integer, minimum: 0 } - token_endpoint: { type: string, format: uri } - api_base: { type: string, format: uri } + status: + type: string + enum: + - ok + - ready additionalProperties: false - CreateManagementClient: + VersionInfo: type: object - required: [client_id, name] + required: + - version + - commit + - built_at + - schema properties: - client_id: { type: string, minLength: 1, maxLength: 160 } - name: { type: string, minLength: 1, maxLength: 200 } - allowed_scopes: { type: array, items: { type: string, enum: [/management/organizations/*] }, default: [/management/organizations/*] } + version: + type: string + commit: + type: string + built_at: + type: string + schema: + type: string additionalProperties: false - OrganizationEnabledSettings: + SetupStatus: type: object - required: [public_registration, password_authentication, passwordless_authentication, personal_api_keys, delegation, organization_provider_overrides, application_provider_overrides, custom_events, webhooks] + required: + - available + - control_user_email_login_available + - control_auth_methods properties: - public_registration: { type: boolean } - password_authentication: { type: boolean } - passwordless_authentication: { type: boolean } - personal_api_keys: { type: boolean } - delegation: { type: boolean } - organization_provider_overrides: { type: boolean } - application_provider_overrides: { type: boolean } - custom_events: { type: boolean } - webhooks: { type: boolean } + available: + type: boolean + control_user_email_login_available: + type: boolean + control_auth_methods: + $ref: '#/components/schemas/ControlAuthMethods' additionalProperties: false - UpdateOrganizationPolicy: + SetupSession: type: object - required: [max_applications, max_users, enabled_settings] + required: + - access_token + - refresh_token + - token_type + - expires_in + - control_user_id properties: - max_applications: { type: integer, nullable: true, minimum: 0, description: Null means unlimited. } - max_users: { type: integer, nullable: true, minimum: 0, description: Null means unlimited across all applications in the organization. } - enabled_settings: { $ref: "#/components/schemas/OrganizationEnabledSettings" } + access_token: + type: string + writeOnly: true + refresh_token: + type: string + writeOnly: true + token_type: + enum: + - Bearer + expires_in: + type: integer + control_user_id: + $ref: '#/components/schemas/UUID' additionalProperties: false - OrganizationPolicy: - allOf: - - { $ref: "#/components/schemas/UpdateOrganizationPolicy" } - - type: object - required: [organization_id, usage, version] - properties: - organization_id: { $ref: "#/components/schemas/UUID" } - usage: - type: object - required: [applications, users] - properties: - applications: { type: integer, minimum: 0 } - users: { type: integer, minimum: 0 } - additionalProperties: false - version: { type: integer, format: int64, minimum: 1 } - UUID: { type: string, format: uuid } - CreateStorageProvider: + SetupCompletion: type: object - required: [name, endpoint, region, access_key_id, secret_access_key] - properties: - name: { type: string, minLength: 1, maxLength: 200 } - endpoint: { type: string, format: uri, maxLength: 2000 } - region: { type: string, minLength: 1, maxLength: 100 } - access_key_id: { type: string, minLength: 1, writeOnly: true } - secret_access_key: { type: string, minLength: 1, writeOnly: true } - force_path_style: { type: boolean, default: false } - public_bucket: { type: string, minLength: 1 } - private_bucket: { type: string, minLength: 1 } - public_base_url: { type: string, format: uri } - inheritable: { type: boolean, default: false } - allow_private_endpoint: { type: boolean, default: false, description: Installation-scoped opt-in for local or private-network S3 endpoints. } - max_object_bytes: { type: integer, format: int64, minimum: 1, default: 26214400 } - max_email_image_bytes: { type: integer, format: int64, minimum: 1, default: 2097152 } - max_application_bytes: { type: integer, format: int64, minimum: 1, default: 10737418240 } - max_application_objects: { type: integer, format: int64, minimum: 1, default: 100000 } - anyOf: [{ required: [public_bucket] }, { required: [private_bucket] }] + required: + - access_token + - refresh_token + - token_type + - expires_in + - completed + properties: + access_token: + type: string + writeOnly: true + refresh_token: + type: string + writeOnly: true + token_type: + enum: + - Bearer + expires_in: + type: integer + completed: + type: boolean + enum: + - true additionalProperties: false - CreateStorageUpload: + ChallengeAccepted: type: object - required: [filename, content_type, size_bytes, visibility] + required: + - challenge_id + - expires_in properties: - filename: { type: string, minLength: 1, maxLength: 500 } - content_type: { type: string, minLength: 1, maxLength: 255 } - size_bytes: { type: integer, format: int64, minimum: 1 } - visibility: { enum: [public, private] } - purpose: { enum: [email_image] } - metadata: { type: object, additionalProperties: true } + challenge_id: + $ref: '#/components/schemas/UUID' + expires_in: + type: integer + minimum: 1 additionalProperties: false - StorageObject: + NotificationQueued: type: object - required: [id, provider_id, owner_type, visibility, filename, content_type, size_bytes, metadata, status, version, created_at, updated_at] - properties: - id: { $ref: "#/components/schemas/UUID" } - application_id: { type: string, nullable: true, format: uuid } - provider_id: { $ref: "#/components/schemas/UUID" } - owner_type: { enum: [installation, application, user, workspace] } - owner_id: { type: string, nullable: true, format: uuid } - visibility: { enum: [public, private] } - filename: { type: string } - content_type: { type: string } - size_bytes: { type: integer, format: int64 } - etag: { type: string, nullable: true } - metadata: { type: object, additionalProperties: true } - status: { enum: [pending, ready, deleting, failed] } - public_url: { type: string, nullable: true, format: uri } - upload_expires_at: { type: string, nullable: true, format: date-time } - ready_at: { type: string, nullable: true, format: date-time } - last_error: { type: string, nullable: true } - version: { type: integer, format: int64 } - created_at: { type: string, format: date-time } - updated_at: { type: string, format: date-time } + required: + - notification_id + - status + properties: + notification_id: + $ref: '#/components/schemas/UUID' + status: + type: string + enum: + - queued + additionalProperties: false + InvitationResent: + type: object + required: + - id + - last_sent_at + - resend_available_at + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + last_sent_at: + type: string + format: date-time + resend_available_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + additionalProperties: false + ReconciliationAccepted: + type: object + required: + - id + - provider_id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + status: + type: string + enum: + - pending + additionalProperties: false + WebhookTestAccepted: + type: object + required: + - event_id + - delivery_id + - status + properties: + event_id: + $ref: '#/components/schemas/UUID' + delivery_id: + $ref: '#/components/schemas/UUID' + status: + type: string + enum: + - pending + additionalProperties: false + ControlUserAccount: + type: object + required: + - id + - email + - display_name + - status + - installation_role + - organizations + - sign_in_methods + - created_at + - updated_at + properties: + id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + display_name: + type: string + status: + enum: + - active + - suspended + - deleted + installation_role: + type: string + enum: + - owner + - admin + - auditor + - null + nullable: true + organizations: + type: array + items: + type: object + required: + - id + - name + - role + properties: + id: + $ref: '#/components/schemas/UUID' + name: + type: string + role: + enum: + - owner + - admin + - member + - auditor + additionalProperties: false + sign_in_methods: + type: object + required: + - email_code + - magic_link + - password + - external_identities + properties: + email_code: + type: boolean + magic_link: + type: boolean + password: + type: boolean + external_identities: + type: array + items: + type: object + required: + - id + - provider + - metadata + - available + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + enum: + - google + - apple + metadata: + type: object + additionalProperties: true + available: + type: boolean + created_at: + type: string + format: date-time + last_used_at: + type: string + format: date-time + nullable: true + additionalProperties: false + additionalProperties: false + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Session: + type: object + required: + - id + - actor_type + - created_at + - expires_at + - revoked + properties: + id: + $ref: '#/components/schemas/UUID' + actor_type: + enum: + - control_user + - user + - client + user_agent: + type: string + nullable: true + ip_address: + type: string + nullable: true + amr: + type: array + items: + type: string + authenticated_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + revoked: + type: boolean + additionalProperties: false + NotificationProvider: + type: object + required: + - id + - provider + - scope + - name + - sender_email + - sender_name + - inheritable + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + type: string + enum: + - smtp + scope: + enum: + - installation + - organization + - application + organization_id: + type: string + format: uuid + nullable: true + application_id: + type: string + format: uuid + nullable: true + name: + type: string + sender_email: + type: string + format: email + sender_name: + type: string + inheritable: + type: boolean + verified: + type: boolean + credentials_configured: + type: boolean + effective: + type: boolean + verified_at: + type: string + format: date-time + nullable: true + disabled_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + AuthProvider: + type: object + required: + - id + - provider + - scope + - client_id + - inheritable + - control_login_enabled + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + enum: + - google + - apple + scope: + enum: + - installation + - organization + - application + organization_id: + type: string + format: uuid + nullable: true + application_id: + type: string + format: uuid + nullable: true + client_id: + type: string + team_id: + type: string + nullable: true + key_id: + type: string + nullable: true + inheritable: + type: boolean + control_login_enabled: + type: boolean + configured: + type: boolean + inherited: + type: boolean + linked_control_users: + type: integer + minimum: 0 + inheriting_applications: + type: integer + minimum: 0 + callback_uri: + type: string + format: uri + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + BillingProvider: + type: object + required: + - id + - provider + - public_id + - api_version + - status + - scope + - inheritable + - webhook_uri + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + type: string + enum: + - stripe + public_id: + type: string + api_version: + type: string + status: + enum: + - active + - disabled + - error + scope: + enum: + - installation + - organization + - application + inheritable: + type: boolean + organization_id: + type: string + format: uuid + nullable: true + application_id: + type: string + format: uuid + nullable: true + inherited: + type: boolean + webhook_configured: + type: boolean + effective: + type: boolean + metadata: + type: object + additionalProperties: true + webhook_uri: + type: string + format: uri + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + ControlUser: + type: object + required: + - id + - email + - display_name + - status + - role + properties: + id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + display_name: + type: string + status: + enum: + - active + - suspended + - deleted + role: + enum: + - owner + - admin + - member + - auditor + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + ControlUserInvitation: + type: object + required: + - id + - email + - role + - onboarding_method + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + organization_id: + type: string + format: uuid + nullable: true + email: + type: string + format: email + role: + enum: + - owner + - admin + - member + - auditor + onboarding_method: + enum: + - email + - google + - apple + status: + enum: + - pending + - accepted + - revoked + - expired + expires_at: + type: string + format: date-time + invitation_token: + type: string + writeOnly: true + token_returned_once: + type: boolean + invited_by: + type: string + format: uuid + accepted_by: + type: string + format: uuid + nullable: true + accepted_at: + type: string + format: date-time + nullable: true + revoked_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + SigningKey: + type: object + required: + - id + - kid + - algorithm + - status + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + kid: + type: string + algorithm: + type: string + enum: + - RS256 + status: + enum: + - active + - retiring + - retired + created_at: + type: string + format: date-time + retires_at: + type: string + format: date-time + nullable: true + additionalProperties: false + SecretCredential: + type: object + required: + - secret + - secret_returned_once + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + secret: + type: string + writeOnly: true + secret_returned_once: + type: boolean + previous_secret_valid_for_seconds: + type: integer + minimum: 0 + additionalProperties: false + ManagementClient: + type: object + required: + - id + - client_id + - name + - allowed_scopes + - status + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + name: + type: string + allowed_scopes: + type: array + items: + type: string + status: + enum: + - active + - disabled + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Organization: + type: object + required: + - id + - slug + - name + - version + properties: + id: + $ref: '#/components/schemas/UUID' + slug: + type: string + name: + type: string + version: + type: integer + format: int64 + role: + type: string + retired_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Application: + type: object + required: + - id + - organization_id + - slug + - name + - version + properties: + id: + $ref: '#/components/schemas/UUID' + organization_id: + $ref: '#/components/schemas/UUID' + slug: + type: string + name: + type: string + version: + type: integer + format: int64 + issuer: + type: string + format: uri + audience: + type: string + auth_config: + type: object + additionalProperties: true + public_config: + type: object + additionalProperties: true + internal_config: + type: object + additionalProperties: true + retired_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + ApplicationStatistics: + type: object + required: + - users + - workspaces + - active_products + - active_entitlements + - pending_local_requests + - live_subscriptions + - notification_failures + - webhook_failures + - events_last_24_hours + properties: + users: + type: object + required: + - total + - active + - suspended + properties: + total: + type: integer + minimum: 0 + active: + type: integer + minimum: 0 + suspended: + type: integer + minimum: 0 + additionalProperties: false + workspaces: + type: integer + minimum: 0 + active_products: + type: integer + minimum: 0 + active_entitlements: + type: integer + minimum: 0 + pending_local_requests: + type: integer + minimum: 0 + live_subscriptions: + type: integer + minimum: 0 + notification_failures: + type: integer + minimum: 0 + webhook_failures: + type: integer + minimum: 0 + events_last_24_hours: + type: integer + minimum: 0 + additionalProperties: false + ApplicationDomain: + type: object + required: + - id + - hostname + - status + properties: + id: + $ref: '#/components/schemas/UUID' + hostname: + type: string + format: hostname + status: + enum: + - pending + - verified + - disabled + created_at: + type: string + format: date-time + additionalProperties: false + OAuthClient: + type: object + required: + - id + - client_id + - name + - client_type + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + name: + type: string + client_type: + enum: + - public + - confidential + - machine + redirect_uris: + type: array + items: + type: string + format: uri + post_logout_redirect_uris: + type: array + items: + type: string + format: uri + allowed_scopes: + type: array + items: + type: string + allowed_grants: + type: array + items: + type: string + client_secret: + type: string + writeOnly: true + nullable: true + secret: + type: string + writeOnly: true + secret_returned_once: + type: boolean + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Workspace: + type: object + required: + - id + - owner_user_id + - key + - name + - metadata + - version + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + owner_user_id: + $ref: '#/components/schemas/UUID' + key: + type: string + name: + type: string + metadata: + type: object + additionalProperties: true + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + WorkspaceMember: + type: object + required: + - workspace_id + - user_id + - role_keys + properties: + workspace_id: + $ref: '#/components/schemas/UUID' + user_id: + $ref: '#/components/schemas/UUID' + role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + RoleAssignmentRecord: + type: object + required: + - id + - role_id + properties: + id: + $ref: '#/components/schemas/UUID' + user_id: + type: string + format: uuid + nullable: true + client_id: + type: string + format: uuid + nullable: true + role_id: + $ref: '#/components/schemas/UUID' + workspace_id: + type: string + format: uuid + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + Delegation: + type: object + required: + - id + - user_id + - scopes + - reason + - status + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + user_id: + $ref: '#/components/schemas/UUID' + workspace_id: + type: string + format: uuid + nullable: true + scopes: + type: array + items: + type: string + reason: + type: string + status: + enum: + - pending + - exchanged + - revoked + - expired + exchange_code: + type: string + writeOnly: true + expires_at: + type: string + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + ApplicationInvitation: + type: object + required: + - id + - application_id + - email + - status + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + workspace_id: + type: string + format: uuid + nullable: true + email: + type: string + format: email + application_role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + workspace_role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + status: + enum: + - pending + - accepted + - revoked + - expired + code: + type: string + writeOnly: true + link_token: + type: string + writeOnly: true + link: + type: string + format: uri + expires_at: + type: string + format: date-time + accepted_user_id: + type: string + format: uuid + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + RevokedSessionCount: + type: object + required: + - revoked_sessions + properties: + revoked_sessions: + type: integer + minimum: 0 + additionalProperties: false + AuthMethods: + type: object + required: + - methods + - registration_enabled + - registration_mode + properties: + methods: + type: array + items: + enum: + - password + - email_code + - magic_link + - google + - apple + - totp + - webauthn + registration_enabled: + type: boolean + registration_mode: + enum: + - public + - invite_only + additionalProperties: false + WebAuthnChallenge: + type: object + required: + - ceremony_id + - options + - expires_at + properties: + ceremony_id: + $ref: '#/components/schemas/UUID' + options: + type: object + additionalProperties: true + expires_at: + type: string + format: date-time + additionalProperties: false + InvitationExchangeResult: + type: object + required: + - authorization_code + - redirect_uri + - expires_in + properties: + authorization_code: + type: string + writeOnly: true + redirect_uri: + type: string + format: uri + expires_in: + type: integer + minimum: 1 + mfa_challenge_id: + type: string + format: uuid + nullable: true + additionalProperties: false + PersonalAPIKeyCreated: + type: object + required: + - token + - api_key + properties: + token: + type: string + writeOnly: true + api_key: + type: object + required: + - id + - label + - token_prefix + - scopes + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + label: + type: string + token_prefix: + type: string + scopes: + type: array + items: + type: string + expires_at: + type: string + format: date-time + additionalProperties: false + additionalProperties: false + Feature: + type: object + required: + - id + - key + - name + - value_type + - metadata + properties: + id: + $ref: '#/components/schemas/UUID' + key: + type: string + name: + type: string + value_type: + enum: + - boolean + - number + - string + - free_form + free_form_format: + type: string + enum: + - text + - csv + - json + - null + nullable: true + metadata: + type: object + additionalProperties: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Product: + type: object + required: + - id + - key + - name + - listable + - status + - metadata + - entitlement_config + - features + - version + properties: + id: + $ref: '#/components/schemas/UUID' + key: + type: string + name: + type: string + description: + type: string + nullable: true + listable: + type: boolean + status: + enum: + - active + - archived + metadata: + type: object + additionalProperties: true + entitlement_config: + type: object + additionalProperties: true + features: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + version: + type: integer + format: int64 + prices: + type: array + items: + $ref: '#/components/schemas/Price' + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Price: + type: object + required: + - id + - key + - mode + - currency + - currency_exponent + - tax_behavior + - checkout_config + - entitlement_config + - features + properties: + id: + $ref: '#/components/schemas/UUID' + product_id: + $ref: '#/components/schemas/UUID' + key: + type: string + mode: + enum: + - recurring + - one_time + - local + amount_minor: + type: integer + format: int64 + nullable: true + currency: + type: string + currency_exponent: + type: integer + tax_behavior: + enum: + - inclusive + - exclusive + - unspecified + checkout_config: + type: object + additionalProperties: true + entitlement_config: + type: object + additionalProperties: true + features: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + status: + enum: + - active + - archived + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + additionalProperties: false + EntitlementGrant: + type: object + required: + - id + - subject_type + - subject_id + - source_type + - feature_values + - configuration + - starts_at + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + source_type: + enum: + - manual + - local_request + - subscription + - checkout + source_id: + type: string + format: uuid + nullable: true + feature_values: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + configuration: + type: object + additionalProperties: true + starts_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + nullable: true + revoked_at: + type: string + format: date-time + nullable: true + external_reference: + type: string + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + EffectiveEntitlements: + type: object + required: + - workspace_id + - effective + - provenance + - sources + properties: + workspace_id: + type: string + format: uuid + nullable: true + effective: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + provenance: + type: object + additionalProperties: + type: array + items: + $ref: '#/components/schemas/UUID' + sources: + type: array + items: + $ref: '#/components/schemas/EntitlementGrant' + additionalProperties: false + LocalEntitlementRequest: + type: object + required: + - id + - status + - subject_type + - subject_id + - product_snapshot + - price_snapshot + - feature_snapshot + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - pending + - approved + - rejected + - cancelled + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + product_snapshot: + type: object + additionalProperties: true + price_snapshot: + type: object + additionalProperties: true + feature_snapshot: + type: object + additionalProperties: true + address_snapshot: + type: object + additionalProperties: true + nullable: true + external_reference: + type: string + nullable: true + entitlement_grant_id: + type: string + format: uuid + nullable: true + reason: + type: string + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + LocalEntitlementApproval: + type: object + required: + - status + - entitlement_grant_id + properties: + status: + type: string + enum: + - approved + entitlement_grant_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + CheckoutSession: + type: object + required: + - id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - open + - complete + - expired + checkout_uri: + type: string + format: uri + nullable: true + provider_session_id: + type: string + nullable: true + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + external_reference: + type: string + nullable: true + created_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + nullable: true + additionalProperties: false + PortalSession: + type: object + required: + - provider_session_id + - portal_uri + properties: + provider_session_id: + type: string + portal_uri: + type: string + format: uri + additionalProperties: false + Subscription: + type: object + required: + - id + - subject_type + - subject_id + - price_id + - provider_id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + price_id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + provider_subscription_id: + type: string + status: + type: string + current_period_start: + type: string + format: date-time + nullable: true + current_period_end: + type: string + format: date-time + nullable: true + cancel_at_period_end: + type: boolean + external_reference: + type: string + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Invoice: + type: object + required: + - id + - subject_type + - subject_id + - status + - amount_due_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + subscription_id: + type: string + format: uuid + nullable: true + provider_invoice_id: + type: string + status: + type: string + amount_due_minor: + type: integer + format: int64 + amount_paid_minor: + type: integer + format: int64 + currency: + type: string + hosted_invoice_uri: + type: string + format: uri + nullable: true + external_reference: + type: string + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + Payment: + type: object + required: + - id + - subject_type + - subject_id + - status + - amount_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + invoice_id: + type: string + format: uuid + nullable: true + provider_payment_id: + type: string + status: + type: string + amount_minor: + type: integer + format: int64 + currency: + type: string + external_reference: + type: string + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + Refund: + type: object + required: + - id + - status + - amount_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + payment_id: + $ref: '#/components/schemas/UUID' + provider_refund_id: + type: string + status: + type: string + amount_minor: + type: integer + format: int64 + currency: + type: string + reason: + type: string + nullable: true + external_reference: + type: string + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + Dispute: + type: object + required: + - id + - status + - amount_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + payment_id: + type: string + format: uuid + nullable: true + provider_dispute_id: + type: string + status: + type: string + amount_minor: + type: integer + format: int64 + currency: + type: string + reason: + type: string + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + BillingStatistics: + type: object + required: + - from + - to + - revenue_minor_by_currency + - refunds_minor_by_currency + - status_counts + properties: + from: + type: string + format: date-time + to: + type: string + format: date-time + revenue_minor_by_currency: + type: array + items: + $ref: '#/components/schemas/CurrencyTotal' + refunds_minor_by_currency: + type: array + items: + $ref: '#/components/schemas/CurrencyTotal' + status_counts: + type: object + additionalProperties: + type: object + additionalProperties: + type: integer + minimum: 0 + additionalProperties: false + CurrencyTotal: + type: object + required: + - currency + - amount_minor + properties: + currency: + type: string + pattern: ^[A-Z]{3}$ + amount_minor: + type: integer + format: int64 + additionalProperties: false + BillingProviderEvent: + type: object + required: + - id + - provider_event_id + - event_type + - status + - received_at + properties: + id: + $ref: '#/components/schemas/UUID' + provider_event_id: + type: string + event_type: + type: string + status: + enum: + - pending + - processed + - failed + - ignored + attempts: + type: integer + last_error: + type: string + nullable: true + received_at: + type: string + format: date-time + processed_at: + type: string + format: date-time + nullable: true + additionalProperties: false + ReconciliationRun: + type: object + required: + - id + - provider_id + - status + - findings + - repairs + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + status: + enum: + - pending + - running + - completed + - failed + findings: + type: integer + minimum: 0 + repairs: + type: integer + minimum: 0 + last_error: + type: string + nullable: true + started_at: + type: string + format: date-time + nullable: true + completed_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + BillingProfile: + type: object + required: + - id + - subject_type + - subject_id + - version + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + name: + type: string + nullable: true + email: + type: string + format: email + nullable: true + tax_id: + type: string + nullable: true + default_address_id: + type: string + format: uuid + nullable: true + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + BillingSummary: + type: object + required: + - subject_type + - subject_id + - billing_profile + - subscriptions + properties: + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + billing_profile: + type: object + allOf: + - $ref: '#/components/schemas/BillingProfile' + nullable: true + subscriptions: + type: array + items: + $ref: '#/components/schemas/Subscription' + additionalProperties: false + Address: + type: object + required: + - id + - subject_type + - subject_id + - line1 + - city + - postal_code + - country + - active + - version + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + name: + type: string + nullable: true + line1: + type: string + line2: + type: string + nullable: true + city: + type: string + region: + type: string + nullable: true + postal_code: + type: string + country: + type: string + active: + type: boolean + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + AccountExport: + type: object + required: + - exported_at + - user + - addresses + properties: + exported_at: + type: string + format: date-time + user: + $ref: '#/components/schemas/User' + addresses: + type: array + items: + $ref: '#/components/schemas/Address' + additionalProperties: false + MFAEnrollment: + type: object + required: + - method_id + - secret + - provisioning_uri + properties: + method_id: + $ref: '#/components/schemas/UUID' + secret: + type: string + writeOnly: true + provisioning_uri: + type: string + format: uri + additionalProperties: false + MFAActivation: + type: object + required: + - method_id + - recovery_codes + properties: + method_id: + $ref: '#/components/schemas/UUID' + recovery_codes: + type: array + items: + type: string + writeOnly: true + additionalProperties: false + RecoveryCodes: + type: object + required: + - recovery_codes + properties: + recovery_codes: + type: array + items: + type: string + writeOnly: true + additionalProperties: false + MFAMethod: + type: object + required: + - id + - type + - status + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + type: + enum: + - totp + - webauthn + name: + type: string + nullable: true + status: + enum: + - pending + - active + - disabled + last_used_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + additionalProperties: false + ExternalIdentity: + type: object + required: + - id + - provider + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + enum: + - google + - apple + email: + type: string + format: email + nullable: true + created_at: + type: string + format: date-time + last_used_at: + type: string + format: date-time + nullable: true + additionalProperties: false + PermissionCheckResult: + type: object + required: + - workspace_id + - results + properties: + workspace_id: + type: string + format: uuid + nullable: true + results: + type: object + additionalProperties: + type: boolean + additionalProperties: false + AuditRecord: + type: object + required: + - id + - actor_type + - action + - target_type + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + organization_id: + type: string + format: uuid + nullable: true + application_id: + type: string + format: uuid + nullable: true + actor_type: + enum: + - control_user + - user + - client + - system + actor_id: + type: string + format: uuid + nullable: true + action: + type: string + target_type: + type: string + target_id: + type: string + nullable: true + reason: + type: string + nullable: true + request_id: + type: string + nullable: true + changes: + type: object + additionalProperties: true + created_at: + type: string + format: date-time + additionalProperties: false + AuditExportRecord: + type: object + required: + - id + - record_count + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + record_count: + type: integer + minimum: 0 + filters: + type: object + additionalProperties: true + status: + enum: + - pending + - ready + - expired + - failed + download_uri: + type: string + format: uri + nullable: true + expires_at: + type: string + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + Webhook: + type: object + required: + - id + - uri + - event_filters + - disabled + properties: + id: + $ref: '#/components/schemas/UUID' + uri: + type: string + format: uri + event_filters: + type: array + items: + type: string + secret: + type: string + writeOnly: true + secret_returned_once: + type: boolean + disabled: + type: boolean + disabled_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + WebhookDelivery: + type: object + required: + - id + - event_id + - webhook_id + - status + - attempt_count + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + event_id: + $ref: '#/components/schemas/UUID' + webhook_id: + $ref: '#/components/schemas/UUID' + status: + enum: + - pending + - delivered + - failed + - dead + attempt_count: + type: integer + minimum: 0 + response_status: + type: integer + nullable: true + last_error: + type: string + nullable: true + next_attempt_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + delivered_at: + type: string + format: date-time + nullable: true + additionalProperties: false + SenderIdentity: + type: object + required: + - id + - provider_id + - email + - name + - is_default + - verified + properties: + id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + name: + type: string + is_default: + type: boolean + verified: + type: boolean + created_at: + type: string + format: date-time + additionalProperties: false + NotificationTemplate: + type: object + required: + - id + - key + - locale + - category + - version + - status + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + type: string + format: uuid + nullable: true + key: + type: string + locale: + $ref: '#/components/schemas/Locale' + category: + type: string + subject_template: + type: string + text_template: + type: string + html_template: + type: string + nullable: true + version: + type: integer + status: + enum: + - draft + - active + - archived + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + TemplateVariables: + type: object + required: + - protected + - optional + properties: + protected: + type: array + items: + type: string + optional: + type: array + items: + type: string + additionalProperties: false + NotificationTemplatePreview: + type: object + required: + - template_id + - version + - subject + - text + - html + properties: + template_id: + $ref: '#/components/schemas/UUID' + version: + type: integer + subject: + type: string + text: + type: string + html: + type: string + nullable: true + additionalProperties: false + NotificationStatistics: + type: object + required: + - notification_status_counts + - attempts_delivered + - attempts_failed + properties: + notification_status_counts: + type: object + additionalProperties: + type: integer + minimum: 0 + attempts_delivered: + type: integer + minimum: 0 + attempts_failed: + type: integer + minimum: 0 + additionalProperties: false + Notification: + type: object + required: + - id + - template_key + - recipient + - status + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + template_key: + type: string + recipient: + type: string + format: email + locale: + $ref: '#/components/schemas/Locale' + status: + enum: + - queued + - sending + - delivered + - failed + - suppressed + - dead + attempt_count: + type: integer + minimum: 0 + last_error: + type: string + nullable: true + created_at: + type: string + format: date-time + delivered_at: + type: string + format: date-time + nullable: true + additionalProperties: false + NotificationPreference: + type: object + required: + - category + - email_enabled + properties: + category: + type: string + email_enabled: + type: boolean + updated_at: + type: string + format: date-time + additionalProperties: false + StorageProvider: + type: object + required: + - id + - provider + - scope + - name + - endpoint + - region + - force_path_style + - status + - inheritable + - credentials_configured + - allow_private_endpoint + - max_object_bytes + - max_email_image_bytes + - max_application_bytes + - max_application_objects + - version + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + type: string + enum: + - s3 + scope: + enum: + - installation + - organization + - application + organization_id: + type: string + format: uuid + nullable: true + application_id: + type: string + format: uuid + nullable: true + name: + type: string + endpoint: + type: string + format: uri + region: + type: string + force_path_style: + type: boolean + public_bucket: + type: string + nullable: true + private_bucket: + type: string + nullable: true + public_base_url: + type: string + format: uri + nullable: true + status: + enum: + - active + - disabled + - unverified + - error + inheritable: + type: boolean + credentials_configured: + type: boolean + allow_private_endpoint: + type: boolean + verified_at: + type: string + format: date-time + nullable: true + disabled_at: + type: string + format: date-time + nullable: true + last_error: + type: string + nullable: true + max_object_bytes: + type: integer + format: int64 + max_email_image_bytes: + type: integer + format: int64 + max_application_bytes: + type: integer + format: int64 + max_application_objects: + type: integer + format: int64 + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + StorageProviderStatus: + type: object + required: + - id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - active + - disabled + - unverified + - error + additionalProperties: false + StorageDownload: + type: object + required: + - url + - expires_at + - visibility + properties: + url: + type: string + format: uri + expires_at: + type: string + format: date-time + visibility: + enum: + - public + - private + additionalProperties: false + OIDCDiscovery: + type: object + required: + - issuer + - authorization_endpoint + - token_endpoint + - jwks_uri + - response_types_supported + - subject_types_supported + - id_token_signing_alg_values_supported + properties: + issuer: + type: string + format: uri + authorization_endpoint: + type: string + format: uri + token_endpoint: + type: string + format: uri + userinfo_endpoint: + type: string + format: uri + revocation_endpoint: + type: string + format: uri + introspection_endpoint: + type: string + format: uri + jwks_uri: + type: string + format: uri + response_types_supported: + type: array + items: + type: string + grant_types_supported: + type: array + items: + type: string + subject_types_supported: + type: array + items: + type: string + id_token_signing_alg_values_supported: + type: array + items: + type: string + code_challenge_methods_supported: + type: array + items: + type: string + scopes_supported: + type: array + items: + type: string + additionalProperties: false + JWKS: + type: object + required: + - keys + properties: + keys: + type: array + items: + type: object + required: + - kty + - kid + - use + - alg + - n + - e + properties: + kty: + type: string + kid: + type: string + use: + type: string + alg: + type: string + n: + type: string + e: + type: string + additionalProperties: false + additionalProperties: false + AuthorizationRedirect: + type: object + required: + - redirect_to + properties: + redirect_to: + type: string + format: uri + additionalProperties: false + TokenIntrospection: + type: object + required: + - active + properties: + active: + type: boolean + sub: + type: string + aud: + oneOf: + - type: string + - type: array + items: + type: string + iss: + type: string + format: uri + exp: + type: integer + format: int64 + iat: + type: integer + format: int64 + scope: + type: string + client_id: + type: string + token_type: + type: string + actor_type: + enum: + - control_user + - user + - client + application_id: + type: string + format: uuid + roles: + $ref: '#/components/schemas/StructuredRoles' + additionalProperties: false + UserInfo: + type: object + required: + - sub + - application_id + - actor_type + properties: + sub: + type: string + application_id: + $ref: '#/components/schemas/UUID' + actor_type: + enum: + - user + - client + email: + type: string + format: email + email_verified: + type: boolean + given_name: + type: string + family_name: + type: string + locale: + $ref: '#/components/schemas/Locale' + scope: + type: string + roles: + $ref: '#/components/schemas/StructuredRoles' + custom_claims: + type: object + additionalProperties: true + additionalProperties: false + WebhookAcknowledgement: + type: object + required: + - received + properties: + received: + type: boolean + additionalProperties: false + OrganizationMember: + type: object + required: + - control_user_id + - email + - display_name + - role + - status + properties: + control_user_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + display_name: + type: string + role: + enum: + - owner + - admin + - member + - auditor + status: + enum: + - active + - suspended + - deleted + joined_at: + type: string + format: date-time + additionalProperties: false + PersonalAPIKey: + type: object + required: + - id + - label + - token_prefix + - scopes + - status + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + label: + type: string + token_prefix: + type: string + scopes: + type: array + items: + type: string + status: + enum: + - active + - revoked + - expired + last_used_at: + type: string + format: date-time + nullable: true + expires_at: + type: string + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + OAuthConsent: + type: object + required: + - id + - client_id + - scopes + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + client_name: + type: string + scopes: + type: array + items: + type: string + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + WorkspaceAccessEntry: + type: object + required: + - type + - workspace_id + properties: + type: + enum: + - owner + - member + - invitation + workspace_id: + $ref: '#/components/schemas/UUID' + user_id: + type: string + format: uuid + nullable: true + email: + type: string + format: email + nullable: true + role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + invitation_id: + type: string + format: uuid + nullable: true + status: + type: string + expires_at: + type: string + format: date-time + nullable: true + additionalProperties: false + EmptyResponse: + type: object + maxProperties: 0 + additionalProperties: false + SessionPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Session' + next_cursor: + type: string + nullable: true + additionalProperties: false + NotificationProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/NotificationProvider' + next_cursor: + type: string + nullable: true + additionalProperties: false + AuthProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/AuthProvider' + next_cursor: + type: string + nullable: true + additionalProperties: false + BillingProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/BillingProvider' + next_cursor: + type: string + nullable: true + additionalProperties: false + ControlUserPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ControlUser' + next_cursor: + type: string + nullable: true + additionalProperties: false + ControlUserInvitationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ControlUserInvitation' + next_cursor: + type: string + nullable: true + additionalProperties: false + SigningKeyPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/SigningKey' + next_cursor: + type: string + nullable: true + additionalProperties: false + ManagementClientPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ManagementClient' + next_cursor: + type: string + nullable: true + additionalProperties: false + ApplicationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Application' + next_cursor: + type: string + nullable: true + additionalProperties: false + OrganizationMemberPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/OrganizationMember' + next_cursor: + type: string + nullable: true + additionalProperties: false + ApplicationDomainPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ApplicationDomain' + next_cursor: + type: string + nullable: true + additionalProperties: false + OAuthClientPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/OAuthClient' + next_cursor: + type: string + nullable: true + additionalProperties: false + RolePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Role' + next_cursor: + type: string + nullable: true + additionalProperties: false + WorkspacePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Workspace' + next_cursor: + type: string + nullable: true + additionalProperties: false + WorkspaceMemberPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/WorkspaceMember' + next_cursor: + type: string + nullable: true + additionalProperties: false + RoleAssignmentPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/RoleAssignmentRecord' + next_cursor: + type: string + nullable: true + additionalProperties: false + PermissionGrantPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/PermissionGrant' + next_cursor: + type: string + nullable: true + additionalProperties: false + DelegationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Delegation' + next_cursor: + type: string + nullable: true + additionalProperties: false + ApplicationInvitationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ApplicationInvitation' + next_cursor: + type: string + nullable: true + additionalProperties: false + UserPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/User' + next_cursor: + type: string + nullable: true + additionalProperties: false + EntitlementGrantPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/EntitlementGrant' + next_cursor: + type: string + nullable: true + additionalProperties: false + AddressPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Address' + next_cursor: + type: string + nullable: true + additionalProperties: false + OAuthConsentPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/OAuthConsent' + next_cursor: + type: string + nullable: true + additionalProperties: false + FeaturePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Feature' + next_cursor: + type: string + nullable: true + additionalProperties: false + ProductPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Product' + next_cursor: + type: string + nullable: true + additionalProperties: false + PricePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Price' + next_cursor: + type: string + nullable: true + additionalProperties: false + LocalEntitlementRequestPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/LocalEntitlementRequest' + next_cursor: + type: string + nullable: true + additionalProperties: false + SubscriptionPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Subscription' + next_cursor: + type: string + nullable: true + additionalProperties: false + InvoicePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Invoice' + next_cursor: + type: string + nullable: true + additionalProperties: false + PaymentPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Payment' + next_cursor: + type: string + nullable: true + additionalProperties: false + RefundPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Refund' + next_cursor: + type: string + nullable: true + additionalProperties: false + DisputePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Dispute' + next_cursor: + type: string + nullable: true + additionalProperties: false + BillingProviderEventPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/BillingProviderEvent' + next_cursor: + type: string + nullable: true + additionalProperties: false + ReconciliationRunPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ReconciliationRun' + next_cursor: + type: string + nullable: true + additionalProperties: false + MFAMethodPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/MFAMethod' + next_cursor: + type: string + nullable: true + additionalProperties: false + ExternalIdentityPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ExternalIdentity' + next_cursor: + type: string + nullable: true + additionalProperties: false + WorkspaceAccessPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/WorkspaceAccessEntry' + next_cursor: + type: string + nullable: true + additionalProperties: false + EventPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/EventEnvelope' + next_cursor: + type: string + nullable: true + additionalProperties: false + EventTypePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/EventTypeDefinition' + next_cursor: + type: string + nullable: true + additionalProperties: false + AuditRecordPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/AuditRecord' + next_cursor: + type: string + nullable: true + additionalProperties: false + WebhookPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Webhook' + next_cursor: + type: string + nullable: true + additionalProperties: false + WebhookDeliveryPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/WebhookDelivery' + next_cursor: + type: string + nullable: true + additionalProperties: false + SenderIdentityPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/SenderIdentity' + next_cursor: + type: string + nullable: true + additionalProperties: false + NotificationTemplatePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/NotificationTemplate' + next_cursor: + type: string + nullable: true + additionalProperties: false + NotificationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Notification' + next_cursor: + type: string + nullable: true + additionalProperties: false + NotificationPreferencePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/NotificationPreference' + next_cursor: + type: string + nullable: true + additionalProperties: false + StorageProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/StorageProvider' + next_cursor: + type: string + nullable: true + additionalProperties: false + StorageObjectPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/StorageObject' + next_cursor: + type: string + nullable: true + additionalProperties: false + PersonalAPIKeyPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/PersonalAPIKey' + next_cursor: + type: string + nullable: true + additionalProperties: false + CompleteSetup: + type: object + properties: + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + additionalProperties: false + ControlEmailStart: + type: object + required: + - email + properties: + email: + type: string + format: email + delivery: + enum: + - code + - link + - both + default: both + additionalProperties: false + UpdateControlUserAccount: + type: object + required: + - display_name + properties: + display_name: + type: string + minLength: 1 + maxLength: 200 + additionalProperties: false + ControlInvitationProviderStart: + type: object + required: + - invitation_token + properties: + invitation_token: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + UpdateControlInvitationMethod: + type: object + properties: + onboarding_method: + enum: + - email + - google + - apple + additionalProperties: false + UpdateManagementAPI: + type: object + required: + - enabled + properties: + enabled: + type: boolean + additionalProperties: false + RefreshToken: + type: object + required: + - refresh_token + properties: + refresh_token: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + ConfigureAuthProvider: + type: object + required: + - client_id + properties: + client_id: + type: string + minLength: 1 + maxLength: 500 + client_secret: + type: string + minLength: 1 + writeOnly: true + team_id: + type: string + minLength: 1 + maxLength: 100 + key_id: + type: string + minLength: 1 + maxLength: 100 + private_key_pem: + type: string + minLength: 1 + writeOnly: true + inheritable: + type: boolean + default: false + control_login_enabled: + type: boolean + additionalProperties: false + UpdateSMTPProvider: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 200 + host: + type: string + minLength: 1 + maxLength: 255 + port: + type: integer + minimum: 1 + maximum: 65535 + username: + type: string + password: + type: string + writeOnly: true + tls_mode: + enum: + - starttls + - implicit_tls + sender_email: + type: string + format: email + sender_name: + type: string + maxLength: 200 + inheritable: + type: boolean + additionalProperties: false + TestNotificationProvider: + type: object + required: + - recipient + properties: + recipient: + type: string + format: email + additionalProperties: false + UpdateBillingProvider: + type: object + minProperties: 1 + properties: + secret: + type: string + writeOnly: true + webhook_secret: + type: string + writeOnly: true + metadata: + type: object + additionalProperties: true + inheritable: + type: boolean + additionalProperties: false + MembershipRole: + type: object + required: + - role + properties: + role: + enum: + - owner + - admin + - member + - auditor + additionalProperties: false + CreateApplicationDomain: + type: object + required: + - hostname + properties: + hostname: + type: string + minLength: 1 + maxLength: 253 + additionalProperties: false + CreateClient: + type: object + required: + - client_id + - name + - client_type + properties: + client_id: + type: string + minLength: 1 + maxLength: 160 + name: + type: string + minLength: 1 + maxLength: 200 + client_type: + enum: + - public + - confidential + redirect_uris: + type: array + uniqueItems: true + items: + type: string + format: uri + allowed_grants: + type: array + uniqueItems: true + items: + enum: + - authorization_code + - refresh_token + - client_credentials + allowed_scopes: + type: array + uniqueItems: true + items: + type: string + additionalProperties: false + UpdateClient: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 200 + redirect_uris: + type: array + uniqueItems: true + items: + type: string + format: uri + allowed_grants: + type: array + uniqueItems: true + items: + enum: + - authorization_code + - refresh_token + - client_credentials + allowed_scopes: + type: array + uniqueItems: true + items: + type: string + additionalProperties: false + CreateWorkspace: + type: object + required: + - key + - name + properties: + key: + type: string + minLength: 1 + maxLength: 100 + name: + type: string + minLength: 1 + maxLength: 255 + owner_user_id: + $ref: '#/components/schemas/UUID' + metadata: + type: object + additionalProperties: true + additionalProperties: false + UpdateWorkspace: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 255 + metadata: + type: object + additionalProperties: true + additionalProperties: false + ReplaceWorkspaceMemberRoles: + type: object + required: + - role_keys + properties: + role_keys: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/RoleKey' + additionalProperties: false + CreateDelegation: + type: object + required: + - user_id + - reason + - redirect_uri + - permissions + properties: + user_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + reason: + type: string + minLength: 1 + maxLength: 500 + redirect_uri: + type: string + format: uri + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + expires_in: + type: integer + format: int64 + minimum: 60 + maximum: 3600 + additionalProperties: false + ExchangeDelegation: + type: object + required: + - exchange_code + properties: + exchange_code: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + CreateUser: + type: object + required: + - email + properties: + email: + type: string + format: email + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + first_name: + type: string + maxLength: 200 + last_name: + type: string + maxLength: 200 + username: + type: string + maxLength: 200 + nullable: true + locale: + $ref: '#/components/schemas/Locale' + email_verified: + type: boolean + is_org_verified: + type: boolean + custom_attributes: + type: object + additionalProperties: true + additionalProperties: false + UpdateUser: + type: object + minProperties: 1 + properties: + first_name: + type: string + maxLength: 200 + last_name: + type: string + maxLength: 200 + username: + type: string + maxLength: 200 + nullable: true + locale: + $ref: '#/components/schemas/Locale' + status: + enum: + - active + - suspended + - pending_deletion + email_verified: + type: boolean + is_org_verified: + type: boolean + custom_attributes: + type: object + additionalProperties: true + reason: + type: string + maxLength: 500 + additionalProperties: false + AuditReason: + type: object + required: + - reason + properties: + reason: + type: string + minLength: 1 + maxLength: 500 + additionalProperties: false + PasswordResetStart: + type: object + required: + - email + properties: + email: + type: string + format: email + additionalProperties: false + PasswordResetVerify: + type: object + required: + - challenge_id + - password + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + minLength: 8 + maxLength: 8 + writeOnly: true + link_token: + type: string + writeOnly: true + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + additionalProperties: false + ExternalAuthStartRequest: + type: object + required: + - redirect_uri + properties: + flow: + enum: + - sign_in + - sign_up + - automatic + - link + default: automatic + redirect_uri: + type: string + format: uri + login_hint: + type: string + format: email + additionalProperties: false + ExternalAuthExchange: + type: object + required: + - exchange + properties: + exchange: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + VerifyMFA: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + writeOnly: true + recovery_code: + type: string + writeOnly: true + oneOf: + - required: + - code + - required: + - recovery_code + additionalProperties: false + BeginWebAuthnAuthentication: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + origin: + type: string + format: uri + additionalProperties: false + BeginWebAuthnRegistration: + type: object + properties: + origin: + type: string + format: uri + label: + type: string + maxLength: 120 + additionalProperties: false + FinishWebAuthnCeremony: + type: object + required: + - ceremony_id + - credential + properties: + ceremony_id: + $ref: '#/components/schemas/UUID' + credential: + type: object + additionalProperties: true + additionalProperties: false + CreateEntitlement: + type: object + required: + - subject_type + - subject_id + properties: + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + product_id: + $ref: '#/components/schemas/UUID' + price_id: + $ref: '#/components/schemas/UUID' + feature_values: + type: object + additionalProperties: true + configuration: + type: object + additionalProperties: true + starts_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + reason: + type: string + maxLength: 500 + external_reference: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false + AdjustEntitlement: + type: object + properties: + expires_at: + type: string + format: date-time + nullable: true + reason: + type: string + maxLength: 500 + additionalProperties: false + CreatePortalSession: + type: object + required: + - provider_id + - return_uri + properties: + provider_id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + default: user + subject_id: + $ref: '#/components/schemas/UUID' + return_uri: + type: string + format: uri + additionalProperties: false + CancelSubscription: + type: object + properties: + at_period_end: + type: boolean + additionalProperties: false + ChangeSubscriptionPrice: + type: object + required: + - price_id + properties: + price_id: + $ref: '#/components/schemas/UUID' + proration_behavior: + enum: + - create_prorations + - always_invoice + - none + default: create_prorations + additionalProperties: false + CreateRefund: + type: object + properties: + amount_minor: + type: integer + format: int64 + minimum: 1 + reason: + type: string + maxLength: 500 + additionalProperties: false + AccountChallenge: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + minLength: 8 + maxLength: 8 + writeOnly: true + link_token: + type: string + writeOnly: true + additionalProperties: false + EmailAddress: + type: object + required: + - email + properties: + email: + type: string + format: email + additionalProperties: false + PasswordChange: + type: object + required: + - current_password + - new_password + properties: + current_password: + type: string + writeOnly: true + new_password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + additionalProperties: false + StartTOTP: + type: object + properties: + label: + type: string + maxLength: 120 + additionalProperties: false + ActivateTOTP: + type: object + required: + - code + properties: + code: + type: string + minLength: 6 + maxLength: 8 + writeOnly: true + additionalProperties: false + CreateAddress: + type: object + required: + - name + - line1 + - city + - postal_code + - country_code + properties: + name: + type: string + minLength: 1 + maxLength: 200 + line1: + type: string + minLength: 1 + maxLength: 500 + line2: + type: string + maxLength: 500 + city: + type: string + minLength: 1 + maxLength: 200 + region: + type: string + maxLength: 200 + postal_code: + type: string + minLength: 1 + maxLength: 50 + country_code: + type: string + pattern: ^[A-Za-z]{2}$ + tax_id: + type: string + maxLength: 100 + nullable: true + active: + type: boolean + default: true + additionalProperties: false + UpdateAddress: + type: object + required: + - version + properties: + name: + type: string + minLength: 1 + maxLength: 200 + line1: + type: string + minLength: 1 + maxLength: 500 + line2: + type: string + maxLength: 500 + city: + type: string + minLength: 1 + maxLength: 200 + region: + type: string + maxLength: 200 + postal_code: + type: string + minLength: 1 + maxLength: 50 + country_code: + type: string + pattern: ^[A-Za-z]{2}$ + tax_id: + type: string + maxLength: 100 + nullable: true + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + UpdateBillingProfile: + type: object + required: + - version + properties: + name: + type: string + maxLength: 200 + email: + type: string + format: email + tax_id: + type: string + maxLength: 100 + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + PermissionCheck: + type: object + required: + - permissions + properties: + permissions: + type: array + minItems: 1 + maxItems: 100 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + workspace_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + AuditExport: + type: object + properties: + start: + type: string + format: date-time + end: + type: string + format: date-time + actor_type: + enum: + - control_user + - user + - client + - system + action: + type: string + target_type: + type: string + additionalProperties: false + CreateWebhook: + type: object + required: + - uri + properties: + uri: + type: string + format: uri + event_filters: + type: array + uniqueItems: true + items: + type: string + additionalProperties: false + UpdateWebhook: + type: object + minProperties: 1 + properties: + uri: + type: string + format: uri + event_filters: + type: array + uniqueItems: true + items: + type: string + enabled: + type: boolean + additionalProperties: false + CreateSenderIdentity: + type: object + required: + - provider_id + - email + properties: + provider_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + name: + type: string + maxLength: 200 + is_default: + type: boolean + default: false + additionalProperties: false + CreateNotificationTemplate: + type: object + required: + - key + - category + - subject_template + - text_template + properties: + key: + type: string + pattern: ^[a-z][a-z0-9_.-]{2,100}$ + locale: + $ref: '#/components/schemas/Locale' + category: + enum: + - security + - billing + - transactional + - marketing + subject_template: + type: string + minLength: 1 + maxLength: 500 + text_template: + type: string + minLength: 1 + maxLength: 100000 + html_template: + type: string + maxLength: 200000 + variable_schema: + type: object + additionalProperties: true + additionalProperties: false + UpdateNotificationTemplate: + type: object + minProperties: 1 + properties: + category: + enum: + - security + - billing + - transactional + - marketing + subject_template: + type: string + minLength: 1 + maxLength: 500 + text_template: + type: string + minLength: 1 + maxLength: 100000 + html_template: + type: string + maxLength: 200000 + variable_schema: + type: object + additionalProperties: true + additionalProperties: false + PreviewNotificationTemplate: + type: object + required: + - variables + properties: + variables: + type: object + additionalProperties: true + user_id: + $ref: '#/components/schemas/UUID' + recipient: + type: string + format: email + additionalProperties: false + UpdateNotificationPreference: + type: object + required: + - email_enabled + properties: + email_enabled: + type: boolean + additionalProperties: false + UpdateStorageProvider: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 200 + endpoint: + type: string + format: uri + maxLength: 2000 + region: + type: string + minLength: 1 + maxLength: 100 + access_key_id: + type: string + minLength: 1 + writeOnly: true + secret_access_key: + type: string + minLength: 1 + writeOnly: true + force_path_style: + type: boolean + public_bucket: + type: string + private_bucket: + type: string + public_base_url: + type: string + format: uri + inheritable: + type: boolean + allow_private_endpoint: + type: boolean + max_object_bytes: + type: integer + format: int64 + minimum: 1 + max_email_image_bytes: + type: integer + format: int64 + minimum: 1 + max_application_bytes: + type: integer + format: int64 + minimum: 1 + max_application_objects: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + ManagementAPIStatus: + type: object + required: + - enabled + - can_manage + - active_clients + - token_endpoint + - api_base + properties: + enabled: + type: boolean + can_manage: + type: boolean + active_clients: + type: integer + minimum: 0 + token_endpoint: + type: string + format: uri + api_base: + type: string + format: uri + additionalProperties: false + CreateManagementClient: + type: object + required: + - client_id + - name + properties: + client_id: + type: string + minLength: 1 + maxLength: 160 + name: + type: string + minLength: 1 + maxLength: 200 + allowed_scopes: + type: array + items: + type: string + enum: + - /management/organizations/* + default: + - /management/organizations/* + additionalProperties: false + OrganizationEnabledSettings: + type: object + required: + - public_registration + - password_authentication + - passwordless_authentication + - personal_api_keys + - delegation + - organization_provider_overrides + - application_provider_overrides + - custom_events + - webhooks + properties: + public_registration: + type: boolean + password_authentication: + type: boolean + passwordless_authentication: + type: boolean + personal_api_keys: + type: boolean + delegation: + type: boolean + organization_provider_overrides: + type: boolean + application_provider_overrides: + type: boolean + custom_events: + type: boolean + webhooks: + type: boolean + additionalProperties: false + UpdateOrganizationPolicy: + type: object + required: + - max_applications + - max_users + - enabled_settings + properties: + max_applications: + type: integer + minimum: 0 + description: Null means unlimited. + nullable: true + max_users: + type: integer + minimum: 0 + description: Null means unlimited across all applications in the organization. + nullable: true + enabled_settings: + $ref: '#/components/schemas/OrganizationEnabledSettings' + additionalProperties: false + OrganizationPolicy: + type: object + required: + - max_applications + - max_users + - enabled_settings + - organization_id + - usage + - version + properties: + max_applications: + type: integer + minimum: 0 + description: Null means unlimited. + nullable: true + max_users: + type: integer + minimum: 0 + description: Null means unlimited across all applications in the organization. + nullable: true + enabled_settings: + $ref: '#/components/schemas/OrganizationEnabledSettings' + organization_id: + $ref: '#/components/schemas/UUID' + usage: + type: object + required: + - applications + - users + properties: + applications: + type: integer + minimum: 0 + users: + type: integer + minimum: 0 + additionalProperties: false + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + UUID: + type: string + format: uuid + CreateStorageProvider: + type: object + required: + - name + - endpoint + - region + - access_key_id + - secret_access_key + properties: + name: + type: string + minLength: 1 + maxLength: 200 + endpoint: + type: string + format: uri + maxLength: 2000 + region: + type: string + minLength: 1 + maxLength: 100 + access_key_id: + type: string + minLength: 1 + writeOnly: true + secret_access_key: + type: string + minLength: 1 + writeOnly: true + force_path_style: + type: boolean + default: false + public_bucket: + type: string + minLength: 1 + private_bucket: + type: string + minLength: 1 + public_base_url: + type: string + format: uri + inheritable: + type: boolean + default: false + allow_private_endpoint: + type: boolean + default: false + description: Installation-scoped opt-in for local or private-network S3 endpoints. + max_object_bytes: + type: integer + format: int64 + minimum: 1 + default: 26214400 + max_email_image_bytes: + type: integer + format: int64 + minimum: 1 + default: 2097152 + max_application_bytes: + type: integer + format: int64 + minimum: 1 + default: 10737418240 + max_application_objects: + type: integer + format: int64 + minimum: 1 + default: 100000 + anyOf: + - required: + - public_bucket + - required: + - private_bucket + additionalProperties: false + CreateStorageUpload: + type: object + required: + - filename + - content_type + - size_bytes + - visibility + properties: + filename: + type: string + minLength: 1 + maxLength: 500 + content_type: + type: string + minLength: 1 + maxLength: 255 + size_bytes: + type: integer + format: int64 + minimum: 1 + visibility: + enum: + - public + - private + purpose: + enum: + - email_image + metadata: + type: object + additionalProperties: true + additionalProperties: false + StorageObject: + type: object + required: + - id + - provider_id + - owner_type + - visibility + - filename + - content_type + - size_bytes + - metadata + - status + - version + - created_at + - updated_at + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + type: string + format: uuid + nullable: true + provider_id: + $ref: '#/components/schemas/UUID' + owner_type: + enum: + - installation + - application + - user + - workspace + owner_id: + type: string + format: uuid + nullable: true + visibility: + enum: + - public + - private + filename: + type: string + content_type: + type: string + size_bytes: + type: integer + format: int64 + etag: + type: string + nullable: true + metadata: + type: object + additionalProperties: true + status: + enum: + - pending + - ready + - deleting + - failed + public_url: + type: string + format: uri + nullable: true + upload_expires_at: + type: string + format: date-time + nullable: true + ready_at: + type: string + format: date-time + nullable: true + last_error: + type: string + nullable: true + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time additionalProperties: false StorageUploadAuthorization: type: object - required: [object, upload_url, upload_expires_at, required_headers] + required: + - object + - upload_url + - upload_expires_at + - required_headers properties: - object: { $ref: "#/components/schemas/StorageObject" } - upload_url: { type: string, format: uri, writeOnly: true } - upload_expires_at: { type: string, format: date-time } - required_headers: { type: object, additionalProperties: { type: string } } + object: + $ref: '#/components/schemas/StorageObject' + upload_url: + type: string + format: uri + writeOnly: true + upload_expires_at: + type: string + format: date-time + required_headers: + type: object + additionalProperties: + type: string additionalProperties: false RuntimeStorageConfig: type: object - required: [public_uploads_enabled, private_uploads_enabled] - properties: - public_uploads_enabled: { type: boolean } - private_uploads_enabled: { type: boolean } - max_public_object_bytes: { type: integer, format: int64 } - max_private_object_bytes: { type: integer, format: int64 } - max_email_image_bytes: { type: integer, format: int64 } - public_provider_scope: { enum: [installation, organization, application] } - private_provider_scope: { enum: [installation, organization, application] } - additionalProperties: false - Locale: { type: string, maxLength: 35, description: "Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference." } - Problem: { type: object, required: [type, title, status, code], properties: { type: { type: string, format: uri-reference }, title: { type: string }, status: { type: integer }, detail: { type: string }, code: { type: string }, request_id: { type: string } } } - Page: { type: object, required: [items, next_cursor], properties: { items: { type: array, items: {} }, next_cursor: { type: string, nullable: true } } } - OrganizationPage: { type: object, required: [items, next_cursor, installation_role], properties: { items: { type: array, items: { type: object, additionalProperties: true } }, next_cursor: { type: string, nullable: true }, installation_role: { type: string, nullable: true, enum: [owner, admin, auditor, null], description: "The current operator's installation-wide role, or null for organization-only access." } } } - BootstrapRequest: { type: object, required: [credential, email], properties: { credential: { type: string, writeOnly: true }, email: { type: string, format: email }, display_name: { type: string } } } - AcceptOrganizationInvitation: { type: object, required: [invitation_token], properties: { invitation_token: { type: string, minLength: 1, writeOnly: true }, display_name: { type: string, maxLength: 200 } }, additionalProperties: false } - ApplicationFlowConfig: { type: object, required: [oauth_client_id, sign_in_redirect_uri, invitation_redirect_uri], additionalProperties: false, properties: { oauth_client_id: { type: string, minLength: 1 }, sign_in_redirect_uri: { type: string, format: uri }, invitation_redirect_uri: { type: string, format: uri } } } - ApplicationAuthConfig: { type: object, additionalProperties: false, properties: { flows: { $ref: "#/components/schemas/ApplicationFlowConfig" } } } - ApplicationInternalConfig: { type: object, additionalProperties: false, properties: { registration_mode: { type: string, enum: [public, invite_only] }, password_enabled: { type: boolean }, passwordless_enabled: { type: boolean }, personal_api_keys_enabled: { type: boolean }, delegation_enabled: { type: boolean } } } - RuntimeAuthConfig: { type: object, required: [registration_mode, registration_enabled, password_enabled, passwordless_enabled], additionalProperties: false, properties: { registration_mode: { type: string, enum: [public, invite_only] }, registration_enabled: { type: boolean }, password_enabled: { type: boolean }, passwordless_enabled: { type: boolean }, flows: { $ref: "#/components/schemas/ApplicationFlowConfig" } } } - RuntimeConfig: { type: object, required: [schema_version, api_base, issuer, application_id, public_config, auth, storage], properties: { schema_version: { type: string }, api_base: { type: string, format: uri }, issuer: { type: string, format: uri }, application_id: { $ref: "#/components/schemas/UUID" }, public_config: { type: object, additionalProperties: true }, auth: { $ref: "#/components/schemas/RuntimeAuthConfig" }, storage: { $ref: "#/components/schemas/RuntimeStorageConfig" } } } - PasswordSignIn: { type: object, required: [email, password], properties: { email: { type: string, format: email }, password: { type: string, writeOnly: true, minLength: 12, maxLength: 1024 } } } - PasswordSignUp: { allOf: [{ $ref: "#/components/schemas/PasswordSignIn" }, { type: object, properties: { first_name: { type: string }, last_name: { type: string }, locale: { $ref: "#/components/schemas/Locale" } } }] } - EmailStart: { type: object, required: [email, intent, delivery], properties: { email: { type: string, format: email }, intent: { enum: [sign_in, sign_up, automatic] }, delivery: { enum: [code, link, both] }, redirect_uri: { type: string, format: uri } } } - EmailVerify: { type: object, required: [challenge_id], properties: { challenge_id: { $ref: "#/components/schemas/UUID" }, code: { type: string, minLength: 8, maxLength: 8, writeOnly: true }, link_token: { type: string, writeOnly: true } } } - TokenResponse: { type: object, required: [access_token, refresh_token, token_type, expires_in], properties: { access_token: { type: string, writeOnly: true }, refresh_token: { type: string, writeOnly: true }, token_type: { enum: [Bearer] }, expires_in: { type: integer } } } - User: { type: object, required: [id, application_id, email, locale, email_verified, is_org_verified, status], properties: { id: { $ref: "#/components/schemas/UUID" }, application_id: { $ref: "#/components/schemas/UUID" }, email: { type: string, format: email }, first_name: { type: string }, last_name: { type: string }, username: { type: string, nullable: true }, locale: { $ref: "#/components/schemas/Locale" }, email_verified: { type: boolean }, is_org_verified: { type: boolean }, status: { enum: [active, suspended, pending_deletion, anonymized, deleted] }, custom_attributes: { type: object, additionalProperties: true }, version: { type: integer, format: int64 } } } + required: + - public_uploads_enabled + - private_uploads_enabled + properties: + public_uploads_enabled: + type: boolean + private_uploads_enabled: + type: boolean + max_public_object_bytes: + type: integer + format: int64 + max_private_object_bytes: + type: integer + format: int64 + max_email_image_bytes: + type: integer + format: int64 + public_provider_scope: + enum: + - installation + - organization + - application + private_provider_scope: + enum: + - installation + - organization + - application + additionalProperties: false + Locale: + type: string + maxLength: 35 + description: Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Problem: + type: object + required: + - type + - title + - status + - code + properties: + type: + type: string + format: uri-reference + title: + type: string + status: + type: integer + detail: + type: string + code: + type: string + request_id: + type: string + affected_users: + type: integer + minimum: 0 + additionalProperties: false + OrganizationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Organization' + next_cursor: + type: string + nullable: true + installation_role: + type: string + enum: + - owner + - admin + - auditor + - null + description: The current Platform user's installation-wide role, or null for organization-only access. + nullable: true + additionalProperties: false + BootstrapRequest: + type: object + required: + - credential + - email + properties: + credential: + type: string + writeOnly: true + email: + type: string + format: email + display_name: + type: string + additionalProperties: false + AcceptControlUserInvitation: + type: object + required: + - invitation_token + properties: + invitation_token: + type: string + minLength: 1 + writeOnly: true + display_name: + type: string + maxLength: 200 + additionalProperties: false + CreateControlUserInvitation: + type: object + required: + - email + - role + properties: + email: + type: string + format: email + role: + enum: + - owner + - admin + - member + - auditor + onboarding_method: + enum: + - email + - google + - apple + default: email + expires_in: + type: integer + minimum: 300 + maximum: 2592000 + additionalProperties: false + ControlAuthPolicy: + type: object + required: + - email_code_enabled + - magic_link_enabled + - password_enabled + properties: + email_code_enabled: + type: boolean + magic_link_enabled: + type: boolean + password_enabled: + type: boolean + additionalProperties: false + UpdateControlAuthPolicy: + type: object + required: + - email_code_enabled + - magic_link_enabled + - password_enabled + properties: + email_code_enabled: + type: boolean + magic_link_enabled: + type: boolean + password_enabled: + type: boolean + confirm_affected_users: + type: boolean + additionalProperties: false + ControlAuthMethods: + type: object + required: + - email_code + - magic_link + - password + - providers + properties: + email_code: + type: boolean + magic_link: + type: boolean + password: + type: boolean + providers: + type: array + items: + enum: + - google + - apple + additionalProperties: false + ExternalAuthStart: + type: object + required: + - provider + - authorize_url + - expires_in + properties: + provider: + enum: + - google + - apple + authorize_url: + type: string + format: uri + expires_in: + type: integer + additionalProperties: false + UpdateInstallationAuthProvider: + type: object + properties: + inheritable: + type: boolean + control_login_enabled: + type: boolean + confirm_affected_users: + type: boolean + minProperties: 1 + additionalProperties: false + ApplicationFlowConfig: + type: object + required: + - oauth_client_id + - sign_in_redirect_uri + - invitation_redirect_uri + additionalProperties: false + properties: + oauth_client_id: + type: string + minLength: 1 + sign_in_redirect_uri: + type: string + format: uri + description: Exact registered HTTPS, loopback HTTP, or public-client native application redirect URI. + invitation_redirect_uri: + type: string + format: uri + description: Invitation destination using the same origin or native scheme authority as the sign-in redirect. + ApplicationAuthConfig: + type: object + additionalProperties: false + properties: + flows: + $ref: '#/components/schemas/ApplicationFlowConfig' + ApplicationInternalConfig: + type: object + additionalProperties: false + properties: + registration_mode: + type: string + enum: + - public + - invite_only + password_enabled: + type: boolean + passwordless_enabled: + type: boolean + personal_api_keys_enabled: + type: boolean + delegation_enabled: + type: boolean + user_invitations_enabled: + type: boolean + default: false + custom_token_claim_keys: + type: array + maxItems: 32 + items: + type: string + minLength: 1 + maxLength: 64 + pattern: ^[A-Za-z0-9_.-]+$ + RuntimeAuthConfig: + type: object + required: + - registration_mode + - registration_enabled + - password_enabled + - passwordless_enabled + additionalProperties: false + properties: + registration_mode: + type: string + enum: + - public + - invite_only + registration_enabled: + type: boolean + password_enabled: + type: boolean + passwordless_enabled: + type: boolean + flows: + $ref: '#/components/schemas/ApplicationFlowConfig' + RuntimeConfig: + type: object + required: + - schema_version + - api_base + - issuer + - application_id + - public_config + - auth + - storage + properties: + schema_version: + type: string + api_base: + type: string + format: uri + issuer: + type: string + format: uri + application_id: + $ref: '#/components/schemas/UUID' + public_config: + type: object + additionalProperties: true + auth: + $ref: '#/components/schemas/RuntimeAuthConfig' + storage: + $ref: '#/components/schemas/RuntimeStorageConfig' + additionalProperties: false + PasswordSignIn: + type: object + required: + - email + - password + properties: + email: + type: string + format: email + password: + type: string + writeOnly: true + minLength: 12 + maxLength: 1024 + additionalProperties: false + PasswordSignUp: + type: object + required: + - email + - password + properties: + email: + type: string + format: email + password: + type: string + writeOnly: true + minLength: 12 + maxLength: 1024 + first_name: + type: string + last_name: + type: string + locale: + $ref: '#/components/schemas/Locale' + additionalProperties: false + EmailStart: + type: object + required: + - email + - intent + - delivery + properties: + email: + type: string + format: email + intent: + enum: + - sign_in + - sign_up + - automatic + delivery: + enum: + - code + - link + - both + redirect_uri: + type: string + format: uri + additionalProperties: false + EmailVerify: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + minLength: 8 + maxLength: 8 + writeOnly: true + link_token: + type: string + writeOnly: true + additionalProperties: false + TokenResponse: + type: object + required: + - access_token + - refresh_token + - token_type + - expires_in + properties: + access_token: + type: string + writeOnly: true + refresh_token: + type: string + writeOnly: true + token_type: + enum: + - Bearer + expires_in: + type: integer + additionalProperties: false + User: + type: object + required: + - id + - application_id + - email + - locale + - email_verified + - is_org_verified + - status + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + first_name: + type: string + last_name: + type: string + username: + type: string + nullable: true + locale: + $ref: '#/components/schemas/Locale' + email_verified: + type: boolean + is_org_verified: + type: boolean + status: + enum: + - active + - suspended + - pending_deletion + - anonymized + - deleted + custom_attributes: + type: object + additionalProperties: true + version: + type: integer + format: int64 + additionalProperties: false UpdateUserProfile: type: object properties: - first_name: { type: string } - last_name: { type: string } - username: { type: string, nullable: true } - locale: { $ref: "#/components/schemas/Locale" } + first_name: + type: string + last_name: + type: string + username: + type: string + nullable: true + locale: + $ref: '#/components/schemas/Locale' additionalProperties: false QueueNotification: type: object - required: [template_key] + required: + - template_key properties: - template_key: { type: string, minLength: 3, maxLength: 101 } - locale: { $ref: "#/components/schemas/Locale", description: Explicit locale override. When omitted, the selected user's locale is used. } - recipient: { type: string, format: email } - user_id: { $ref: "#/components/schemas/UUID" } - variables: { type: object, additionalProperties: true } + template_key: + type: string + minLength: 3 + maxLength: 101 + locale: + $ref: '#/components/schemas/Locale' + description: Explicit locale override. When omitted + the selected user's locale is used.: null + recipient: + type: string + format: email + user_id: + $ref: '#/components/schemas/UUID' + variables: + type: object + additionalProperties: true attachments: type: array items: type: object - required: [filename, content_type, content_base64] + required: + - filename + - content_type + - content_base64 properties: - filename: { type: string } - content_type: { type: string } - content_base64: { type: string, format: byte } + filename: + type: string + content_type: + type: string + content_base64: + type: string + format: byte additionalProperties: false additionalProperties: false QueuedNotification: type: object - required: [id, status, requested_locale, resolved_locale, fallback_used] + required: + - id + - status + - requested_locale + - resolved_locale + - fallback_used + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - queued + - suppressed + requested_locale: + $ref: '#/components/schemas/Locale' + resolved_locale: + $ref: '#/components/schemas/Locale' + fallback_used: + type: boolean + additionalProperties: false + CreateInvitation: + type: object + required: + - email + properties: + email: + type: string + format: email + workspace_id: + $ref: '#/components/schemas/UUID' + application_role_keys: + type: array + items: + type: string + maxItems: 20 + workspace_role_keys: + type: array + items: + type: string + maxItems: 20 + expires_in: + type: integer + format: int64 + minimum: 300 + maximum: 2592000 + default: 604800 + additionalProperties: false + ExchangeInvitation: + type: object + required: + - code_challenge + oneOf: + - required: + - email + - code + - required: + - invitation_id + - link_token + properties: + invitation_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + code: + type: string + minLength: 8 + maxLength: 8 + pattern: ^[ABCDEFGHJKLMNPQRSTUVWXYZ23456789]{8}$ + writeOnly: true + link_token: + type: string + writeOnly: true + code_challenge: + type: string + minLength: 43 + maxLength: 43 + pattern: ^[A-Za-z0-9_-]{43}$ + writeOnly: true + additionalProperties: false + RedeemInvitation: + type: object + required: + - authorization_code + - code_verifier properties: - id: { $ref: "#/components/schemas/UUID" } - status: { enum: [queued, suppressed] } - requested_locale: { $ref: "#/components/schemas/Locale" } - resolved_locale: { $ref: "#/components/schemas/Locale" } - fallback_used: { type: boolean } + authorization_code: + type: string + writeOnly: true + code_verifier: + type: string + minLength: 43 + maxLength: 128 + pattern: ^[A-Za-z0-9._~-]{43,128}$ + writeOnly: true additionalProperties: false RoleAssignment: type: object - required: [role_id] - oneOf: [{ required: [user_id] }, { required: [client_id] }] + required: + - role_id + oneOf: + - required: + - user_id + - required: + - client_id + properties: + user_id: + $ref: '#/components/schemas/UUID' + client_id: + $ref: '#/components/schemas/UUID' + role_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + PermissionKey: + type: string + minLength: 1 + maxLength: 160 + pattern: ^(\*|[a-z0-9][a-z0-9._-]{0,63}(:[a-z0-9][a-z0-9._-]{0,63})*(:\*)?)$ + RoleKey: + type: string + minLength: 1 + maxLength: 63 + pattern: ^[a-z][a-z0-9_-]{0,62}$ + CreateRole: + type: object + required: + - key + - name + - scope + - permissions + properties: + key: + $ref: '#/components/schemas/RoleKey' + name: + type: string + minLength: 1 + maxLength: 255 + scope: + type: string + enum: + - application + - workspace + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + additionalProperties: false + UpdateRole: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 255 + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + additionalProperties: false + Role: + type: object + required: + - key + - name + - scope + - permissions + - id + - built_in + - version + properties: + key: + $ref: '#/components/schemas/RoleKey' + name: + type: string + minLength: 1 + maxLength: 255 + scope: + type: string + enum: + - application + - workspace + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + id: + $ref: '#/components/schemas/UUID' + built_in: + type: boolean + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + StructuredRoles: + type: object + required: + - application + - workspaces + properties: + application: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/RoleKey' + workspaces: + type: object + additionalProperties: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/RoleKey' + additionalProperties: false + CreatePermissionGrant: + type: object + required: + - subject_type + - subject_id + - permission properties: - user_id: { $ref: "#/components/schemas/UUID" } - client_id: { $ref: "#/components/schemas/UUID" } - role_id: { $ref: "#/components/schemas/UUID" } - workspace_id: { $ref: "#/components/schemas/UUID" } + subject_type: + type: string + enum: + - user + - client + subject_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + permission: + $ref: '#/components/schemas/PermissionKey' + reason: + type: string + maxLength: 500 + additionalProperties: false + PermissionGrant: + type: object + required: + - subject_type + - subject_id + - permission + - id + - application_id + - canonical_scope + - status + - version + - created_at + properties: + subject_type: + type: string + enum: + - user + - client + subject_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + permission: + $ref: '#/components/schemas/PermissionKey' + reason: + type: string + maxLength: 500 + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + canonical_scope: + type: string + status: + type: string + enum: + - active + - revoked + version: + type: integer + format: int64 + minimum: 1 + created_at: + type: string + format: date-time + revoked_at: + type: string + format: date-time + nullable: true + additionalProperties: false + EffectiveAccess: + type: object + required: + - subject_type + - subject_id + - roles + - scopes + - provenance + properties: + subject_type: + type: string + enum: + - user + - client + subject_id: + $ref: '#/components/schemas/UUID' + roles: + $ref: '#/components/schemas/StructuredRoles' + scopes: + type: array + uniqueItems: true + items: + type: string + provenance: + type: array + items: + type: object + required: + - scope + - source + properties: + scope: + type: string + source: + type: string + enum: + - role_marker + - role + - direct + - workspace_owner + role_key: + $ref: '#/components/schemas/RoleKey' + grant_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + permission: + $ref: '#/components/schemas/PermissionKey' + additionalProperties: false additionalProperties: false OwnershipTransfer: type: object - required: [new_owner_user_id] + required: + - new_owner_user_id properties: - new_owner_user_id: { $ref: "#/components/schemas/UUID" } - previous_owner_disposition: { enum: [member, remove], default: member } + new_owner_user_id: + $ref: '#/components/schemas/UUID' + previous_owner_disposition: + enum: + - member + - remove + default: member additionalProperties: false OwnershipTransferResult: type: object - required: [workspace_id, owner_user_id, previous_owner_user_id, previous_owner_disposition] + required: + - workspace_id + - owner_user_id + - previous_owner_user_id + - previous_owner_disposition properties: - workspace_id: { $ref: "#/components/schemas/UUID" } - owner_user_id: { $ref: "#/components/schemas/UUID" } - previous_owner_user_id: { $ref: "#/components/schemas/UUID" } - previous_owner_disposition: { enum: [member, remove] } - OperatorPasswordLogin: + workspace_id: + $ref: '#/components/schemas/UUID' + owner_user_id: + $ref: '#/components/schemas/UUID' + previous_owner_user_id: + $ref: '#/components/schemas/UUID' + previous_owner_disposition: + enum: + - member + - remove + additionalProperties: false + ControlUserPasswordLogin: type: object - required: [email, password] + required: + - email + - password properties: - email: { type: string, format: email } - password: { type: string, minLength: 12, maxLength: 1024, writeOnly: true } + email: + type: string + format: email + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true additionalProperties: false - OperatorPasswordChange: + ControlUserPasswordChange: type: object - required: [new_password] + required: + - new_password properties: - current_password: { type: string, maxLength: 1024, writeOnly: true } - new_password: { type: string, minLength: 12, maxLength: 1024, writeOnly: true } + current_password: + type: string + maxLength: 1024 + writeOnly: true + new_password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true additionalProperties: false CreateEventType: type: object - required: [name, data_schema, example_subject, example_data] + required: + - name + - data_schema + - example_subject + - example_data properties: - name: { type: string, pattern: '^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$', maxLength: 160 } - description: { type: string, maxLength: 500 } - schema_version: { type: string, pattern: '^[1-9][0-9]*\.[0-9]+$', default: '1.0' } - data_schema: { type: object, additionalProperties: true, description: JSON Schema 2020-12 with an object root. } - example_subject: { type: string, minLength: 1, maxLength: 500 } - example_data: { type: object, additionalProperties: true, description: Must validate against data_schema. } + name: + type: string + pattern: ^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$ + maxLength: 160 + description: + type: string + maxLength: 500 + schema_version: + type: string + pattern: ^[1-9][0-9]*\.[0-9]+$ + default: '1.0' + data_schema: + type: object + additionalProperties: true + description: JSON Schema 2020-12 with an object root. + example_subject: + type: string + minLength: 1 + maxLength: 500 + example_data: + type: object + additionalProperties: true + description: Must validate against data_schema. additionalProperties: false UpdateEventType: type: object properties: - description: { type: string, maxLength: 500 } - schema_version: { type: string, pattern: '^[1-9][0-9]*\.[0-9]+$' } - data_schema: { type: object, additionalProperties: true } - example_subject: { type: string, minLength: 1, maxLength: 500 } - example_data: { type: object, additionalProperties: true } - status: { enum: [active, archived] } + description: + type: string + maxLength: 500 + schema_version: + type: string + pattern: ^[1-9][0-9]*\.[0-9]+$ + data_schema: + type: object + additionalProperties: true + example_subject: + type: string + minLength: 1 + maxLength: 500 + example_data: + type: object + additionalProperties: true + status: + enum: + - active + - archived additionalProperties: false EventEnvelope: type: object - required: [specversion, id, source, type, contract_source, time, application_id, schema_version, data] - properties: - specversion: { type: string, enum: ['1.0'] } - id: { $ref: "#/components/schemas/UUID" } - source: { type: string, format: uri } - type: { type: string } - contract_source: { type: string, enum: [platform93, application] } - time: { type: string, format: date-time } - application_id: { $ref: "#/components/schemas/UUID" } - schema_version: { type: string, pattern: '^[1-9][0-9]*\.[0-9]+$' } - subject: { type: string, nullable: true } - actor: { type: object, nullable: true, additionalProperties: true } - correlation_id: { type: string, nullable: true, format: uuid } - causation_id: { type: string, nullable: true, format: uuid } - data: { type: object, additionalProperties: true } + required: + - specversion + - id + - source + - type + - contract_source + - time + - application_id + - schema_version + - data + properties: + specversion: + type: string + enum: + - '1.0' + id: + $ref: '#/components/schemas/UUID' + source: + type: string + format: uri + type: + type: string + contract_source: + type: string + enum: + - platform93 + - application + time: + type: string + format: date-time + application_id: + $ref: '#/components/schemas/UUID' + schema_version: + type: string + pattern: ^[1-9][0-9]*\.[0-9]+$ + subject: + type: string + nullable: true + actor: + type: object + additionalProperties: true + nullable: true + correlation_id: + type: string + format: uuid + nullable: true + causation_id: + type: string + format: uuid + nullable: true + data: + type: object + additionalProperties: true additionalProperties: false EventTypeDefinition: type: object - required: [id, name, description, schema_version, data_schema, example_subject, example_data, example_event, source, status, version] - properties: - id: { $ref: "#/components/schemas/UUID" } - name: { type: string } - description: { type: string } - schema_version: { type: string } - data_schema: { type: object, additionalProperties: true } - example_subject: { type: string } - example_data: { type: object, additionalProperties: true } - example_event: { $ref: "#/components/schemas/EventEnvelope" } - source: { type: string, enum: [platform93, application] } - status: { type: string, enum: [active, archived] } - version: { type: integer, format: int64 } - event_count: { type: integer, format: int64 } - last_occurred_at: { type: string, nullable: true, format: date-time } - created_at: { type: string, format: date-time } - updated_at: { type: string, format: date-time } + required: + - id + - name + - description + - schema_version + - data_schema + - example_subject + - example_data + - example_event + - source + - status + - version + properties: + id: + $ref: '#/components/schemas/UUID' + name: + type: string + description: + type: string + schema_version: + type: string + data_schema: + type: object + additionalProperties: true + example_subject: + type: string + example_data: + type: object + additionalProperties: true + example_event: + $ref: '#/components/schemas/EventEnvelope' + source: + type: string + enum: + - platform93 + - application + status: + type: string + enum: + - active + - archived + version: + type: integer + format: int64 + event_count: + type: integer + format: int64 + last_occurred_at: + type: string + format: date-time + nullable: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false PublishCustomEvent: type: object - required: [type, subject, data] - properties: - type: { type: string, pattern: '^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$', maxLength: 160 } - subject: { type: string, minLength: 1, maxLength: 500 } - data: { type: object, additionalProperties: true } - correlation_id: { $ref: "#/components/schemas/UUID" } - causation_id: { $ref: "#/components/schemas/UUID" } - additionalProperties: false - CreatePersonalAPIKey: { type: object, properties: { label: { type: string, maxLength: 255 }, expires_in_days: { type: integer, minimum: 1, maximum: 366, default: 365 }, scopes: { type: array, items: { type: string } } } } - CreateFeature: { type: object, required: [key, name, value_type], properties: { key: { type: string, minLength: 1 }, name: { type: string, minLength: 1 }, value_type: { type: string, enum: [boolean, quantity, free_form] }, free_form_format: { type: string, enum: [text, csv, json], description: Required when value_type is free_form and forbidden otherwise. }, metadata: { type: object, additionalProperties: true } }, additionalProperties: false } - FeatureValue: { type: object, required: [feature_id], properties: { feature_id: { $ref: "#/components/schemas/UUID" }, boolean_value: { type: boolean }, quantity_value: { type: integer, minimum: 0 }, free_form_value: { description: "A string for text or CSV features, or any valid JSON value for JSON features." } }, additionalProperties: false } - CreateProduct: { type: object, required: [key, name], properties: { key: { type: string }, name: { type: string }, description: { type: string }, listable: { type: boolean, default: true }, status: { enum: [draft, active, archived] }, metadata: { type: object }, entitlement_config: { type: object, additionalProperties: true }, features: { type: array, items: { $ref: "#/components/schemas/FeatureValue" } } } } - UpdateProduct: { type: object, properties: { name: { type: string }, description: { type: string }, listable: { type: boolean }, status: { enum: [draft, active, archived] }, metadata: { type: object }, entitlement_config: { type: object, additionalProperties: true }, features: { type: array, items: { $ref: "#/components/schemas/FeatureValue" } } }, additionalProperties: false } - CreatePrice: { type: object, required: [key, mode, amount_minor, currency], properties: { key: { type: string }, mode: { enum: [recurring, one_time, local] }, amount_minor: { type: integer, minimum: 0 }, currency: { type: string, minLength: 3, maxLength: 3 }, currency_exponent: { type: integer, default: 2 }, interval_unit: { enum: [day, week, month, year] }, interval_count: { type: integer, minimum: 1 }, validity_seconds: { type: integer, minimum: 1 }, grace_seconds: { type: integer, minimum: 0 }, tax_behavior: { enum: [inclusive, exclusive, unspecified] }, checkout_config: { type: object }, entitlement_config: { type: object, additionalProperties: true }, features: { type: array, items: { $ref: "#/components/schemas/FeatureValue" } } } } - LocalCheckout: { type: object, required: [price_id], properties: { price_id: { $ref: "#/components/schemas/UUID" }, subject_type: { enum: [user, workspace] }, subject_id: { $ref: "#/components/schemas/UUID" }, address_id: { $ref: "#/components/schemas/UUID" }, local_reference: { type: string } } } - CreateBillingProvider: { type: object, required: [provider, secret], properties: { provider: { enum: [stripe] }, secret: { type: string, writeOnly: true }, webhook_secret: { type: string, writeOnly: true }, api_version: { enum: [2026-04-22.dahlia] }, inheritable: { type: boolean, default: false } } } - CreateCheckout: { type: object, required: [price_id, success_uri, cancel_uri], properties: { price_id: { $ref: "#/components/schemas/UUID" }, provider_id: { $ref: "#/components/schemas/UUID", description: Optional provider pin; omission resolves the effective application, organization, or installation provider. }, subject_type: { enum: [user, workspace] }, subject_id: { $ref: "#/components/schemas/UUID" }, payment_methods: { type: array, items: { enum: [card, twint] } }, success_uri: { type: string, format: uri }, cancel_uri: { type: string, format: uri } } } + required: + - type + - subject + - data + properties: + type: + type: string + pattern: ^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$ + maxLength: 160 + subject: + type: string + minLength: 1 + maxLength: 500 + data: + type: object + additionalProperties: true + correlation_id: + $ref: '#/components/schemas/UUID' + causation_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + CreatePersonalAPIKey: + type: object + properties: + label: + type: string + maxLength: 255 + expires_in_days: + type: integer + minimum: 1 + maximum: 366 + default: 365 + scopes: + type: array + items: + type: string + additionalProperties: false + CreateFeature: + type: object + required: + - key + - name + - value_type + properties: + key: + type: string + minLength: 1 + name: + type: string + minLength: 1 + value_type: + type: string + enum: + - boolean + - quantity + - free_form + free_form_format: + type: string + enum: + - text + - csv + - json + description: Required when value_type is free_form and forbidden otherwise. + metadata: + type: object + additionalProperties: true + additionalProperties: false + FeatureValue: + type: object + required: + - feature_id + properties: + feature_id: + $ref: '#/components/schemas/UUID' + boolean_value: + type: boolean + quantity_value: + type: integer + minimum: 0 + free_form_value: + description: A string for text or CSV features, or any valid JSON value for JSON features. + additionalProperties: false + CreateProduct: + type: object + required: + - key + - name + properties: + key: + type: string + name: + type: string + description: + type: string + listable: + type: boolean + default: true + status: + enum: + - draft + - active + - archived + metadata: + type: object + entitlement_config: + type: object + additionalProperties: true + features: + type: array + items: + $ref: '#/components/schemas/FeatureValue' + additionalProperties: false + UpdateProduct: + type: object + properties: + name: + type: string + description: + type: string + listable: + type: boolean + status: + enum: + - draft + - active + - archived + metadata: + type: object + entitlement_config: + type: object + additionalProperties: true + features: + type: array + items: + $ref: '#/components/schemas/FeatureValue' + additionalProperties: false + CreatePrice: + type: object + required: + - key + - mode + - amount_minor + - currency + properties: + key: + type: string + mode: + enum: + - recurring + - one_time + - local + amount_minor: + type: integer + minimum: 0 + currency: + type: string + minLength: 3 + maxLength: 3 + currency_exponent: + type: integer + default: 2 + interval_unit: + enum: + - day + - week + - month + - year + interval_count: + type: integer + minimum: 1 + validity_seconds: + type: integer + minimum: 1 + grace_seconds: + type: integer + minimum: 0 + tax_behavior: + enum: + - inclusive + - exclusive + - unspecified + checkout_config: + type: object + entitlement_config: + type: object + additionalProperties: true + features: + type: array + items: + $ref: '#/components/schemas/FeatureValue' + additionalProperties: false + LocalCheckout: + type: object + required: + - price_id + properties: + price_id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + address_id: + $ref: '#/components/schemas/UUID' + external_reference: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false + CreateBillingProvider: + type: object + required: + - provider + - secret + properties: + provider: + enum: + - stripe + secret: + type: string + writeOnly: true + webhook_secret: + type: string + writeOnly: true + api_version: + enum: + - 2026-04-22.dahlia + inheritable: + type: boolean + default: false + additionalProperties: false + CreateCheckout: + type: object + required: + - price_id + - success_uri + - cancel_uri + properties: + price_id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + description: Optional provider pin; omission resolves the effective application + organization: null + or installation provider.: null + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + payment_methods: + type: array + items: + enum: + - card + - twint + success_uri: + type: string + format: uri + cancel_uri: + type: string + format: uri + external_reference: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false diff --git a/api/openapi/platform93.yaml b/api/openapi/platform93.yaml index a801f2f..58bf69c 100644 --- a/api/openapi/platform93.yaml +++ b/api/openapi/platform93.yaml @@ -2,1367 +2,14910 @@ openapi: 3.1.0 info: title: Platform93 API version: 0.1.0 - license: { name: Apache-2.0, identifier: Apache-2.0 } + license: + name: Apache-2.0 + identifier: Apache-2.0 description: Public contract for fresh Platform93 installations. -servers: [{ url: / }] -security: [{ bearerAuth: [] }] +servers: + - url: / +security: + - bearerAuth: [] tags: - - { name: System, description: Process health and build information. } - - { name: Setup, description: One-time installation bootstrap. } - - { name: Control, description: "Installation operators, organizations, and applications." } - - { name: Management, description: "Machine-only installation provisioning and organization governance." } - - { name: Identity, description: Application-user authentication and profiles. } - - { name: Catalog, description: "Features, products, and immutable prices." } - - { name: Entitlements, description: Grants and local entitlement requests. } - - { name: Billing, description: Provider connections and billing lifecycle. } - - { name: Storage, description: Optional tenant-aware S3-compatible object storage. } - - { name: Events, description: "Domain events, outgoing webhooks, and audit." } + - name: System + description: Process health and build information. + - name: Setup + description: One-time installation bootstrap. + - name: Control + description: Platform users, organizations, and applications. + - name: Management + description: Machine-only installation provisioning and organization governance. + - name: Identity + description: Application-user authentication and profiles. + - name: Catalog + description: Features, products, and immutable prices. + - name: Entitlements + description: Grants and local entitlement requests. + - name: Billing + description: Provider connections and billing lifecycle. + - name: Storage + description: Optional tenant-aware S3-compatible object storage. + - name: Events + description: Domain events, outgoing webhooks, and audit. paths: /healthz: - get: { operationId: health, tags: [System], security: [], responses: { "200": { description: Process is alive } } } + get: + operationId: health + tags: + - System + security: [] + responses: + '200': + description: Process is alive + content: + application/json: + schema: + $ref: '#/components/schemas/HealthStatus' /readyz: - get: { operationId: readiness, tags: [System], security: [], responses: { "200": { description: Process is ready }, "503": { $ref: "#/components/responses/Problem" } } } + get: + operationId: readiness + tags: + - System + security: [] + responses: + '200': + description: Process is ready + content: + application/json: + schema: + $ref: '#/components/schemas/HealthStatus' + '503': + $ref: '#/components/responses/Problem' /version: - get: { operationId: version, tags: [System], security: [], responses: { "200": { description: Build information, content: { application/json: { schema: { type: object } } } } } } + get: + operationId: version + tags: + - System + security: [] + responses: + '200': + description: Build information + content: + application/json: + schema: + $ref: '#/components/schemas/VersionInfo' /v1/setup/status: - get: { operationId: setupStatus, tags: [Setup], security: [], responses: { "200": { description: Setup and operator login availability, content: { application/json: { schema: { type: object, required: [available, operator_email_login_available], properties: { available: { type: boolean }, operator_email_login_available: { type: boolean } } } } } } } } + get: + operationId: setupStatus + tags: + - Setup + security: [] + responses: + '200': + description: Setup and Platform user login availability + content: + application/json: + schema: + $ref: '#/components/schemas/SetupStatus' /v1/setup/bootstrap: post: operationId: bootstrap - tags: [Setup] + tags: + - Setup security: [] - requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/BootstrapRequest" } } } } - responses: { "201": { description: Setup-only operator session }, "401": { $ref: "#/components/responses/Problem" } } + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BootstrapRequest' + responses: + '201': + description: Setup-only Platform user session + content: + application/json: + schema: + $ref: '#/components/schemas/SetupSession' + '401': + $ref: '#/components/responses/Problem' /v1/setup/complete: - post: { operationId: completeSetup, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Setup completed }, "409": { $ref: "#/components/responses/Problem" } } } + post: + operationId: completeSetup + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/CompleteSetup' + responses: + '200': + description: Setup completed + content: + application/json: + schema: + $ref: '#/components/schemas/SetupCompletion' + '409': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' /v1/setup/notification-providers: - post: { operationId: createSetupNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: Installation SMTP provider stored } } } + post: + operationId: createSetupNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: Installation SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/auth/email/start: - post: { operationId: startOperatorEmailLogin, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [email], properties: { email: { type: string, format: email }, delivery: { enum: [code, link, both] } } } } } }, responses: { "202": { description: Enumeration-safe operator challenge accepted } } } + post: + operationId: startControlUserEmailLogin + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlEmailStart' + responses: + '202': + description: Enumeration-safe Platform user challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/control/auth/email/verify: - post: { operationId: verifyOperatorEmailLogin, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/EmailVerify" } } } }, responses: { "200": { description: Operator cookie session created } } } + post: + operationId: verifyControlUserEmailLogin + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailVerify' + responses: + '200': + description: Platform user cookie session created + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' /v1/control/auth/password: - post: { operationId: loginOperatorWithPassword, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/OperatorPasswordLogin" } } } }, responses: { "200": { description: Operator cookie session created }, "401": { $ref: "#/components/responses/Problem" } } } - put: { operationId: changeOperatorPassword, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/OperatorPasswordChange" } } } }, responses: { "204": { description: Password stored and other operator sessions revoked }, "409": { $ref: "#/components/responses/Problem" } } } + post: + operationId: loginControlUserWithPassword + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserPasswordLogin' + responses: + '200': + description: Platform user cookie session created + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '401': + $ref: '#/components/responses/Problem' + put: + operationId: changeControlUserPassword + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserPasswordChange' + responses: + '204': + description: Password stored and other Platform user sessions revoked + '409': + $ref: '#/components/responses/Problem' /v1/control/auth/me: - get: { operationId: getOperatorAccount, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Current operator profile and sign-in methods } } } - patch: { operationId: updateOperatorAccount, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [display_name], properties: { display_name: { type: string, minLength: 1, maxLength: 200 } }, additionalProperties: false } } } }, responses: { "204": { description: Operator profile updated } } } + get: + operationId: getControlUserAccount + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Current Platform user profile and sign-in methods + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserAccount' + patch: + operationId: updateControlUserAccount + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateControlUserAccount' + responses: + '204': + description: Platform user profile updated /v1/control/auth/logout: - post: { operationId: logoutOperator, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Operator session revoked } } } + post: + operationId: logoutControlUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Platform user session revoked /v1/control/auth/token/refresh: - post: { operationId: refreshOperatorSession, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Operator session credential rotated } } } + post: + operationId: refreshControlUserSession + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Platform user session credential rotated + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' /v1/control/auth/sessions: - get: { operationId: listOperatorSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listControlUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listControlUserSessions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SessionPage' /v1/control/auth/sessions/{session_id}: - parameters: [{ name: session_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeOperatorSession, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Operator session revoked } } } + parameters: + - name: session_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeControlUserSession + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Platform user session revoked /v1/control/auth/logout-all: - post: { operationId: logoutAllOperatorSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: All operator sessions revoked } } } - /v1/control/organization-invitations/accept: - post: { operationId: acceptOrganizationInvitation, tags: [Control], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/AcceptOrganizationInvitation" } } } }, responses: { "200": { description: Invitation accepted and operator cookie issued }, "401": { $ref: "#/components/responses/Problem" } } } + post: + operationId: logoutAllControlUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: All Platform user sessions revoked + /v1/control/auth/methods: + get: + operationId: getControlAuthMethods + tags: + - Identity + security: [] + responses: + '200': + description: Available Platform user sign-in methods + content: + application/json: + schema: + $ref: '#/components/schemas/ControlAuthMethods' + /v1/control/auth/providers/{provider}/start: + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + post: + operationId: startControlExternalLogin + tags: + - Identity + security: [] + responses: + '201': + description: External Platform sign-in started + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/control/auth/providers/{provider}/link: + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + post: + operationId: linkControlExternalIdentity + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '201': + description: External Platform identity link started + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/control/auth/identities/{identity_id}: + parameters: + - name: identity_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: unlinkControlExternalIdentity + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: External Platform identity unlinked + '409': + $ref: '#/components/responses/Problem' + /v1/control/invitations/accept: + post: + operationId: acceptControlUserInvitation + tags: + - Control + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AcceptControlUserInvitation' + responses: + '200': + description: Invitation accepted and Platform user cookie issued + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '401': + $ref: '#/components/responses/Problem' + /v1/control/invitations/providers/{provider}/start: + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + post: + operationId: startControlInvitationExternalLogin + tags: + - Control + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ControlInvitationProviderStart' + responses: + '201': + description: Provider-backed invitation acceptance started + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' /v1/control/installation/notification-providers: - get: { operationId: listInstallationNotificationProviders, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: Installation SMTP provider stored } } } + get: + operationId: listInstallationNotificationProviders + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationNotificationProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProviderPage' + post: + operationId: createInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: Installation SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/installation/notification-providers/{provider_id}: - parameters: [{ name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation notification provider metadata }, "404": { $ref: "#/components/responses/Problem" } } } - patch: { operationId: updateInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Installation notification provider updated }, "404": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation notification provider disabled }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation notification provider metadata + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + '404': + $ref: '#/components/responses/Problem' + patch: + operationId: updateInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateSMTPProvider' + responses: + '200': + description: Installation notification provider updated + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + '404': + $ref: '#/components/responses/Problem' + delete: + operationId: disableInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation notification provider disabled + '404': + $ref: '#/components/responses/Problem' /v1/control/installation/notification-providers/{provider_id}/verify: - parameters: [{ name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: SMTP connectivity and credentials verified }, "502": { $ref: "#/components/responses/Problem" } } } + parameters: + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: SMTP connectivity and credentials verified + '502': + $ref: '#/components/responses/Problem' /v1/control/installation/notification-providers/{provider_id}/test: - parameters: [{ name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testInstallationNotificationProvider, tags: [Setup], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Installation SMTP test queued }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testInstallationNotificationProvider + tags: + - Setup + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TestNotificationProvider' + responses: + '202': + description: Installation SMTP test queued + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationQueued' + '404': + $ref: '#/components/responses/Problem' /v1/control/installation/auth/providers: - get: { operationId: listInstallationAuthProviders, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listInstallationAuthProviders + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/control/installation/auth/providers/{provider}: - parameters: [{ name: provider, in: path, required: true, schema: { type: string, enum: [google, apple] } }] - put: { operationId: configureInstallationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Installation authentication provider configured } } } - patch: { operationId: updateInstallationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/ProviderInheritance" }, responses: { "204": { description: Installation authentication provider inheritance updated }, "404": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableInstallationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation authentication provider disabled } } } + parameters: + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + put: + operationId: configureInstallationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Installation authentication provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' + patch: + operationId: updateInstallationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateInstallationAuthProvider' + responses: + '204': + description: Installation authentication provider settings updated + '404': + $ref: '#/components/responses/Problem' + delete: + operationId: disableInstallationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation authentication provider disabled /v1/control/installation/billing/providers: - get: { operationId: listInstallationBillingProviders, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateBillingProvider" } } } }, responses: { "201": { description: Installation billing provider configured } } } + get: + operationId: listInstallationBillingProviders + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationBillingProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderPage' + post: + operationId: createInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBillingProvider' + responses: + '201': + description: Installation billing provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' /v1/control/installation/billing/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free installation billing provider } } } - patch: { operationId: updateInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Installation billing provider updated } } } - delete: { operationId: disableInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation billing provider disabled } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free installation billing provider + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' + patch: + operationId: updateInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProvider' + responses: + '204': + description: Installation billing provider updated + delete: + operationId: disableInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation billing provider disabled /v1/control/installation/billing/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyInstallationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation billing provider credentials verified } } } - /v1/control/installation/operators: - get: { operationId: listInstallationOperators, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationOperator, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Installation operator and role created } } } - /v1/control/installation/operators/{operator_id}: - parameters: [{ name: operator_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateInstallationOperator, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Installation role updated } } } - delete: { operationId: deleteInstallationOperator, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation role removed and sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyInstallationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation billing provider credentials verified + /v1/control/installation/users: + get: + operationId: listInstallationControlUsers + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationControlUsers response. + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserPage' + /v1/control/installation/users/{control_user_id}: + parameters: + - name: control_user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateInstallationControlUser + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MembershipRole' + responses: + '204': + description: Installation role updated + delete: + operationId: deleteInstallationControlUser + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation role removed and sessions revoked + /v1/control/installation/invitations: + get: + operationId: listInstallationControlUserInvitations + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationControlUserInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitationPage' + post: + operationId: createInstallationControlUserInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateControlUserInvitation' + responses: + '201': + description: Platform user invitation created and credential returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' + /v1/control/installation/invitations/{invitation_id}/resend: + parameters: + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendInstallationControlUserInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateControlInvitationMethod' + responses: + '200': + description: Platform user invitation rotated + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' + /v1/control/installation/invitations/{invitation_id}: + parameters: + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeInstallationControlUserInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Platform user invitation revoked + /v1/control/installation/auth-policy: + get: + operationId: getControlAuthPolicy + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Platform authentication policy + content: + application/json: + schema: + $ref: '#/components/schemas/ControlAuthPolicy' + patch: + operationId: updateControlAuthPolicy + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateControlAuthPolicy' + responses: + '204': + description: Platform authentication policy updated + '409': + $ref: '#/components/responses/Problem' /v1/control/installation/signing-keys: - get: { operationId: listSigningKeys, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listSigningKeys + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listSigningKeys response. + content: + application/json: + schema: + $ref: '#/components/schemas/SigningKeyPage' /v1/control/installation/signing-keys/rotate: - post: { operationId: rotateSigningKey, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "201": { description: New installation signing key activated } } } + post: + operationId: rotateSigningKey + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '201': + description: New installation signing key activated + content: + application/json: + schema: + $ref: '#/components/schemas/SigningKey' /v1/control/installation/management-api: - get: { operationId: getManagementAPIStatus, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Management API installation status, content: { application/json: { schema: { $ref: "#/components/schemas/ManagementAPIStatus" } } } } } } - patch: { operationId: updateManagementAPIStatus, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [enabled], properties: { enabled: { type: boolean } }, additionalProperties: false } } } }, responses: { "200": { description: Management API status updated } } } + get: + operationId: getManagementAPIStatus + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Management API installation status + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementAPIStatus' + patch: + operationId: updateManagementAPIStatus + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateManagementAPI' + responses: + '200': + description: Management API status updated + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementAPIStatus' /v1/control/installation/management-clients: - get: { operationId: listManagementClients, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createManagementClient, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateManagementClient" } } } }, responses: { "201": { description: Management client created and secret returned once }, "409": { $ref: "#/components/responses/Problem" } } } + get: + operationId: listManagementClients + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listManagementClients response. + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementClientPage' + post: + operationId: createManagementClient + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateManagementClient' + responses: + '201': + description: Management client created and secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ManagementClient' + '409': + $ref: '#/components/responses/Problem' /v1/control/installation/management-clients/{management_client_id}/rotate-secret: - parameters: [{ name: management_client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: rotateManagementClientSecret, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Management client secret rotated and returned once } } } + parameters: + - name: management_client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: rotateManagementClientSecret + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Management client secret rotated and returned once + content: + application/json: + schema: + $ref: '#/components/schemas/SecretCredential' /v1/control/installation/management-clients/{management_client_id}: - parameters: [{ name: management_client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: disableManagementClient, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Management client disabled and all of its tokens invalidated } } } + parameters: + - name: management_client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: disableManagementClient + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Management client disabled and all of its tokens invalidated /v1/control/installation/organizations/{organization_id}/policy: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - put: { operationId: updateOrganizationPolicy, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateOrganizationPolicy" } } } }, responses: { "204": { description: Installation-owned organization policy updated }, "412": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + put: + operationId: updateOrganizationPolicy + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOrganizationPolicy' + responses: + '204': + description: Installation-owned organization policy updated + '412': + $ref: '#/components/responses/Problem' /v1/control/organizations: - get: { operationId: listOrganizations, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { description: Accessible organizations and the current installation role, content: { application/json: { schema: { $ref: "#/components/schemas/OrganizationPage" } } } } } } - post: { operationId: createOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Organization created }, "409": { $ref: "#/components/responses/Problem" } } } + get: + operationId: listOrganizations + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Accessible organizations and the current installation role + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPage' + post: + operationId: createOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Organization created + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' + '409': + $ref: '#/components/responses/Problem' /v1/control/organizations/{organization_id}/applications: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listApplications, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Application created } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listApplications + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Successful listApplications response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationPage' + post: + operationId: createApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Application created + content: + application/json: + schema: + $ref: '#/components/schemas/Application' /v1/control/organizations/{organization_id}/applications/{application_resource_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Application renamed }, "412": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: retireApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application retired and live credentials revoked } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Application renamed + '412': + $ref: '#/components/responses/Problem' + delete: + operationId: retireApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application retired and live credentials revoked /v1/control/organizations/{organization_id}/applications/{application_resource_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: restoreApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application restored without restoring revoked credentials } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: restoreApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application restored without restoring revoked credentials /v1/control/organizations/{organization_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: getOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Organization details } } } - patch: { operationId: updateOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Organization renamed }, "412": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: retireOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization and active descendants retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: getOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Organization details + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' + patch: + operationId: updateOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Organization renamed + '412': + $ref: '#/components/responses/Problem' + delete: + operationId: retireOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization and active descendants retired /v1/control/organizations/{organization_id}/policy: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: getOrganizationPolicy, tags: [Management], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Organization policy and current usage, content: { application/json: { schema: { $ref: "#/components/schemas/OrganizationPolicy" } } } } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: getOrganizationPolicy + tags: + - Management + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Organization policy and current usage + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPolicy' /v1/control/organizations/{organization_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - post: { operationId: restoreOrganization, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization restored; descendants remain retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + post: + operationId: restoreOrganization + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization restored; descendants remain retired /v1/control/organizations/{organization_id}/members: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationMembers, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationMembers + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationMembers response. + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationMemberPage' /v1/control/organizations/{organization_id}/members/{member_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: member_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateOrganizationMember, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Organization role updated } } } - delete: { operationId: deleteOrganizationMember, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization member removed } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: member_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateOrganizationMember + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MembershipRole' + responses: + '204': + description: Organization role updated + delete: + operationId: deleteOrganizationMember + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization member removed /v1/control/organizations/{organization_id}/invitations: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationInvitations, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Invitation queued and credential returned once } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationInvitations + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitationPage' + post: + operationId: createOrganizationInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateControlUserInvitation' + responses: + '201': + description: Invitation queued and credential returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' /v1/control/organizations/{organization_id}/invitations/{invitation_id}/resend: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: resendOrganizationInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Invitation credential rotated and delivery queued } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendOrganizationInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Invitation credential rotated and delivery queued + content: + application/json: + schema: + $ref: '#/components/schemas/ControlUserInvitation' /v1/control/organizations/{organization_id}/invitations/{invitation_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeOrganizationInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Pending invitation revoked } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeOrganizationInvitation + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Pending invitation revoked /v1/control/organizations/{organization_id}/audit-logs: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationAuditLogs, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationAuditLogs + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationAuditLogs response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuditRecordPage' /v1/control/organizations/{organization_id}/auth/providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationAuthProviders, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationAuthProviders + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/control/organizations/{organization_id}/auth/providers/{provider}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider, in: path, required: true, schema: { type: string, enum: [google, apple] } }] - put: { operationId: configureOrganizationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Organization authentication provider configured } } } - patch: { operationId: updateOrganizationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/ProviderInheritance" }, responses: { "204": { description: Organization authentication provider inheritance updated }, "404": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableOrganizationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization authentication provider disabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + put: + operationId: configureOrganizationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Organization authentication provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' + patch: + operationId: updateOrganizationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/ProviderInheritance' + responses: + '204': + description: Organization authentication provider inheritance updated + '404': + $ref: '#/components/responses/Problem' + delete: + operationId: disableOrganizationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization authentication provider disabled /v1/control/organizations/{organization_id}/notification-providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationNotificationProviders, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: Organization SMTP provider stored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationNotificationProviders + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationNotificationProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProviderPage' + post: + operationId: createOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: Organization SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/organizations/{organization_id}/notification-providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Redacted organization SMTP provider } } } - patch: { operationId: updateOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Organization SMTP provider updated } } } - delete: { operationId: disableOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization SMTP provider disabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Redacted organization SMTP provider + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + patch: + operationId: updateOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateSMTPProvider' + responses: + '200': + description: Organization SMTP provider updated + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + delete: + operationId: disableOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization SMTP provider disabled /v1/control/organizations/{organization_id}/notification-providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization SMTP provider verified } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization SMTP provider verified /v1/control/organizations/{organization_id}/notification-providers/{provider_id}/test: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testOrganizationNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Organization SMTP test queued } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testOrganizationNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TestNotificationProvider' + responses: + '202': + description: Organization SMTP test queued + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationQueued' /v1/control/organizations/{organization_id}/billing/providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationBillingProviders, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateBillingProvider" } } } }, responses: { "201": { description: Organization billing provider configured } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationBillingProviders + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationBillingProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderPage' + post: + operationId: createOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBillingProvider' + responses: + '201': + description: Organization billing provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' /v1/control/organizations/{organization_id}/billing/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free organization billing provider } } } - patch: { operationId: updateOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Organization billing provider updated } } } - delete: { operationId: disableOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization billing provider disabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free organization billing provider + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' + patch: + operationId: updateOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProvider' + responses: + '204': + description: Organization billing provider updated + delete: + operationId: disableOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization billing provider disabled /v1/control/organizations/{organization_id}/billing/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyOrganizationBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Organization billing provider credentials verified } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyOrganizationBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Organization billing provider credentials verified /v1/applications/{application_id}/public-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: publicConfig, tags: [Control], security: [], responses: { "200": { description: Secret-free runtime configuration, content: { application/json: { schema: { $ref: "#/components/schemas/RuntimeConfig" } } } } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: publicConfig + tags: + - Control + security: [] + responses: + '200': + description: Secret-free runtime configuration + content: + application/json: + schema: + $ref: '#/components/schemas/RuntimeConfig' /v1/control/applications/{application_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getApplication, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Application details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getApplication + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Application details + content: + application/json: + schema: + $ref: '#/components/schemas/Application' /v1/control/applications/{application_id}/statistics: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getApplicationStatistics, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Application identity, catalog, billing, and delivery counts" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getApplicationStatistics + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Application identity, catalog, billing, and delivery counts + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationStatistics' /v1/control/applications/{application_id}/public-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - patch: { operationId: updatePublicApplicationConfig, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/PublicApplicationConfig" }, responses: { "204": { description: Explicitly public runtime configuration replaced }, "412": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + patch: + operationId: updatePublicApplicationConfig + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/PublicApplicationConfig' + responses: + '204': + description: Explicitly public runtime configuration replaced + '412': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/internal-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - patch: { operationId: updateInternalApplicationConfig, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/InternalApplicationConfig" }, responses: { "204": { description: Internal application policy updated and disabled credentials revoked }, "412": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + patch: + operationId: updateInternalApplicationConfig + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/InternalApplicationConfig' + responses: + '204': + description: Internal application policy updated and disabled credentials revoked + '412': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/auth-config: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - patch: { operationId: updateAuthConfig, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/ApplicationAuthConfig" }, responses: { "204": { description: Authentication configuration and PKCE application redirects updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + patch: + operationId: updateAuthConfig + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/ApplicationAuthConfig' + responses: + '204': + description: Authentication configuration and PKCE application redirects updated /v1/control/applications/{application_id}/auth/providers/google: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - put: { operationId: configureGoogleProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Google client configured and callback URI returned } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + put: + operationId: configureGoogleProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Google client configured and callback URI returned + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' /v1/control/applications/{application_id}/auth/providers/apple: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - put: { operationId: configureAppleProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Apple client configured and callback URI returned } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + put: + operationId: configureAppleProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ConfigureAuthProvider' + responses: + '200': + description: Apple client configured and callback URI returned + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProvider' /v1/control/applications/{application_id}/auth/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationAuthProviders, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationAuthProviders + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/control/applications/{application_id}/auth/providers/{provider}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider, in: path, required: true, schema: { type: string, enum: [google, apple] } }] - delete: { operationId: disableApplicationAuthProvider, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application authentication provider disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider + in: path + required: true + schema: + type: string + enum: + - google + - apple + delete: + operationId: disableApplicationAuthProvider + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application authentication provider disabled /v1/control/applications/{application_id}/domains: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationDomains, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createApplicationDomain, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Domain added and DNS proof returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationDomains + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationDomains response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationDomainPage' + post: + operationId: createApplicationDomain + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateApplicationDomain' + responses: + '201': + description: Domain added and DNS proof returned once + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationDomain' /v1/control/applications/{application_id}/domains/{domain_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: domain_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: deleteApplicationDomain, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Domain removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: domain_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: deleteApplicationDomain + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Domain removed /v1/control/applications/{application_id}/domains/{domain_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: domain_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyApplicationDomain, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: DNS ownership verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: domain_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyApplicationDomain + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: DNS ownership verified /v1/control/applications/{application_id}/clients: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listClients, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createClient, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Client created and secret returned once when applicable } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listClients + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listClients response. + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthClientPage' + post: + operationId: createClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateClient' + responses: + '201': + description: Client created and secret returned once when applicable + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthClient' /v1/control/applications/{application_id}/clients/{client_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: client_id, in: path, required: true, schema: { type: string } }] - patch: { operationId: updateClient, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Client updated } } } - delete: { operationId: disableClient, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Client and active OAuth grants disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: client_id + in: path + required: true + schema: + type: string + get: + operationId: getClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Client detail + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthClient' + patch: + operationId: updateClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateClient' + responses: + '204': + description: Client updated + delete: + operationId: disableClient + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Client and active OAuth grants disabled /v1/control/applications/{application_id}/clients/{client_id}/rotate-secret: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: client_id, in: path, required: true, schema: { type: string } }] - post: { operationId: rotateClientSecret, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Replacement client secret returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: client_id + in: path + required: true + schema: + type: string + post: + operationId: rotateClientSecret + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Replacement client secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/SecretCredential' /v1/control/applications/{application_id}/roles: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listRoles, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Role created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listRoles + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listRoles response. + content: + application/json: + schema: + $ref: '#/components/schemas/RolePage' + post: + operationId: createRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateRole' + responses: + '201': + description: Role created + content: + application/json: + schema: + $ref: '#/components/schemas/Role' + '422': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/roles/{role_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: role_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Role details }, "404": { $ref: "#/components/responses/Problem" } } } - patch: { operationId: updateRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Role updated }, "409": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: deleteRole, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Unassigned custom role deleted }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: role_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Role details + content: + application/json: + schema: + $ref: '#/components/schemas/Role' + '404': + $ref: '#/components/responses/Problem' + patch: + operationId: updateRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateRole' + responses: + '204': + description: Role updated + '409': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' + delete: + operationId: deleteRole + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Unassigned custom role deleted + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/workspaces: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWorkspaces, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listWorkspaces + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWorkspaces response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspacePage' + post: + operationId: createWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkspace' + responses: + '201': + description: Workspace created + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' /v1/control/applications/{application_id}/workspaces/{workspace_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Workspace details } } } - patch: { operationId: updateWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace updated } } } - delete: { operationId: deleteWorkspace, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Workspace retired and memberships removed }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Workspace details + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' + patch: + operationId: updateWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateWorkspace' + responses: + '204': + description: Workspace updated + delete: + operationId: deleteWorkspace + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Workspace retired and memberships removed + '404': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/workspaces/{workspace_id}/owner-transfer: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: recoverWorkspaceOwnership, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/OwnershipTransfer" }, responses: { "200": { $ref: "#/components/responses/OwnershipTransferResult" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: recoverWorkspaceOwnership + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/OwnershipTransfer' + responses: + '200': + $ref: '#/components/responses/OwnershipTransferResult' /v1/control/applications/{application_id}/workspaces/{workspace_id}/members: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listWorkspaceMembers, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listWorkspaceMembers + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWorkspaceMembers response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMemberPage' /v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - put: { operationId: replaceWorkspaceMemberRoles, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Workspace member roles replaced atomically } } } - delete: { operationId: deleteWorkspaceMember, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Workspace membership removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + put: + operationId: replaceWorkspaceMemberRoles + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ReplaceWorkspaceMemberRoles' + responses: + '200': + description: Workspace member roles replaced atomically + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMember' + delete: + operationId: deleteWorkspaceMember + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Workspace membership removed /v1/control/applications/{application_id}/role-assignments: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listRoleAssignments, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createRoleAssignment, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/RoleAssignment" }, responses: { "201": { description: User or machine-client role assignment created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listRoleAssignments + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listRoleAssignments response. + content: + application/json: + schema: + $ref: '#/components/schemas/RoleAssignmentPage' + post: + operationId: createRoleAssignment + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/RoleAssignment' + responses: + '201': + description: User or machine-client role assignment created + content: + application/json: + schema: + $ref: '#/components/schemas/RoleAssignmentRecord' /v1/control/applications/{application_id}/role-assignments/{assignment_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: assignment_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: deleteRoleAssignment, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Role assignment deleted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: assignment_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: deleteRoleAssignment + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Role assignment deleted + /v1/control/applications/{application_id}/permission-grants: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/OptionalPermissionSubjectType' + - $ref: '#/components/parameters/OptionalPermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + - $ref: '#/components/parameters/PermissionGrantStatus' + get: + operationId: listControlPermissionGrants + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listControlPermissionGrants response. + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrantPage' + post: + operationId: createControlPermissionGrant + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/PermissionGrantBody' + responses: + '201': + description: Direct permission grant created + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + '422': + $ref: '#/components/responses/Problem' + /v1/control/applications/{application_id}/permission-grants/effective: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PermissionSubjectType' + - $ref: '#/components/parameters/PermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + get: + operationId: getControlEffectiveAccess + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Effective roles and scopes + content: + application/json: + schema: + $ref: '#/components/schemas/EffectiveAccess' + /v1/control/applications/{application_id}/permission-grants/{grant_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: grant_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getControlPermissionGrant + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Direct permission grant + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + delete: + operationId: revokeControlPermissionGrant + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + responses: + '204': + description: Direct permission grant revoked + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/delegations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listDelegations, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createDelegation, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Short-lived one-time delegation exchange credential } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listDelegations + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listDelegations response. + content: + application/json: + schema: + $ref: '#/components/schemas/DelegationPage' + post: + operationId: createDelegation + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateDelegation' + responses: + '201': + description: Short-lived one-time delegation exchange credential + content: + application/json: + schema: + $ref: '#/components/schemas/Delegation' /v1/control/applications/{application_id}/delegations/{delegation_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delegation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getDelegation, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Delegation details and lifecycle state } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delegation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getDelegation + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Delegation details and lifecycle state + content: + application/json: + schema: + $ref: '#/components/schemas/Delegation' /v1/applications/{application_id}/delegations/{delegation_id}/exchange: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delegation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: exchangeDelegation, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Non-refreshable delegated access token } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delegation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: exchangeDelegation + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExchangeDelegation' + responses: + '200': + description: Non-refreshable delegated access token + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + /v1/applications/{application_id}/notifications: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequiredIdempotencyKey' + post: + operationId: sendMachineNotification + tags: + - Events + description: Machine-client-only template notification delivery. + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/QueueNotification' + responses: + '202': + description: Notification queued or suppressed + content: + application/json: + schema: + $ref: '#/components/schemas/QueuedNotification' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/permission-grants: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/OptionalPermissionSubjectType' + - $ref: '#/components/parameters/OptionalPermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + - $ref: '#/components/parameters/PermissionGrantStatus' + get: + operationId: listPermissionGrants + tags: + - Control + responses: + '200': + description: Successful listPermissionGrants response. + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrantPage' + '403': + $ref: '#/components/responses/Problem' + post: + operationId: createPermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/PermissionGrantBody' + responses: + '201': + description: Direct permission grant created + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + '403': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/permission-grants/effective: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PermissionSubjectType' + - $ref: '#/components/parameters/PermissionSubjectID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + get: + operationId: getEffectiveAccess + tags: + - Control + responses: + '200': + description: Effective roles and scopes + content: + application/json: + schema: + $ref: '#/components/schemas/EffectiveAccess' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/permission-grants/{grant_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: grant_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getPermissionGrant + tags: + - Control + responses: + '200': + description: Direct permission grant + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + delete: + operationId: revokePermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/IfMatch' + responses: + '204': + description: Direct permission grant revoked + '409': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/invitations: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationInvitations + tags: + - Control + responses: + '200': + description: Successful listApplicationInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' + post: + operationId: createApplicationInvitationMachine + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateInvitation' + responses: + '201': + description: Invitation created and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + /v1/applications/{application_id}/invitations/{invitation_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getApplicationInvitation + tags: + - Control + responses: + '200': + description: Invitation detail + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + delete: + operationId: revokeApplicationInvitation + tags: + - Control + responses: + '204': + description: Pending invitation revoked + /v1/applications/{application_id}/invitations/{invitation_id}/resend: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendApplicationInvitation + tags: + - Control + responses: + '202': + description: Invitation credentials rotated and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationResent' + '429': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/users: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: serviceListApplicationUsers + tags: + - Identity + responses: + '200': + description: Successful serviceListApplicationUsers response. + content: + application/json: + schema: + $ref: '#/components/schemas/UserPage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/users/{user_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetApplicationUser + tags: + - Identity + responses: + '200': + description: Redacted application user + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/workspaces: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: serviceListApplicationWorkspaces + tags: + - Control + responses: + '200': + description: Successful serviceListApplicationWorkspaces response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspacePage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/service/workspaces/{workspace_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetApplicationWorkspace + tags: + - Control + responses: + '200': + description: Workspace detail + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/service/workspaces/{workspace_id}/access: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceListApplicationWorkspaceAccess + tags: + - Control + responses: + '200': + description: Successful serviceListApplicationWorkspaceAccess response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceAccessPage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: subject_type + in: path + required: true + schema: + enum: + - user + - workspace + - name: subject_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetSubjectEntitlements + tags: + - Entitlements + responses: + '200': + description: Successful serviceGetSubjectEntitlements response. + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrantPage' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: subject_type + in: path + required: true + schema: + enum: + - user + - workspace + - name: subject_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: serviceGetSubjectBilling + tags: + - Billing + responses: + '200': + description: Subject billing profile and subscription summary + content: + application/json: + schema: + $ref: '#/components/schemas/BillingSummary' + '403': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/delegations/{delegation_id}/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delegation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeDelegation, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Delegation and delegated sessions revoked } } } - /v1/control/applications/{application_id}/workspace-invitations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWorkspaceInvitations, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWorkspaceInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace invitation created and credential returned once } } } - /v1/control/applications/{application_id}/workspace-invitations/{invitation_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeWorkspaceInvitation, tags: [Control], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Pending workspace invitation revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delegation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeDelegation + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Delegation and delegated sessions revoked + /v1/control/applications/{application_id}/invitations: + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationInvitationsControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationInvitationsControl response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' + post: + operationId: createApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateInvitation' + responses: + '201': + description: Application or workspace invitation created and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + /v1/control/applications/{application_id}/invitations/{invitation_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Invitation detail + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + delete: + operationId: revokeApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Pending invitation revoked + /v1/control/applications/{application_id}/invitations/{invitation_id}/resend: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendApplicationInvitationControl + tags: + - Control + security: + - controlBearer: [] + - controlCookie: [] + responses: + '202': + description: Invitation credentials rotated and localized email queued + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationResent' + '429': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/users: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listUsers, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: User created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listUsers + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listUsers response. + content: + application/json: + schema: + $ref: '#/components/schemas/UserPage' + post: + operationId: createUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateUser' + responses: + '201': + description: User created + content: + application/json: + schema: + $ref: '#/components/schemas/User' /v1/control/applications/{application_id}/users/{user_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: User details } } } - patch: { operationId: updateUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: User details + content: + application/json: + schema: + $ref: '#/components/schemas/User' + patch: + operationId: updateUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateUser' + responses: + '204': + description: User updated /v1/control/applications/{application_id}/users/{user_id}/suspend: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: suspendUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User suspended and active grants revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: suspendUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User suspended and active grants revoked /v1/control/applications/{application_id}/users/{user_id}/restore: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: restoreUser, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Suspended user restored without restoring old sessions } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: restoreUser + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Suspended user restored without restoring old sessions /v1/control/applications/{application_id}/users/{user_id}/verify-email: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyUserEmail, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User email administratively verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyUserEmail + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User email administratively verified /v1/control/applications/{application_id}/users/{user_id}/unverify-email: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: unverifyUserEmail, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User email verification removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: unverifyUserEmail + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User email verification removed /v1/control/applications/{application_id}/users/{user_id}/verify-organization: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyUserOrganization, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User organization administratively verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyUserOrganization + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User organization administratively verified /v1/control/applications/{application_id}/users/{user_id}/unverify-organization: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: unverifyUserOrganization, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: User organization verification removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: unverifyUserOrganization + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: User organization verification removed /v1/control/applications/{application_id}/users/{user_id}/sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listUserSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listUserSessions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SessionPage' /v1/control/applications/{application_id}/users/{user_id}/sessions/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeUserSessions, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: All active user sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeUserSessions + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: All active user sessions revoked + content: + application/json: + schema: + $ref: '#/components/schemas/RevokedSessionCount' /v1/control/applications/{application_id}/users/{user_id}/addresses: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listUserAddresses, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listUserAddresses + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listUserAddresses response. + content: + application/json: + schema: + $ref: '#/components/schemas/AddressPage' /v1/control/applications/{application_id}/oauth-consents: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listOAuthConsents, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listOAuthConsents + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOAuthConsents response. + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthConsentPage' /v1/control/applications/{application_id}/oauth-consents/{user_id}/{client_id}/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeOAuthConsent, tags: [Identity], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Consent and active grants revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeOAuthConsent + tags: + - Identity + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Consent and active grants revoked /v1/control/applications/{application_id}/features: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listFeatures, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createFeature, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateFeature" } } } }, responses: { "201": { description: Feature created }, "422": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listFeatures + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listFeatures response. + content: + application/json: + schema: + $ref: '#/components/schemas/FeaturePage' + post: + operationId: createFeature + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateFeature' + responses: + '201': + description: Feature created + content: + application/json: + schema: + $ref: '#/components/schemas/Feature' + '422': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/password/sign-up: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordSignUp, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PasswordSignUp" } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "403": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordSignUp + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordSignUp' + responses: + '200': + $ref: '#/components/responses/Tokens' + '403': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/password/sign-in: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordSignIn, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PasswordSignIn" } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "401": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordSignIn + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordSignIn' + responses: + '200': + $ref: '#/components/responses/Tokens' + '401': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/methods: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: authMethods, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Enumeration-safe enabled authentication methods } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: authMethods + tags: + - Identity + security: [] + responses: + '200': + description: Enumeration-safe enabled authentication methods + content: + application/json: + schema: + $ref: '#/components/schemas/AuthMethods' /v1/applications/{application_id}/auth/email/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailStart, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/EmailStart" } } } }, responses: { "202": { description: Enumeration-safe challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailStart + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailStart' + responses: + '202': + description: Enumeration-safe challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/auth/email/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailVerify, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/EmailVerify" } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailVerify + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailVerify' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/token/refresh: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: refresh, tags: [Identity], security: [], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [refresh_token], properties: { refresh_token: { type: string, writeOnly: true } } } } } }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: refresh + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RefreshToken' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/password/reset/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordResetStart, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Enumeration-safe reset challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordResetStart + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordResetStart' + responses: + '202': + description: Enumeration-safe reset challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/auth/password/reset/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordResetVerify, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordResetVerify + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordResetVerify' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listAuthProviders, tags: [Identity], security: [], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listAuthProviders + tags: + - Identity + security: [] + responses: + '200': + description: Successful listAuthProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuthProviderPage' /v1/applications/{application_id}/auth/providers/google/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startGoogleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: "Google authorization URL with state, nonce, and S256 PKCE" } } } - /v1/applications/{application_id}/auth/providers/google/callback: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: googleAuthCallback, tags: [Identity], security: [], responses: { "302": { description: Redirect with one-time Platform93 exchange credential } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startGoogleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Google authorization URL with state, nonce, and S256 PKCE + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/auth/providers/google/callback: + get: + operationId: googleAuthCallback + tags: + - Identity + security: [] + responses: + '302': + description: Installation-wide callback that resolves the application from protected OAuth state and redirects with a one-time Platform93 exchange credential /v1/applications/{application_id}/auth/providers/google/exchange: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: exchangeGoogleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: exchangeGoogleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthExchange' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/providers/apple/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startAppleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Apple authorization URL with state and nonce } } } - /v1/applications/{application_id}/auth/providers/apple/callback: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: appleAuthCallback, tags: [Identity], security: [], requestBody: { required: false, content: { application/x-www-form-urlencoded: { schema: { type: object, properties: { code: { type: string }, state: { type: string }, user: { type: string }, error: { type: string } } } } } }, responses: { "302": { description: Redirect with one-time Platform93 exchange credential } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startAppleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Apple authorization URL with state and nonce + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' + /v1/auth/providers/apple/callback: + post: + operationId: appleAuthCallback + tags: + - Identity + security: [] + requestBody: + required: false + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + code: + type: string + state: + type: string + user: + type: string + error: + type: string + responses: + '302': + description: Installation-wide callback that resolves the application from protected OAuth state and redirects with a one-time Platform93 exchange credential /v1/applications/{application_id}/auth/providers/apple/exchange: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: exchangeAppleAuth, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: exchangeAppleAuth + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthExchange' + responses: + '200': + $ref: '#/components/responses/Tokens' /v1/applications/{application_id}/auth/mfa/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: verifyMFA, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "401": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: verifyMFA + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/VerifyMFA' + responses: + '200': + $ref: '#/components/responses/Tokens' + '401': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/auth/mfa/webauthn/options: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: beginWebAuthnAuthentication, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: WebAuthn assertion options and opaque ceremony identifier } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: beginWebAuthnAuthentication + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BeginWebAuthnAuthentication' + responses: + '201': + description: WebAuthn assertion options and opaque ceremony identifier + content: + application/json: + schema: + $ref: '#/components/schemas/WebAuthnChallenge' /v1/applications/{application_id}/auth/mfa/webauthn/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: finishWebAuthnAuthentication, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { $ref: "#/components/responses/Tokens" }, "401": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: finishWebAuthnAuthentication + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FinishWebAuthnCeremony' + responses: + '200': + $ref: '#/components/responses/Tokens' + '401': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/auth/invitations/exchange: + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: exchangeApplicationInvitation + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExchangeInvitation' + responses: + '200': + description: Invitation accepted and a short-lived PKCE-bound authorization code returned + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationExchangeResult' + '401': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/auth/invitations/token: + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: redeemApplicationInvitation + tags: + - Identity + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RedeemInvitation' + responses: + '200': + description: Authentication completed or MFA challenge returned + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '401': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/me: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getCurrentUser, tags: [Identity], responses: { "200": { description: Current user, content: { application/json: { schema: { $ref: "#/components/schemas/User" } } } } } } - patch: { operationId: updateCurrentUser, tags: [Identity], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateUserProfile" } } } }, responses: { "204": { description: Profile updated } } } - delete: { operationId: deleteMyAccount, tags: [Identity], responses: { "204": { description: Account deleted and credentials revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getCurrentUser + tags: + - Identity + responses: + '200': + description: Current user + content: + application/json: + schema: + $ref: '#/components/schemas/User' + patch: + operationId: updateCurrentUser + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateUserProfile' + responses: + '204': + description: Profile updated + delete: + operationId: deleteMyAccount + tags: + - Identity + responses: + '204': + description: Account deleted and credentials revoked /v1/applications/{application_id}/auth/logout: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: logoutCurrentSession, tags: [Identity], responses: { "204": { description: Current interactive session revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: logoutCurrentSession + tags: + - Identity + responses: + '204': + description: Current interactive session revoked /v1/applications/{application_id}/me/api-keys: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listPersonalAPIKeys, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" }, "403": { $ref: "#/components/responses/Problem" } } } - post: { operationId: createPersonalAPIKey, tags: [Identity], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreatePersonalAPIKey" } } } }, responses: { "201": { description: Key created and secret returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listPersonalAPIKeys + tags: + - Identity + responses: + '200': + description: Successful listPersonalAPIKeys response. + content: + application/json: + schema: + $ref: '#/components/schemas/PersonalAPIKeyPage' + '403': + $ref: '#/components/responses/Problem' + post: + operationId: createPersonalAPIKey + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePersonalAPIKey' + responses: + '201': + description: Key created and secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/PersonalAPIKeyCreated' /v1/applications/{application_id}/catalog/products: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: publicCatalog, tags: [Catalog], security: [], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: publicCatalog + tags: + - Catalog + security: [] + responses: + '200': + description: Successful publicCatalog response. + content: + application/json: + schema: + $ref: '#/components/schemas/ProductPage' /v1/control/applications/{application_id}/products: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listProducts, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createProduct, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateProduct" } } } }, responses: { "201": { description: Product created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listProducts + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listProducts response. + content: + application/json: + schema: + $ref: '#/components/schemas/ProductPage' + post: + operationId: createProduct + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateProduct' + responses: + '201': + description: Product created + content: + application/json: + schema: + $ref: '#/components/schemas/Product' /v1/control/applications/{application_id}/products/{product_id}/prices: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: product_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listPrices, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createPrice, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreatePrice" } } } }, responses: { "201": { description: Immutable price created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: product_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listPrices + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listPrices response. + content: + application/json: + schema: + $ref: '#/components/schemas/PricePage' + post: + operationId: createPrice + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePrice' + responses: + '201': + description: Immutable price created + content: + application/json: + schema: + $ref: '#/components/schemas/Price' /v1/control/applications/{application_id}/products/{product_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: product_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getProduct, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Product details } } } - patch: { operationId: updateProduct, tags: [Catalog], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateProduct" } } } }, responses: { "204": { description: Product updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: product_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getProduct + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Product details + content: + application/json: + schema: + $ref: '#/components/schemas/Product' + patch: + operationId: updateProduct + tags: + - Catalog + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateProduct' + responses: + '204': + description: Product updated /v1/control/applications/{application_id}/entitlements: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listEntitlements, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Entitlement grant created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listEntitlements + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listEntitlements response. + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrantPage' + post: + operationId: createEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEntitlement' + responses: + '201': + description: Entitlement grant created + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrant' /v1/control/applications/{application_id}/entitlements/{entitlement_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: entitlement_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Entitlement grant, effective state, and append-only actions" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Entitlement grant, effective state, and append-only actions + content: + application/json: + schema: + $ref: '#/components/schemas/EntitlementGrant' /v1/control/applications/{application_id}/entitlements/{entitlement_id}/revoke: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: entitlement_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: revokeEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Append-only revocation recorded } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: revokeEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Append-only revocation recorded + /v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: adjustEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AdjustEntitlement' + responses: + '204': + description: Append-only expiry adjustment recorded /v1/control/applications/{application_id}/entitlements/{entitlement_id}/restore: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: entitlement_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: restoreEntitlement, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Append-only restoration recorded } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: entitlement_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: restoreEntitlement + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Append-only restoration recorded /v1/control/applications/{application_id}/local-entitlement-requests: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listLocalEntitlementRequests, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listLocalEntitlementRequests + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listLocalEntitlementRequests response. + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequestPage' /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - get: { operationId: getLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Local request with immutable snapshots and action history } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + get: + operationId: getLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Local request with immutable snapshots and action history + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequest' /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/approve: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: approveLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Request approved exactly once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: approveLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '200': + description: Request approved exactly once + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementApproval' /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/reject: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: rejectLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Request rejected } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: rejectLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Request rejected /v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/reopen: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: reopenLocalEntitlementRequest, tags: [Entitlements], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Rejected or canceled request reopened for review } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: reopenLocalEntitlementRequest + tags: + - Entitlements + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditReason' + responses: + '204': + description: Rejected or canceled request reopened for review /v1/applications/{application_id}/local-entitlement-checkouts: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: localEntitlementCheckout, tags: [Entitlements], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/LocalCheckout" } } } }, responses: { "201": { description: Pending local entitlement request } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: localEntitlementCheckout + tags: + - Entitlements + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/LocalCheckout' + responses: + '201': + description: Pending local entitlement request + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequest' /v1/applications/{application_id}/me/local-entitlement-requests: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyLocalEntitlementRequests, tags: [Entitlements], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyLocalEntitlementRequests + tags: + - Entitlements + responses: + '200': + description: Successful listMyLocalEntitlementRequests response. + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequestPage' /v1/applications/{application_id}/me/local-entitlement-requests/{request_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - get: { operationId: getMyLocalEntitlementRequest, tags: [Entitlements], responses: { "200": { description: Own local request with immutable snapshots and action history } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + get: + operationId: getMyLocalEntitlementRequest + tags: + - Entitlements + responses: + '200': + description: Own local request with immutable snapshots and action history + content: + application/json: + schema: + $ref: '#/components/schemas/LocalEntitlementRequest' /v1/applications/{application_id}/me/local-entitlement-requests/{request_id}/cancel: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/RequestID" }] - post: { operationId: cancelMyLocalEntitlementRequest, tags: [Entitlements], responses: { "204": { description: Pending request canceled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/RequestID' + post: + operationId: cancelMyLocalEntitlementRequest + tags: + - Entitlements + responses: + '204': + description: Pending request canceled /v1/applications/{application_id}/me/entitlements: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceIDQuery" }] - get: { operationId: listMyEntitlements, tags: [Entitlements], responses: { "200": { description: "Effective user entitlements, optionally merged with one accessible workspace and full provenance" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceIDQuery' + get: + operationId: listMyEntitlements + tags: + - Entitlements + responses: + '200': + description: Effective user entitlements, optionally merged with one accessible workspace and full provenance + content: + application/json: + schema: + $ref: '#/components/schemas/EffectiveEntitlements' /v1/control/applications/{application_id}/billing/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listBillingProviders, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateBillingProvider" } } } }, responses: { "201": { description: Billing provider configured } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listBillingProviders + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listBillingProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderPage' + post: + operationId: createBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBillingProvider' + responses: + '201': + description: Billing provider configured + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' /v1/control/applications/{application_id}/billing/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free provider connection } } } - patch: { operationId: updateBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Provider credentials or metadata updated } } } - delete: { operationId: disableBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Provider disabled }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free provider connection + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProvider' + patch: + operationId: updateBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProvider' + responses: + '204': + description: Provider credentials or metadata updated + delete: + operationId: disableBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Provider disabled + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/billing/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyBillingProvider, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Provider credentials verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyBillingProvider + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Provider credentials verified /v1/applications/{application_id}/billing/checkout-sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createCheckoutSession, tags: [Billing], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateCheckout" } } } }, responses: { "201": { description: Provider checkout created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createCheckoutSession + tags: + - Billing + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateCheckout' + responses: + '201': + description: Provider checkout created + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutSession' /v1/applications/{application_id}/billing/checkout-sessions/{session_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SessionID" }] - get: { operationId: getCheckoutSession, tags: [Billing], responses: { "200": { description: Checkout status and redirect URI } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SessionID' + get: + operationId: getCheckoutSession + tags: + - Billing + responses: + '200': + description: Checkout status and redirect URI + content: + application/json: + schema: + $ref: '#/components/schemas/CheckoutSession' /v1/applications/{application_id}/billing/portal-sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createBillingPortalSession, tags: [Billing], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Customer portal session created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createBillingPortalSession + tags: + - Billing + parameters: + - $ref: '#/components/parameters/IdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePortalSession' + responses: + '201': + description: Customer portal session created + content: + application/json: + schema: + $ref: '#/components/schemas/PortalSession' /v1/control/applications/{application_id}/billing/subscriptions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listSubscriptions, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listSubscriptions + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listSubscriptions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SubscriptionPage' /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }] - get: { operationId: getSubscription, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Subscription details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + get: + operationId: getSubscription + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Subscription details + content: + application/json: + schema: + $ref: '#/components/schemas/Subscription' /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/cancel: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: cancelSubscription, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Subscription cancellation scheduled or applied } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: cancelSubscription + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CancelSubscription' + responses: + '204': + description: Subscription cancellation scheduled or applied /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/resume: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: resumeSubscription, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Scheduled cancellation removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: resumeSubscription + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Scheduled cancellation removed /v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/change-price: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/SubscriptionID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: changeSubscriptionPrice, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { type: object, required: [price_id], properties: { price_id: { $ref: "#/components/schemas/UUID" }, proration_behavior: { enum: [create_prorations, always_invoice, none], default: create_prorations } } } } } }, responses: { "200": { description: Subscription price changed and synchronized } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/SubscriptionID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: changeSubscriptionPrice + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ChangeSubscriptionPrice' + responses: + '200': + description: Subscription price changed and synchronized + content: + application/json: + schema: + $ref: '#/components/schemas/Subscription' /v1/control/applications/{application_id}/billing/invoices: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listInvoices, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listInvoices + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInvoices response. + content: + application/json: + schema: + $ref: '#/components/schemas/InvoicePage' /v1/control/applications/{application_id}/billing/invoices/{invoice_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: invoice_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getInvoice, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized invoice details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: invoice_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getInvoice + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized invoice details + content: + application/json: + schema: + $ref: '#/components/schemas/Invoice' /v1/control/applications/{application_id}/billing/payments: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listPayments, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listPayments + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listPayments response. + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentPage' /v1/control/applications/{application_id}/billing/payments/{payment_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/PaymentID" }] - get: { operationId: getPayment, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized payment details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PaymentID' + get: + operationId: getPayment + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized payment details + content: + application/json: + schema: + $ref: '#/components/schemas/Payment' /v1/control/applications/{application_id}/billing/payments/{payment_id}/refunds: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/PaymentID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: createRefund, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Full or partial refund created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/PaymentID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: createRefund + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateRefund' + responses: + '201': + description: Full or partial refund created + content: + application/json: + schema: + $ref: '#/components/schemas/Refund' /v1/control/applications/{application_id}/billing/refunds: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listRefunds, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listRefunds + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listRefunds response. + content: + application/json: + schema: + $ref: '#/components/schemas/RefundPage' /v1/control/applications/{application_id}/billing/refunds/{refund_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: refund_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getRefund, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized refund details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: refund_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getRefund + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized refund details + content: + application/json: + schema: + $ref: '#/components/schemas/Refund' /v1/control/applications/{application_id}/billing/disputes: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listDisputes, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listDisputes + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listDisputes response. + content: + application/json: + schema: + $ref: '#/components/schemas/DisputePage' /v1/control/applications/{application_id}/billing/disputes/{dispute_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: dispute_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getDispute, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Normalized dispute details } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: dispute_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getDispute + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Normalized dispute details + content: + application/json: + schema: + $ref: '#/components/schemas/Dispute' /v1/control/applications/{application_id}/billing/statistics: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: from, in: query, schema: { type: string, format: date-time } }, { name: to, in: query, schema: { type: string, format: date-time } }] - get: { operationId: getBillingStatistics, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Bounded revenue, refund, and lifecycle statistics" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: from + in: query + schema: + type: string + format: date-time + - name: to + in: query + schema: + type: string + format: date-time + get: + operationId: getBillingStatistics + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Bounded revenue, refund, and lifecycle statistics + content: + application/json: + schema: + $ref: '#/components/schemas/BillingStatistics' /v1/control/applications/{application_id}/billing/provider-events: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listBillingProviderEvents, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listBillingProviderEvents + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listBillingProviderEvents response. + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProviderEventPage' /v1/control/applications/{application_id}/billing/provider-events/{event_id}/replay: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: event_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: replayBillingProviderEvent, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Stored provider event replayed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: event_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: replayBillingProviderEvent + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Stored provider event replayed /v1/control/applications/{application_id}/billing/providers/{provider_id}/reconciliation-runs: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: createBillingReconciliationRun, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "202": { description: Reconciliation queued transactionally } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: createBillingReconciliationRun + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '202': + description: Reconciliation queued transactionally + content: + application/json: + schema: + $ref: '#/components/schemas/ReconciliationAccepted' /v1/control/applications/{application_id}/billing/reconciliation-runs: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listBillingReconciliationRuns, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listBillingReconciliationRuns + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listBillingReconciliationRuns response. + content: + application/json: + schema: + $ref: '#/components/schemas/ReconciliationRunPage' /v1/control/applications/{application_id}/billing/reconciliation-runs/{run_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: run_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getBillingReconciliationRun, tags: [Billing], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Reconciliation findings, repairs, and status" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: run_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getBillingReconciliationRun + tags: + - Billing + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Reconciliation findings, repairs, and status + content: + application/json: + schema: + $ref: '#/components/schemas/ReconciliationRun' /v1/applications/{application_id}/me/billing: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getMyBillingSummary, tags: [Billing], responses: { "200": { description: Current billing resource counts } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getMyBillingSummary + tags: + - Billing + responses: + '200': + description: Current billing resource counts + content: + application/json: + schema: + $ref: '#/components/schemas/BillingSummary' /v1/applications/{application_id}/me/subscriptions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMySubscriptions, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMySubscriptions + tags: + - Billing + responses: + '200': + description: Successful listMySubscriptions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SubscriptionPage' /v1/applications/{application_id}/me/invoices: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyInvoices, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyInvoices + tags: + - Billing + responses: + '200': + description: Successful listMyInvoices response. + content: + application/json: + schema: + $ref: '#/components/schemas/InvoicePage' /v1/applications/{application_id}/me/payments: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyPayments, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyPayments + tags: + - Billing + responses: + '200': + description: Successful listMyPayments response. + content: + application/json: + schema: + $ref: '#/components/schemas/PaymentPage' /v1/applications/{application_id}/me/sessions: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMySessions, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMySessions + tags: + - Identity + responses: + '200': + description: Successful listMySessions response. + content: + application/json: + schema: + $ref: '#/components/schemas/SessionPage' /v1/applications/{application_id}/me/email-verification/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailVerificationStart, tags: [Identity], responses: { "202": { description: Verification challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailVerificationStart + tags: + - Identity + responses: + '202': + description: Verification challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/me/email-verification/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailVerificationVerify, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Email verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailVerificationVerify + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccountChallenge' + responses: + '204': + description: Email verified /v1/applications/{application_id}/me/email-change/start: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailChangeStart, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Email change challenge accepted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailChangeStart + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmailAddress' + responses: + '202': + description: Email change challenge accepted + content: + application/json: + schema: + $ref: '#/components/schemas/ChallengeAccepted' /v1/applications/{application_id}/me/email-change/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: emailChangeVerify, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Email changed and other sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: emailChangeVerify + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AccountChallenge' + responses: + '204': + description: Email changed and other sessions revoked /v1/applications/{application_id}/me/password/change: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: passwordChange, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Password changed and other sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: passwordChange + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PasswordChange' + responses: + '204': + description: Password changed and other sessions revoked /v1/applications/{application_id}/me/export: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: exportMyAccount, tags: [Identity], responses: { "200": { description: Portable account export } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: exportMyAccount + tags: + - Identity + responses: + '200': + description: Portable account export + content: + application/json: + schema: + $ref: '#/components/schemas/AccountExport' /v1/applications/{application_id}/me/anonymize: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: anonymizeMyAccount, tags: [Identity], responses: { "204": { description: Personal account data anonymized and credentials revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: anonymizeMyAccount + tags: + - Identity + responses: + '204': + description: Personal account data anonymized and credentials revoked /v1/applications/{application_id}/me/mfa/methods: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyMFAMethods, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyMFAMethods + tags: + - Identity + responses: + '200': + description: Successful listMyMFAMethods response. + content: + application/json: + schema: + $ref: '#/components/schemas/MFAMethodPage' /v1/applications/{application_id}/me/mfa/totp: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startTOTPEnrollment, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: One-time TOTP secret and provisioning URI } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startTOTPEnrollment + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/StartTOTP' + responses: + '201': + description: One-time TOTP secret and provisioning URI + content: + application/json: + schema: + $ref: '#/components/schemas/MFAEnrollment' /v1/applications/{application_id}/me/mfa/totp/{method_id}/activate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: method_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: activateTOTPEnrollment, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: TOTP activated and recovery codes returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: method_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: activateTOTPEnrollment + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ActivateTOTP' + responses: + '200': + description: TOTP activated and recovery codes returned once + content: + application/json: + schema: + $ref: '#/components/schemas/MFAActivation' /v1/applications/{application_id}/me/mfa/webauthn/options: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: beginWebAuthnRegistration, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: WebAuthn credential creation options and opaque ceremony identifier } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: beginWebAuthnRegistration + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/BeginWebAuthnRegistration' + responses: + '201': + description: WebAuthn credential creation options and opaque ceremony identifier + content: + application/json: + schema: + $ref: '#/components/schemas/WebAuthnChallenge' /v1/applications/{application_id}/me/mfa/webauthn/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: finishWebAuthnRegistration, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: WebAuthn credential activated and recovery codes returned once when created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: finishWebAuthnRegistration + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/FinishWebAuthnCeremony' + responses: + '200': + description: WebAuthn credential activated and recovery codes returned once when created + content: + application/json: + schema: + $ref: '#/components/schemas/MFAActivation' /v1/applications/{application_id}/me/mfa/methods/{method_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: method_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: disableMFAMethod, tags: [Identity], responses: { "204": { description: MFA method disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: method_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: disableMFAMethod + tags: + - Identity + responses: + '204': + description: MFA method disabled /v1/applications/{application_id}/me/mfa/recovery-codes/regenerate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: regenerateRecoveryCodes, tags: [Identity], responses: { "200": { description: Replacement recovery codes returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: regenerateRecoveryCodes + tags: + - Identity + responses: + '200': + description: Replacement recovery codes returned once + content: + application/json: + schema: + $ref: '#/components/schemas/RecoveryCodes' /v1/applications/{application_id}/me/auth/providers/google/link: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startGoogleLink, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Authenticated Google account-link authorization URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startGoogleLink + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Authenticated Google account-link authorization URL + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' /v1/applications/{application_id}/me/auth/providers/apple/link: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: startAppleLink, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Authenticated Apple account-link authorization URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: startAppleLink + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStartRequest' + responses: + '201': + description: Authenticated Apple account-link authorization URL + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalAuthStart' /v1/applications/{application_id}/me/auth/identities: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyIdentities, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyIdentities + tags: + - Identity + responses: + '200': + description: Successful listMyIdentities response. + content: + application/json: + schema: + $ref: '#/components/schemas/ExternalIdentityPage' /v1/applications/{application_id}/me/auth/identities/{identity_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: identity_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: unlinkMyIdentity, tags: [Identity], responses: { "204": { description: Linked identity removed while preserving a usable login method } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: identity_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: unlinkMyIdentity + tags: + - Identity + responses: + '204': + description: Linked identity removed while preserving a usable login method /v1/applications/{application_id}/me/sessions/{session_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: session_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeMySession, tags: [Identity], responses: { "204": { description: Session revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: session_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeMySession + tags: + - Identity + responses: + '204': + description: Session revoked /v1/applications/{application_id}/me/logout-all: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: logoutAll, tags: [Identity], responses: { "204": { description: All user sessions revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: logoutAll + tags: + - Identity + responses: + '204': + description: All user sessions revoked /v1/applications/{application_id}/me/api-keys/{key_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: key_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokePersonalAPIKey, tags: [Identity], responses: { "204": { description: Personal API key revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: key_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokePersonalAPIKey + tags: + - Identity + responses: + '204': + description: Personal API key revoked /v1/applications/{application_id}/me/addresses: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyAddresses, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createMyAddress, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Address created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyAddresses + tags: + - Identity + responses: + '200': + description: Successful listMyAddresses response. + content: + application/json: + schema: + $ref: '#/components/schemas/AddressPage' + post: + operationId: createMyAddress + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAddress' + responses: + '201': + description: Address created + content: + application/json: + schema: + $ref: '#/components/schemas/Address' /v1/applications/{application_id}/me/addresses/{address_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateMyAddress, tags: [Identity], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Address updated with optimistic concurrency } } } - delete: { operationId: deleteMyAddress, tags: [Identity], responses: { "204": { description: Inactive address deleted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateMyAddress + tags: + - Identity + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAddress' + responses: + '204': + description: Address updated with optimistic concurrency + delete: + operationId: deleteMyAddress + tags: + - Identity + responses: + '204': + description: Inactive address deleted /v1/applications/{application_id}/me/addresses/{address_id}/activate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: activateMyAddress, tags: [Identity], responses: { "204": { description: Address atomically selected as active } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: activateMyAddress + tags: + - Identity + responses: + '204': + description: Address atomically selected as active /v1/applications/{application_id}/me/billing-profile: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getMyBillingProfile, tags: [Billing], responses: { "200": { description: Current user billing profile } } } - patch: { operationId: updateMyBillingProfile, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Current user billing profile updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getMyBillingProfile + tags: + - Billing + responses: + '200': + description: Current user billing profile + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProfile' + patch: + operationId: updateMyBillingProfile + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProfile' + responses: + '204': + description: Current user billing profile updated /v1/applications/{application_id}/me/workspaces: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyWorkspaces, tags: [Control], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createMyWorkspace, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace created with the current user as owner } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyWorkspaces + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaces response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspacePage' + post: + operationId: createMyWorkspace + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWorkspace' + responses: + '201': + description: Workspace created with the current user as owner + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' /v1/applications/{application_id}/workspaces/{workspace_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getMyWorkspace, tags: [Control], responses: { "200": { description: Accessible workspace details } } } - patch: { operationId: updateMyWorkspace, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace updated } } } - delete: { operationId: archiveMyWorkspace, tags: [Control], responses: { "204": { description: Owned workspace archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getMyWorkspace + tags: + - Control + responses: + '200': + description: Accessible workspace details + content: + application/json: + schema: + $ref: '#/components/schemas/Workspace' + patch: + operationId: updateMyWorkspace + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateWorkspace' + responses: + '204': + description: Workspace updated + delete: + operationId: archiveMyWorkspace + tags: + - Control + responses: + '204': + description: Owned workspace archived /v1/applications/{application_id}/workspaces/{workspace_id}/members: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listMyWorkspaceMembers, tags: [Control], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listMyWorkspaceMembers + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaceMembers response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMemberPage' /v1/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: user_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - put: { operationId: replaceMyWorkspaceMemberRoles, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Workspace member roles replaced } } } - delete: { operationId: removeMyWorkspaceMember, tags: [Control], responses: { "204": { description: Workspace member removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: user_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + put: + operationId: replaceMyWorkspaceMemberRoles + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ReplaceWorkspaceMemberRoles' + responses: + '200': + description: Workspace member roles replaced + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceMember' + delete: + operationId: removeMyWorkspaceMember + tags: + - Control + responses: + '204': + description: Workspace member removed /v1/applications/{application_id}/workspaces/{workspace_id}/owner-transfer: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: transferMyWorkspaceOwnership, tags: [Control], requestBody: { $ref: "#/components/requestBodies/OwnershipTransfer" }, responses: { "200": { $ref: "#/components/responses/OwnershipTransferResult" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: transferMyWorkspaceOwnership + tags: + - Control + requestBody: + $ref: '#/components/requestBodies/OwnershipTransfer' + responses: + '200': + $ref: '#/components/responses/OwnershipTransferResult' /v1/applications/{application_id}/workspaces/{workspace_id}/membership: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: leaveWorkspace, tags: [Control], responses: { "204": { description: Current membership removed } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: leaveWorkspace + tags: + - Control + responses: + '204': + description: Current membership removed /v1/applications/{application_id}/workspaces/{workspace_id}/invitations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: createMyWorkspaceInvitation, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace invitation created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listMyWorkspaceInvitations + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaceInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' + post: + operationId: createMyWorkspaceInvitation + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateInvitation' + responses: + '201': + description: Workspace invitation created and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitation' + /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeMyWorkspaceInvitation + tags: + - Control + responses: + '204': + description: Pending workspace invitation revoked + /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: invitation_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: resendMyWorkspaceInvitation + tags: + - Control + responses: + '202': + description: Workspace invitation credentials rotated and email queued + content: + application/json: + schema: + $ref: '#/components/schemas/InvitationResent' + '429': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/workspaces/{workspace_id}/access: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listMyWorkspaceAccess + tags: + - Control + responses: + '200': + description: Successful listMyWorkspaceAccess response. + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceAccessPage' + /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/OptionalPermissionSubjectType' + - $ref: '#/components/parameters/OptionalPermissionSubjectID' + - $ref: '#/components/parameters/PermissionGrantStatus' + get: + operationId: listWorkspacePermissionGrants + tags: + - Control + responses: + '200': + description: Successful listWorkspacePermissionGrants response. + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrantPage' + '403': + $ref: '#/components/responses/Problem' + post: + operationId: createWorkspacePermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/PermissionGrantBody' + responses: + '201': + description: Workspace direct permission grant created + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + '403': + $ref: '#/components/responses/Problem' + /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}: + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - name: grant_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWorkspacePermissionGrant + tags: + - Control + responses: + '200': + description: Workspace direct permission grant + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionGrant' + delete: + operationId: revokeWorkspacePermissionGrant + tags: + - Control + parameters: + - $ref: '#/components/parameters/IfMatch' + responses: + '204': + description: Workspace direct permission grant revoked + '409': + $ref: '#/components/responses/Problem' /v1/applications/{application_id}/workspaces/{workspace_id}/billing-profile: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWorkspaceBillingProfile, tags: [Billing], responses: { "200": { description: Workspace billing profile } } } - patch: { operationId: updateWorkspaceBillingProfile, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace billing profile updated } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWorkspaceBillingProfile + tags: + - Billing + responses: + '200': + description: Workspace billing profile + content: + application/json: + schema: + $ref: '#/components/schemas/BillingProfile' + patch: + operationId: updateWorkspaceBillingProfile + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBillingProfile' + responses: + '204': + description: Workspace billing profile updated /v1/applications/{application_id}/workspaces/{workspace_id}/addresses: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: listWorkspaceAddresses, tags: [Billing], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWorkspaceAddress, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Workspace billing address created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: listWorkspaceAddresses + tags: + - Billing + responses: + '200': + description: Successful listWorkspaceAddresses response. + content: + application/json: + schema: + $ref: '#/components/schemas/AddressPage' + post: + operationId: createWorkspaceAddress + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAddress' + responses: + '201': + description: Workspace billing address created + content: + application/json: + schema: + $ref: '#/components/schemas/Address' /v1/applications/{application_id}/workspaces/{workspace_id}/addresses/{address_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: updateWorkspaceAddress, tags: [Billing], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Workspace billing address updated } } } - delete: { operationId: deleteWorkspaceAddress, tags: [Billing], responses: { "204": { description: Inactive workspace billing address deleted } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: updateWorkspaceAddress + tags: + - Billing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateAddress' + responses: + '204': + description: Workspace billing address updated + delete: + operationId: deleteWorkspaceAddress + tags: + - Billing + responses: + '204': + description: Inactive workspace billing address deleted /v1/applications/{application_id}/workspaces/{workspace_id}/addresses/{address_id}/activate: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { name: address_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: activateWorkspaceAddress, tags: [Billing], responses: { "204": { description: Workspace billing address selected as active } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - name: address_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: activateWorkspaceAddress + tags: + - Billing + responses: + '204': + description: Workspace billing address selected as active /v1/applications/{application_id}/me/workspace-invitations: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyWorkspaceInvitations, tags: [Control], responses: { "200": { $ref: "#/components/responses/Page" } } } - /v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: invitation_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: acceptMyWorkspaceInvitation, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Workspace invitation accepted atomically } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyPendingInvitations + tags: + - Control + responses: + '200': + description: Successful listMyPendingInvitations response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInvitationPage' /v1/applications/{application_id}/me/permissions/check: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: checkMyPermissions, tags: [Control], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Permission decisions with role explanations } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: checkMyPermissions + tags: + - Control + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionCheck' + responses: + '200': + description: Permission decisions with role explanations + content: + application/json: + schema: + $ref: '#/components/schemas/PermissionCheckResult' /v1/applications/{application_id}/me/oauth-consents: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyOAuthConsents, tags: [Identity], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyOAuthConsents + tags: + - Identity + responses: + '200': + description: Successful listMyOAuthConsents response. + content: + application/json: + schema: + $ref: '#/components/schemas/OAuthConsentPage' /v1/applications/{application_id}/me/oauth-consents/{client_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: client_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - delete: { operationId: revokeMyOAuthConsent, tags: [Identity], responses: { "204": { description: Own consent and active grants revoked } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: client_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + delete: + operationId: revokeMyOAuthConsent + tags: + - Identity + responses: + '204': + description: Own consent and active grants revoked /v1/applications/{application_id}/events: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: publishCustomEvent, tags: [Events], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PublishCustomEvent" } } } }, responses: { "202": { description: Custom event and transactional outbox record accepted, content: { application/json: { schema: { $ref: "#/components/schemas/EventEnvelope" } } } }, "403": { $ref: "#/components/responses/Problem" }, "422": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: publishCustomEvent + tags: + - Events + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PublishCustomEvent' + responses: + '202': + description: Custom event and transactional outbox record accepted + content: + application/json: + schema: + $ref: '#/components/schemas/EventEnvelope' + '403': + $ref: '#/components/responses/Problem' + '422': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/events: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listEvents, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listEvents + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listEvents response. + content: + application/json: + schema: + $ref: '#/components/schemas/EventPage' /v1/control/applications/{application_id}/events/{event_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: event_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getEvent, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: CloudEvents-compatible event detail, content: { application/json: { schema: { $ref: "#/components/schemas/EventEnvelope" } } } } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: event_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getEvent + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: CloudEvents-compatible event detail + content: + application/json: + schema: + $ref: '#/components/schemas/EventEnvelope' /v1/control/applications/{application_id}/event-types: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listEventTypes, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateEventType" } } } }, responses: { "201": { description: Application event type registered }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listEventTypes + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listEventTypes response. + content: + application/json: + schema: + $ref: '#/components/schemas/EventTypePage' + post: + operationId: createEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateEventType' + responses: + '201': + description: Application event type registered + content: + application/json: + schema: + $ref: '#/components/schemas/EventTypeDefinition' + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/event-types/{event_type_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: event_type_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Versioned event contract with a complete webhook example, content: { application/json: { schema: { $ref: "#/components/schemas/EventTypeDefinition" } } } } } } - patch: { operationId: updateEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateEventType" } } } }, responses: { "204": { description: Event type definition updated }, "409": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: archiveEventType, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Application event type archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: event_type_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Versioned event contract with a complete webhook example + content: + application/json: + schema: + $ref: '#/components/schemas/EventTypeDefinition' + patch: + operationId: updateEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateEventType' + responses: + '204': + description: Event type definition updated + '409': + $ref: '#/components/responses/Problem' + delete: + operationId: archiveEventType + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Application event type archived /v1/control/applications/{application_id}/audit-logs: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listAuditLogs, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listAuditLogs + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listAuditLogs response. + content: + application/json: + schema: + $ref: '#/components/schemas/AuditRecordPage' /v1/control/applications/{application_id}/audit-logs/{audit_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: audit_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getAuditLog, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Audit record detail } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: audit_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getAuditLog + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Audit record detail + content: + application/json: + schema: + $ref: '#/components/schemas/AuditRecord' /v1/control/applications/{application_id}/audit-exports: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createAuditExport, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Encrypted one-hour audit export created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createAuditExport + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AuditExport' + responses: + '201': + description: Encrypted one-hour audit export created + content: + application/json: + schema: + $ref: '#/components/schemas/AuditExportRecord' /v1/control/applications/{application_id}/audit-exports/{export_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: export_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getAuditExport, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Decrypted audit export before expiry } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: export_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getAuditExport + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Decrypted audit export before expiry + content: + application/json: + schema: + $ref: '#/components/schemas/AuditExportRecord' /v1/control/applications/{application_id}/webhooks: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWebhooks, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Webhook created and secret returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listWebhooks + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWebhooks response. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookPage' + post: + operationId: createWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateWebhook' + responses: + '201': + description: Webhook created and secret returned once + content: + application/json: + schema: + $ref: '#/components/schemas/Webhook' /v1/control/applications/{application_id}/webhooks/{webhook_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: webhook_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Webhook endpoint and delivery statistics }, "404": { $ref: "#/components/responses/Problem" } } } - patch: { operationId: updateWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Webhook endpoint updated }, "409": { $ref: "#/components/responses/Problem" } } } - delete: { operationId: disableWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Webhook disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: webhook_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Webhook endpoint and delivery statistics + content: + application/json: + schema: + $ref: '#/components/schemas/Webhook' + '404': + $ref: '#/components/responses/Problem' + patch: + operationId: updateWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateWebhook' + responses: + '204': + description: Webhook endpoint updated + '409': + $ref: '#/components/responses/Problem' + delete: + operationId: disableWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Webhook disabled /v1/control/applications/{application_id}/webhooks/{webhook_id}/test: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: webhook_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testWebhook, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "202": { description: Targeted signed test delivery queued }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: webhook_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testWebhook + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '202': + description: Targeted signed test delivery queued + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookTestAccepted' + '404': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/webhooks/{webhook_id}/rotate-secret: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: webhook_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: rotateWebhookSecret, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Webhook secret rotated and returned once } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: webhook_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: rotateWebhookSecret + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Webhook secret rotated and returned once + content: + application/json: + schema: + $ref: '#/components/schemas/SecretCredential' /v1/control/applications/{application_id}/webhook-deliveries: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listWebhookDeliveries, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listWebhookDeliveries + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listWebhookDeliveries response. + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookDeliveryPage' /v1/control/applications/{application_id}/webhook-deliveries/{delivery_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delivery_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getWebhookDelivery, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Webhook delivery history detail }, "404": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delivery_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getWebhookDelivery + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Webhook delivery history detail + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookDelivery' + '404': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/webhook-deliveries/{delivery_id}/replay: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: delivery_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: replayWebhookDelivery, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Delivery queued for replay } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: delivery_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: replayWebhookDelivery + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Delivery queued for replay /v1/control/applications/{application_id}/notification-providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotificationProviders, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/SMTPProvider" }, responses: { "201": { description: SMTP provider stored } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotificationProviders + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listNotificationProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProviderPage' + post: + operationId: createNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/SMTPProvider' + responses: + '201': + description: SMTP provider stored + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' /v1/control/applications/{application_id}/notification-providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Redacted provider configuration and health } } } - patch: { operationId: updateNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Redacted updated provider configuration } } } - delete: { operationId: disableNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Notification provider disabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Redacted provider configuration and health + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + patch: + operationId: updateNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateSMTPProvider' + responses: + '200': + description: Redacted updated provider configuration + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationProvider' + delete: + operationId: disableNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Notification provider disabled /v1/control/applications/{application_id}/notification-providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: verifyNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: SMTP connectivity and authentication verified }, "502": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: verifyNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: SMTP connectivity and authentication verified + '502': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/notification-providers/{provider_id}/test: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }, { $ref: "#/components/parameters/IdempotencyKey" }] - post: { operationId: testNotificationProvider, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "202": { description: Provider-specific test notification queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + - $ref: '#/components/parameters/IdempotencyKey' + post: + operationId: testNotificationProvider + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/TestNotificationProvider' + responses: + '202': + description: Provider-specific test notification queued + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationQueued' /v1/control/applications/{application_id}/sender-identities: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listSenderIdentities, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createSenderIdentity, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Sender identity created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listSenderIdentities + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listSenderIdentities response. + content: + application/json: + schema: + $ref: '#/components/schemas/SenderIdentityPage' + post: + operationId: createSenderIdentity + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateSenderIdentity' + responses: + '201': + description: Sender identity created + content: + application/json: + schema: + $ref: '#/components/schemas/SenderIdentity' /v1/control/applications/{application_id}/sender-identities/{sender_id}/default: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: sender_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: setDefaultSenderIdentity, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Default sender selected } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: sender_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: setDefaultSenderIdentity + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Default sender selected /v1/control/installation/notification-templates: - get: { operationId: listInstallationNotificationTemplates, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Installation template draft created } } } + get: + operationId: listInstallationNotificationTemplates + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationNotificationTemplates response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePage' + post: + operationId: createInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateNotificationTemplate' + responses: + '201': + description: Installation template draft created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/installation/notification-template-variables: - get: { operationId: listInstallationNotificationTemplateVariables, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation template variables and samples } } } + get: + operationId: listInstallationNotificationTemplateVariables + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation template variables and samples + content: + application/json: + schema: + $ref: '#/components/schemas/TemplateVariables' /v1/control/installation/notification-templates/{template_id}: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation template and immutable history } } } - patch: { operationId: updateInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: New installation template draft version created } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation template and immutable history + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' + patch: + operationId: updateInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNotificationTemplate' + responses: + '201': + description: New installation template draft version created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/installation/notification-templates/{template_id}/preview: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: previewInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Safely rendered installation template preview } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: previewInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PreviewNotificationTemplate' + responses: + '200': + description: Safely rendered installation template preview + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePreview' /v1/control/installation/notification-templates/{template_id}/publish: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: publishInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation template published } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: publishInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation template published /v1/control/installation/notification-templates/{template_id}/archive: - parameters: [{ name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: archiveInstallationNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Installation template archived } } } + parameters: + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: archiveInstallationNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Installation template archived /v1/control/applications/{application_id}/notification-templates: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotificationTemplates, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: Immutable draft template version created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotificationTemplates + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listNotificationTemplates response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePage' + post: + operationId: createNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateNotificationTemplate' + responses: + '201': + description: Immutable draft template version created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/applications/{application_id}/notification-template-variables: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotificationTemplateVariables, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Built-in notification template variables and sample values } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotificationTemplateVariables + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Built-in notification template variables and sample values + content: + application/json: + schema: + $ref: '#/components/schemas/TemplateVariables' /v1/control/applications/{application_id}/notification-templates/{template_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Template version and immutable version history } } } - patch: { operationId: updateNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "201": { description: New immutable draft version created } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Template version and immutable version history + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' + patch: + operationId: updateNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNotificationTemplate' + responses: + '201': + description: New immutable draft version created + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplate' /v1/control/applications/{application_id}/notification-templates/{template_id}/preview: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: previewNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Safely rendered preview without delivery } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: previewNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PreviewNotificationTemplate' + responses: + '200': + description: Safely rendered preview without delivery + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationTemplatePreview' /v1/control/applications/{application_id}/notification-templates/{template_id}/publish: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: publishNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Template version published and predecessor archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: publishNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Template version published and predecessor archived /v1/control/applications/{application_id}/notification-templates/{template_id}/archive: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: template_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: archiveNotificationTemplate, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Template version archived } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: template_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: archiveNotificationTemplate + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Template version archived /v1/control/applications/{application_id}/notifications: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listNotifications, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: queueNotification, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/QueueNotification" } } } }, responses: { "202": { description: Rendered locale-aware template snapshot queued or suppressed by preference, content: { application/json: { schema: { $ref: "#/components/schemas/QueuedNotification" } } } } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listNotifications + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listNotifications response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationPage' /v1/control/applications/{application_id}/notifications/statistics: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: getNotificationStatistics, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Notification and attempt status totals } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: getNotificationStatistics + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Notification and attempt status totals + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationStatistics' /v1/control/applications/{application_id}/notifications/{notification_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: notification_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - get: { operationId: getNotification, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: "Notification metadata, attachment metadata, and attempts without encrypted payload" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: notification_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + get: + operationId: getNotification + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Notification metadata, attachment metadata, and attempts without encrypted payload + content: + application/json: + schema: + $ref: '#/components/schemas/Notification' /v1/control/applications/{application_id}/notifications/{notification_id}/retry: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: notification_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: retryNotification, tags: [Events], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Notification queued for retry } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: notification_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: retryNotification + tags: + - Events + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Notification queued for retry /v1/applications/{application_id}/me/notification-preferences: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyNotificationPreferences, tags: [Events], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyNotificationPreferences + tags: + - Events + responses: + '200': + description: Successful listMyNotificationPreferences response. + content: + application/json: + schema: + $ref: '#/components/schemas/NotificationPreferencePage' /v1/applications/{application_id}/me/notification-preferences/{category}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { name: category, in: path, required: true, schema: { enum: [transactional, billing, product, marketing] } }] - put: { operationId: updateMyNotificationPreference, tags: [Events], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "204": { description: Email preference updated; security remains mandatory } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - name: category + in: path + required: true + schema: + enum: + - transactional + - billing + - product + - marketing + put: + operationId: updateMyNotificationPreference + tags: + - Events + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateNotificationPreference' + responses: + '204': + description: Email preference updated; security remains mandatory /v1/control/installation/storage/providers: - get: { operationId: listInstallationStorageProviders, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/StorageProvider" }, responses: { "201": { description: Storage provider stored without exposing credentials } } } + get: + operationId: listInstallationStorageProviders + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationStorageProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderPage' + post: + operationId: createInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/StorageProviderBody' + responses: + '201': + description: Storage provider stored without exposing credentials + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' /v1/control/installation/storage/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free storage provider } } } - patch: { operationId: updateInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Storage provider updated and marked unverified } } } - delete: { operationId: disableInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ConfirmAffectedObjects" }], responses: { "204": { description: Provider disabled in Platform93 }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free storage provider + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + patch: + operationId: updateInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateStorageProvider' + responses: + '200': + description: Storage provider updated and marked unverified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + delete: + operationId: disableInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ConfirmAffectedObjects' + responses: + '204': + description: Provider disabled in Platform93 + '409': + $ref: '#/components/responses/Problem' /v1/control/installation/storage/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Credentials and bucket visibility verified }, "502": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Credentials and bucket visibility verified + '502': + $ref: '#/components/responses/Problem' /v1/control/installation/storage/providers/{provider_id}/enable: - parameters: [{ $ref: "#/components/parameters/ProviderID" }] - post: { operationId: enableInstallationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Provider re-enabled } } } + parameters: + - $ref: '#/components/parameters/ProviderID' + post: + operationId: enableInstallationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Provider re-enabled + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderStatus' /v1/control/organizations/{organization_id}/storage/providers: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationStorageProviders, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/StorageProvider" }, responses: { "201": { description: Organization storage override stored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationStorageProviders + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationStorageProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderPage' + post: + operationId: createOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/StorageProviderBody' + responses: + '201': + description: Organization storage override stored + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' /v1/control/organizations/{organization_id}/storage/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free storage provider } } } - patch: { operationId: updateOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Storage provider updated and marked unverified } } } - delete: { operationId: disableOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ConfirmAffectedObjects" }], responses: { "204": { description: Provider disabled in Platform93 }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free storage provider + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + patch: + operationId: updateOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateStorageProvider' + responses: + '200': + description: Storage provider updated and marked unverified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + delete: + operationId: disableOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ConfirmAffectedObjects' + responses: + '204': + description: Provider disabled in Platform93 + '409': + $ref: '#/components/responses/Problem' /v1/control/organizations/{organization_id}/storage/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Credentials and bucket visibility verified } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Credentials and bucket visibility verified /v1/control/organizations/{organization_id}/storage/providers/{provider_id}/enable: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: enableOrganizationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Provider re-enabled } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: enableOrganizationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Provider re-enabled + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderStatus' /v1/control/applications/{application_id}/storage/providers: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationStorageProviders, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: createApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/StorageProvider" }, responses: { "201": { description: Application storage override stored } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationStorageProviders + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listApplicationStorageProviders response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderPage' + post: + operationId: createApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + $ref: '#/components/requestBodies/StorageProviderBody' + responses: + '201': + description: Application storage override stored + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' /v1/control/applications/{application_id}/storage/providers/{provider_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - get: { operationId: getApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Secret-free storage provider } } } - patch: { operationId: updateApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], requestBody: { $ref: "#/components/requestBodies/Object" }, responses: { "200": { description: Storage provider updated and marked unverified } } } - delete: { operationId: disableApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ConfirmAffectedObjects" }], responses: { "204": { description: Provider disabled in Platform93 }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + get: + operationId: getApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Secret-free storage provider + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + patch: + operationId: updateApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateStorageProvider' + responses: + '200': + description: Storage provider updated and marked unverified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProvider' + delete: + operationId: disableApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ConfirmAffectedObjects' + responses: + '204': + description: Provider disabled in Platform93 + '409': + $ref: '#/components/responses/Problem' /v1/control/applications/{application_id}/storage/providers/{provider_id}/verify: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: verifyApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "204": { description: Credentials and bucket visibility verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: verifyApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '204': + description: Credentials and bucket visibility verified /v1/control/applications/{application_id}/storage/providers/{provider_id}/enable: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ProviderID" }] - post: { operationId: enableApplicationStorageProvider, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Provider re-enabled } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ProviderID' + post: + operationId: enableApplicationStorageProvider + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Provider re-enabled + content: + application/json: + schema: + $ref: '#/components/schemas/StorageProviderStatus' /v1/control/installation/storage/uploads: - post: { operationId: createInstallationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned installation asset upload, content: { application/json: { schema: { $ref: "#/components/schemas/StorageUploadAuthorization" } } } } } } + post: + operationId: createInstallationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned installation asset upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/control/installation/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeInstallationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeInstallationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/control/installation/storage/objects: - get: { operationId: listInstallationStorageObjects, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + get: + operationId: listInstallationStorageObjects + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listInstallationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/control/installation/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getInstallationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Installation asset metadata } } } - delete: { operationId: deleteInstallationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ForceDelete" }], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getInstallationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Installation asset metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteInstallationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ForceDelete' + responses: + '204': + description: Deletion queued /v1/control/installation/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadInstallationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadInstallationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/control/organizations/{organization_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: listOrganizationStorageObjects, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: listOrganizationStorageObjects + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listOrganizationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/control/organizations/{organization_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getOrganizationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Organization object metadata } } } - delete: { operationId: deleteOrganizationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ForceDelete" }], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getOrganizationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Organization object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteOrganizationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ForceDelete' + responses: + '204': + description: Deletion queued /v1/control/organizations/{organization_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadOrganizationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadOrganizationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/control/applications/{application_id}/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createControlApplicationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned application asset upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createControlApplicationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned application asset upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/control/applications/{application_id}/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeControlApplicationStorageUpload, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeControlApplicationStorageUpload + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/control/applications/{application_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listControlApplicationStorageObjects, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listControlApplicationStorageObjects + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Successful listControlApplicationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/control/applications/{application_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getControlApplicationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Application object metadata } } } - delete: { operationId: deleteControlApplicationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], parameters: [{ $ref: "#/components/parameters/ForceDelete" }], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getControlApplicationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Application object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteControlApplicationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + parameters: + - $ref: '#/components/parameters/ForceDelete' + responses: + '204': + description: Deletion queued /v1/control/applications/{application_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadControlApplicationStorageObject, tags: [Storage], security: [{ operatorBearer: [] }, { operatorCookie: [] }], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadControlApplicationStorageObject + tags: + - Storage + security: + - controlBearer: [] + - controlCookie: [] + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/applications/{application_id}/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createApplicationStorageUpload, tags: [Storage], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned application-owned upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createApplicationStorageUpload + tags: + - Storage + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned application-owned upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/applications/{application_id}/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeApplicationStorageUpload, tags: [Storage], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeApplicationStorageUpload + tags: + - Storage + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/applications/{application_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listApplicationStorageObjects, tags: [Storage], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listApplicationStorageObjects + tags: + - Storage + responses: + '200': + description: Successful listApplicationStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/applications/{application_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getApplicationStorageObject, tags: [Storage], responses: { "200": { description: Application object metadata } } } - delete: { operationId: deleteApplicationStorageObject, tags: [Storage], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getApplicationStorageObject + tags: + - Storage + responses: + '200': + description: Application object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteApplicationStorageObject + tags: + - Storage + responses: + '204': + description: Deletion queued /v1/applications/{application_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadApplicationStorageObject, tags: [Storage], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadApplicationStorageObject + tags: + - Storage + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/applications/{application_id}/me/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - post: { operationId: createMyStorageUpload, tags: [Storage], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned user-owned upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + post: + operationId: createMyStorageUpload + tags: + - Storage + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned user-owned upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/applications/{application_id}/me/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeMyStorageUpload, tags: [Storage], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeMyStorageUpload + tags: + - Storage + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/applications/{application_id}/me/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }] - get: { operationId: listMyStorageObjects, tags: [Storage], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + get: + operationId: listMyStorageObjects + tags: + - Storage + responses: + '200': + description: Successful listMyStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/applications/{application_id}/me/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getMyStorageObject, tags: [Storage], responses: { "200": { description: User object metadata } } } - delete: { operationId: deleteMyStorageObject, tags: [Storage], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getMyStorageObject + tags: + - Storage + responses: + '200': + description: User object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteMyStorageObject + tags: + - Storage + responses: + '204': + description: Deletion queued /v1/applications/{application_id}/me/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadMyStorageObject, tags: [Storage], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadMyStorageObject + tags: + - Storage + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/uploads: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }] - post: { operationId: createWorkspaceStorageUpload, tags: [Storage], parameters: [{ $ref: "#/components/parameters/RequiredIdempotencyKey" }], requestBody: { $ref: "#/components/requestBodies/StorageUpload" }, responses: { "201": { description: Presigned workspace-owned upload } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + post: + operationId: createWorkspaceStorageUpload + tags: + - Storage + parameters: + - $ref: '#/components/parameters/RequiredIdempotencyKey' + requestBody: + $ref: '#/components/requestBodies/StorageUpload' + responses: + '201': + description: Presigned workspace-owned upload + content: + application/json: + schema: + $ref: '#/components/schemas/StorageUploadAuthorization' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/uploads/{object_id}/complete: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: completeWorkspaceStorageUpload, tags: [Storage], responses: { "200": { description: Upload verified } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: completeWorkspaceStorageUpload + tags: + - Storage + responses: + '200': + description: Upload verified + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }] - get: { operationId: listWorkspaceStorageObjects, tags: [Storage], responses: { "200": { $ref: "#/components/responses/Page" } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + get: + operationId: listWorkspaceStorageObjects + tags: + - Storage + responses: + '200': + description: Successful listWorkspaceStorageObjects response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObjectPage' /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects/{object_id}: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }, { $ref: "#/components/parameters/ObjectID" }] - get: { operationId: getWorkspaceStorageObject, tags: [Storage], responses: { "200": { description: Workspace object metadata } } } - delete: { operationId: deleteWorkspaceStorageObject, tags: [Storage], responses: { "204": { description: Deletion queued } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/ObjectID' + get: + operationId: getWorkspaceStorageObject + tags: + - Storage + responses: + '200': + description: Workspace object metadata + content: + application/json: + schema: + $ref: '#/components/schemas/StorageObject' + delete: + operationId: deleteWorkspaceStorageObject + tags: + - Storage + responses: + '204': + description: Deletion queued /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects/{object_id}/download: - parameters: [{ $ref: "#/components/parameters/ApplicationID" }, { $ref: "#/components/parameters/WorkspaceID" }, { $ref: "#/components/parameters/ObjectID" }] - post: { operationId: downloadWorkspaceStorageObject, tags: [Storage], responses: { "200": { description: Public or short-lived private URL } } } + parameters: + - $ref: '#/components/parameters/ApplicationID' + - $ref: '#/components/parameters/WorkspaceID' + - $ref: '#/components/parameters/ObjectID' + post: + operationId: downloadWorkspaceStorageObject + tags: + - Storage + responses: + '200': + description: Public or short-lived private URL + content: + application/json: + schema: + $ref: '#/components/schemas/StorageDownload' /oidc/.well-known/openid-configuration: - get: { operationId: oidcDiscovery, tags: [Identity], security: [], responses: { "200": { description: OpenID Provider metadata } } } + get: + operationId: oidcDiscovery + tags: + - Identity + security: [] + responses: + '200': + description: OpenID Provider metadata + content: + application/json: + schema: + $ref: '#/components/schemas/OIDCDiscovery' /oidc/jwks.json: - get: { operationId: oidcJWKS, tags: [Identity], security: [], responses: { "200": { description: Active and retiring JSON Web Keys } } } + get: + operationId: oidcJWKS + tags: + - Identity + security: [] + responses: + '200': + description: Active and retiring JSON Web Keys + content: + application/json: + schema: + $ref: '#/components/schemas/JWKS' /oidc/authorize: - get: { operationId: beginOIDCAuthorization, tags: [Identity], security: [], parameters: [{ $ref: "#/components/parameters/OAuthClientID" }, { $ref: "#/components/parameters/OAuthRedirectURI" }, { $ref: "#/components/parameters/OAuthResponseType" }, { $ref: "#/components/parameters/OAuthScope" }, { $ref: "#/components/parameters/OAuthState" }, { $ref: "#/components/parameters/OAuthCodeChallenge" }, { $ref: "#/components/parameters/OAuthCodeChallengeMethod" }], responses: { "200": { description: Headless consent interaction }, "302": { description: Authorization response redirect } } } - post: { operationId: decideOIDCAuthorization, tags: [Identity], security: [{ bearerAuth: [] }], requestBody: { $ref: "#/components/requestBodies/OAuthAuthorizationDecision" }, responses: { "200": { description: Headless authorization response containing redirect_to when JSON is requested }, "302": { description: Authorization response redirect } } } + get: + operationId: beginOIDCAuthorization + tags: + - Identity + security: [] + parameters: + - $ref: '#/components/parameters/OAuthClientID' + - $ref: '#/components/parameters/OAuthRedirectURI' + - $ref: '#/components/parameters/OAuthResponseType' + - $ref: '#/components/parameters/OAuthScope' + - $ref: '#/components/parameters/OAuthState' + - $ref: '#/components/parameters/OAuthCodeChallenge' + - $ref: '#/components/parameters/OAuthCodeChallengeMethod' + responses: + '200': + description: Headless consent interaction + content: + application/json: + schema: + $ref: '#/components/schemas/AuthorizationRedirect' + '302': + description: Authorization response redirect + post: + operationId: decideOIDCAuthorization + tags: + - Identity + security: + - bearerAuth: [] + requestBody: + $ref: '#/components/requestBodies/OAuthAuthorizationDecision' + responses: + '200': + description: Headless authorization response containing redirect_to when JSON is requested + content: + application/json: + schema: + $ref: '#/components/schemas/AuthorizationRedirect' + '302': + description: Authorization response redirect /oidc/token: - post: { operationId: exchangeOIDCToken, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/OAuthToken" }, responses: { "200": { description: OAuth token response }, "400": { description: OAuth error response } } } + post: + operationId: exchangeOIDCToken + tags: + - Identity + security: [] + requestBody: + $ref: '#/components/requestBodies/OAuthToken' + responses: + '200': + description: OAuth token response + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + '400': + description: OAuth error response /oidc/revoke: - post: { operationId: revokeOIDCToken, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/OAuthTokenCredential" }, responses: { "200": { description: Token revoked or already inactive } } } + post: + operationId: revokeOIDCToken + tags: + - Identity + security: [] + requestBody: + $ref: '#/components/requestBodies/OAuthTokenCredential' + responses: + '200': + description: Token revoked or already inactive + content: + application/json: + schema: + $ref: '#/components/schemas/EmptyResponse' /oidc/introspect: - post: { operationId: introspectOIDCToken, tags: [Identity], security: [], requestBody: { $ref: "#/components/requestBodies/OAuthTokenCredential" }, responses: { "200": { description: RFC 7662 token state } } } + post: + operationId: introspectOIDCToken + tags: + - Identity + security: [] + requestBody: + $ref: '#/components/requestBodies/OAuthTokenCredential' + responses: + '200': + description: RFC 7662 token state + content: + application/json: + schema: + $ref: '#/components/schemas/TokenIntrospection' /oidc/userinfo: - get: { operationId: oidcUserinfo, tags: [Identity], security: [{ bearerAuth: [] }], responses: { "200": { description: OpenID Connect claims }, "401": { $ref: "#/components/responses/Problem" } } } + get: + operationId: oidcUserinfo + tags: + - Identity + security: + - bearerAuth: [] + responses: + '200': + description: OpenID Connect claims + content: + application/json: + schema: + $ref: '#/components/schemas/UserInfo' + '401': + $ref: '#/components/responses/Problem' /provider-webhooks/stripe/{connection_public_id}: - post: { operationId: stripeWebhook, tags: [Billing], security: [], parameters: [{ name: connection_public_id, in: path, required: true, schema: { type: string } }, { name: Stripe-Signature, in: header, required: true, schema: { type: string } }], requestBody: { required: true, content: { application/json: { schema: {} } } }, responses: { "200": { description: Event stored and processed }, "400": { $ref: "#/components/responses/Problem" } } } + post: + operationId: stripeWebhook + tags: + - Billing + security: [] + parameters: + - name: connection_public_id + in: path + required: true + schema: + type: string + - name: Stripe-Signature + in: header + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: {} + responses: + '200': + description: Event stored and processed + content: + application/json: + schema: + $ref: '#/components/schemas/WebhookAcknowledgement' + '400': + $ref: '#/components/responses/Problem' /v1/management/organizations: - get: { operationId: managementListOrganizations, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: managementCreateOrganization, tags: [Management], security: [{ managementBearer: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Organization provisioned without an operator membership } } } + get: + operationId: managementListOrganizations + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Successful managementListOrganizations response. + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPage' + post: + operationId: managementCreateOrganization + tags: + - Management + security: + - managementBearer: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Organization provisioned without a Platform user membership + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' /v1/management/organizations/{organization_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: managementGetOrganization, tags: [Management], security: [{ managementBearer: [] }], responses: { "200": { description: Organization details } } } - patch: { operationId: managementUpdateOrganization, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Organization renamed } } } - delete: { operationId: managementRetireOrganization, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Organization retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: managementGetOrganization + tags: + - Management + security: + - managementBearer: [] + responses: + '200': + description: Organization details + content: + application/json: + schema: + $ref: '#/components/schemas/Organization' + patch: + operationId: managementUpdateOrganization + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Organization renamed + delete: + operationId: managementRetireOrganization + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Organization retired /v1/management/organizations/{organization_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - post: { operationId: managementRestoreOrganization, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Organization restored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + post: + operationId: managementRestoreOrganization + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Organization restored /v1/management/organizations/{organization_id}/policy: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: managementGetOrganizationPolicy, tags: [Management], security: [{ managementBearer: [] }], responses: { "200": { description: Organization policy and usage, content: { application/json: { schema: { $ref: "#/components/schemas/OrganizationPolicy" } } } } } } - put: { operationId: managementUpdateOrganizationPolicy, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UpdateOrganizationPolicy" } } } }, responses: { "204": { description: Organization policy updated } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: managementGetOrganizationPolicy + tags: + - Management + security: + - managementBearer: [] + responses: + '200': + description: Organization policy and usage + content: + application/json: + schema: + $ref: '#/components/schemas/OrganizationPolicy' + put: + operationId: managementUpdateOrganizationPolicy + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateOrganizationPolicy' + responses: + '204': + description: Organization policy updated /v1/management/organizations/{organization_id}/applications: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }] - get: { operationId: managementListApplications, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IncludeRetired" }], responses: { "200": { $ref: "#/components/responses/Page" } } } - post: { operationId: managementCreateApplication, tags: [Management], security: [{ managementBearer: [] }], requestBody: { $ref: "#/components/requestBodies/Named" }, responses: { "201": { description: Application provisioned }, "409": { $ref: "#/components/responses/Problem" } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + get: + operationId: managementListApplications + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IncludeRetired' + responses: + '200': + description: Successful managementListApplications response. + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationPage' + post: + operationId: managementCreateApplication + tags: + - Management + security: + - managementBearer: [] + requestBody: + $ref: '#/components/requestBodies/Named' + responses: + '201': + description: Application provisioned + content: + application/json: + schema: + $ref: '#/components/schemas/Application' + '409': + $ref: '#/components/responses/Problem' /v1/management/organizations/{organization_id}/applications/{application_resource_id}: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - patch: { operationId: managementUpdateApplication, tags: [Management], security: [{ managementBearer: [] }], parameters: [{ $ref: "#/components/parameters/IfMatch" }], requestBody: { $ref: "#/components/requestBodies/Rename" }, responses: { "204": { description: Application renamed } } } - delete: { operationId: managementRetireApplication, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Application retired } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + patch: + operationId: managementUpdateApplication + tags: + - Management + security: + - managementBearer: [] + parameters: + - $ref: '#/components/parameters/IfMatch' + requestBody: + $ref: '#/components/requestBodies/Rename' + responses: + '204': + description: Application renamed + delete: + operationId: managementRetireApplication + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Application retired /v1/management/organizations/{organization_id}/applications/{application_resource_id}/restore: - parameters: [{ $ref: "#/components/parameters/OrganizationID" }, { name: application_resource_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } }] - post: { operationId: managementRestoreApplication, tags: [Management], security: [{ managementBearer: [] }], responses: { "204": { description: Application restored } } } + parameters: + - $ref: '#/components/parameters/OrganizationID' + - name: application_resource_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + post: + operationId: managementRestoreApplication + tags: + - Management + security: + - managementBearer: [] + responses: + '204': + description: Application restored components: securitySchemes: - bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT-or-PAT } - operatorBearer: { type: http, scheme: bearer, bearerFormat: JWT } - operatorCookie: { type: apiKey, in: cookie, name: p93_operator_access } - managementBearer: { type: http, scheme: bearer, bearerFormat: Platform93-management-JWT, description: "Short-lived client-credentials token with actor_type=management_client and audience platform93:control." } + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT-or-PAT + controlBearer: + type: http + scheme: bearer + bearerFormat: JWT + controlCookie: + type: apiKey + in: cookie + name: p93_control_access + managementBearer: + type: http + scheme: bearer + bearerFormat: Platform93-management-JWT + description: Short-lived client-credentials token with actor_type=management_client and audience platform93:control. parameters: - ApplicationID: { name: application_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - WorkspaceID: { name: workspace_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - ObjectID: { name: object_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - ConfirmAffectedObjects: { name: confirm_affected_objects, in: query, required: false, schema: { type: boolean, default: false }, description: Required when disabling a provider pinned by live objects. } - ForceDelete: { name: force, in: query, required: false, schema: { type: boolean, default: false }, description: Break managed email-template references; requires X-Audit-Reason. } - WorkspaceIDQuery: { name: workspace_id, in: query, required: false, description: Explicit accessible workspace whose grants are merged with the current user's grants., schema: { $ref: "#/components/schemas/UUID" } } - OrganizationID: { name: organization_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - IncludeRetired: { name: include_retired, in: query, schema: { type: boolean, default: false } } - IfMatch: { name: If-Match, in: header, required: true, schema: { type: string }, description: Current resource ETag. } - IdempotencyKey: { name: Idempotency-Key, in: header, required: false, schema: { type: string, minLength: 8, maxLength: 255 } } - RequiredIdempotencyKey: { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 8, maxLength: 255 } } - ProviderID: { name: provider_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - SessionID: { name: session_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - SubscriptionID: { name: subscription_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - PaymentID: { name: payment_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - RequestID: { name: request_id, in: path, required: true, schema: { $ref: "#/components/schemas/UUID" } } - OAuthClientID: { name: client_id, in: query, required: true, schema: { type: string } } - OAuthRedirectURI: { name: redirect_uri, in: query, required: true, schema: { type: string, format: uri } } - OAuthResponseType: { name: response_type, in: query, required: true, schema: { type: string, const: code } } - OAuthScope: { name: scope, in: query, required: true, schema: { type: string } } - OAuthState: { name: state, in: query, required: true, schema: { type: string, minLength: 8 } } - OAuthCodeChallenge: { name: code_challenge, in: query, required: true, schema: { type: string, minLength: 43, maxLength: 128 } } - OAuthCodeChallengeMethod: { name: code_challenge_method, in: query, required: true, schema: { type: string, const: S256 } } + ApplicationID: + name: application_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + WorkspaceID: + name: workspace_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + ObjectID: + name: object_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + ConfirmAffectedObjects: + name: confirm_affected_objects + in: query + required: false + schema: + type: boolean + default: false + description: Required when disabling a provider pinned by live objects. + ForceDelete: + name: force + in: query + required: false + schema: + type: boolean + default: false + description: Break managed email-template references; requires X-Audit-Reason. + WorkspaceIDQuery: + name: workspace_id + in: query + required: false + description: Explicit accessible workspace whose grants are merged with the current user's grants. + schema: + $ref: '#/components/schemas/UUID' + PermissionSubjectType: + name: subject_type + in: query + required: true + schema: + type: string + enum: + - user + - client + PermissionSubjectID: + name: subject_id + in: query + required: true + schema: + $ref: '#/components/schemas/UUID' + OrganizationID: + name: organization_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + IncludeRetired: + name: include_retired + in: query + schema: + type: boolean + default: false + IfMatch: + name: If-Match + in: header + required: true + schema: + type: string + description: Current resource ETag. + IdempotencyKey: + name: Idempotency-Key + in: header + required: false + schema: + type: string + minLength: 8 + maxLength: 255 + RequiredIdempotencyKey: + name: Idempotency-Key + in: header + required: true + schema: + type: string + minLength: 8 + maxLength: 255 + ProviderID: + name: provider_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + SessionID: + name: session_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + SubscriptionID: + name: subscription_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + PaymentID: + name: payment_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + RequestID: + name: request_id + in: path + required: true + schema: + $ref: '#/components/schemas/UUID' + OAuthClientID: + name: client_id + in: query + required: true + schema: + type: string + OAuthRedirectURI: + name: redirect_uri + in: query + required: true + schema: + type: string + format: uri + OAuthResponseType: + name: response_type + in: query + required: true + schema: + type: string + const: code + OAuthScope: + name: scope + in: query + required: true + schema: + type: string + OAuthState: + name: state + in: query + required: true + schema: + type: string + minLength: 8 + OAuthCodeChallenge: + name: code_challenge + in: query + required: true + schema: + type: string + minLength: 43 + maxLength: 128 + OAuthCodeChallengeMethod: + name: code_challenge_method + in: query + required: true + schema: + type: string + const: S256 + OptionalPermissionSubjectType: + name: subject_type + in: query + required: false + schema: + type: string + enum: + - user + - client + OptionalPermissionSubjectID: + name: subject_id + in: query + required: false + schema: + $ref: '#/components/schemas/UUID' + PermissionGrantStatus: + name: status + in: query + required: false + schema: + type: string + enum: + - active + - revoked requestBodies: - Named: { required: true, content: { application/json: { schema: { type: object, required: [name, slug], properties: { name: { type: string }, slug: { type: string, pattern: "^[a-z][a-z0-9-]{1,62}[a-z0-9]$" } } } } } } - Rename: { required: true, content: { application/json: { schema: { type: object, required: [name], properties: { name: { type: string, minLength: 1, maxLength: 255 } }, additionalProperties: false } } } } - Object: { required: true, content: { application/json: { schema: { type: object } } } } - ProviderInheritance: { required: true, content: { application/json: { schema: { type: object, required: [inheritable], properties: { inheritable: { type: boolean, description: Allow child scopes to resolve this provider. } }, additionalProperties: false } } } } - ApplicationAuthConfig: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ApplicationAuthConfig" } } } } - PublicApplicationConfig: { required: true, content: { application/json: { schema: { type: object, additionalProperties: true, description: "This entire object is returned by the unauthenticated runtime-config endpoint. Secrets are forbidden." } } } } - InternalApplicationConfig: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ApplicationInternalConfig" } } } } - RoleAssignment: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/RoleAssignment" } } } } - OwnershipTransfer: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/OwnershipTransfer" } } } } - SMTPProvider: { required: true, content: { application/json: { schema: { type: object, required: [name, host, port, tls_mode, sender_email], properties: { name: { type: string }, host: { type: string }, port: { type: integer, minimum: 1, maximum: 65535 }, username: { type: string }, password: { type: string, writeOnly: true }, tls_mode: { enum: [starttls, implicit_tls] }, sender_email: { type: string, format: email }, sender_name: { type: string }, inheritable: { type: boolean, default: false } } } } } } - StorageProvider: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateStorageProvider" } } } } - StorageUpload: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateStorageUpload" } } } } - OAuthAuthorizationDecision: { required: true, content: { application/x-www-form-urlencoded: { schema: { type: object, required: [client_id, redirect_uri, response_type, scope, state, code_challenge, code_challenge_method, decision], properties: { client_id: { type: string }, redirect_uri: { type: string, format: uri }, response_type: { type: string, const: code }, scope: { type: string }, state: { type: string }, nonce: { type: string }, code_challenge: { type: string }, code_challenge_method: { type: string, const: S256 }, decision: { enum: [grant, deny] } } } } } } - OAuthToken: { required: true, content: { application/x-www-form-urlencoded: { schema: { type: object, required: [grant_type], properties: { grant_type: { enum: [authorization_code, refresh_token, client_credentials] }, code: { type: string }, redirect_uri: { type: string, format: uri }, code_verifier: { type: string }, refresh_token: { type: string }, client_id: { type: string }, client_secret: { type: string, writeOnly: true }, scope: { type: string } } } } } } - OAuthTokenCredential: { required: true, content: { application/x-www-form-urlencoded: { schema: { type: object, required: [token], properties: { token: { type: string, writeOnly: true }, token_type_hint: { enum: [access_token, refresh_token] }, client_id: { type: string }, client_secret: { type: string, writeOnly: true } } } } } } + Named: + required: true + content: + application/json: + schema: + type: object + required: + - name + - slug + properties: + name: + type: string + slug: + type: string + pattern: ^[a-z][a-z0-9-]{1,62}[a-z0-9]$ + Rename: + required: true + content: + application/json: + schema: + type: object + required: + - name + properties: + name: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false + ProviderInheritance: + required: true + content: + application/json: + schema: + type: object + required: + - inheritable + properties: + inheritable: + type: boolean + description: Allow child scopes to resolve this provider. + additionalProperties: false + ApplicationAuthConfig: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationAuthConfig' + PublicApplicationConfig: + required: true + content: + application/json: + schema: + type: object + additionalProperties: true + description: This entire object is returned by the unauthenticated runtime-config endpoint. Secrets are forbidden. + InternalApplicationConfig: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationInternalConfig' + RoleAssignment: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/RoleAssignment' + PermissionGrantBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePermissionGrant' + OwnershipTransfer: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/OwnershipTransfer' + SMTPProvider: + required: true + content: + application/json: + schema: + type: object + required: + - name + - host + - port + - tls_mode + - sender_email + properties: + name: + type: string + host: + type: string + port: + type: integer + minimum: 1 + maximum: 65535 + username: + type: string + password: + type: string + writeOnly: true + tls_mode: + enum: + - starttls + - implicit_tls + sender_email: + type: string + format: email + sender_name: + type: string + inheritable: + type: boolean + default: false + StorageProviderBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateStorageProvider' + StorageUpload: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateStorageUpload' + OAuthAuthorizationDecision: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - client_id + - redirect_uri + - response_type + - scope + - state + - code_challenge + - code_challenge_method + - decision + properties: + client_id: + type: string + redirect_uri: + type: string + format: uri + response_type: + type: string + const: code + scope: + type: string + state: + type: string + nonce: + type: string + code_challenge: + type: string + code_challenge_method: + type: string + const: S256 + decision: + enum: + - grant + - deny + OAuthToken: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - grant_type + properties: + grant_type: + enum: + - authorization_code + - refresh_token + - client_credentials + code: + type: string + redirect_uri: + type: string + format: uri + code_verifier: + type: string + refresh_token: + type: string + client_id: + type: string + client_secret: + type: string + writeOnly: true + scope: + type: string + OAuthTokenCredential: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: + - token + properties: + token: + type: string + writeOnly: true + token_type_hint: + enum: + - access_token + - refresh_token + client_id: + type: string + client_secret: + type: string + writeOnly: true responses: - Problem: { description: RFC 9457 problem, content: { application/problem+json: { schema: { $ref: "#/components/schemas/Problem" } } } } - Page: { description: Cursor page, content: { application/json: { schema: { $ref: "#/components/schemas/Page" } } } } - Tokens: { description: Rotating user session, content: { application/json: { schema: { $ref: "#/components/schemas/TokenResponse" } } } } - OwnershipTransferResult: { description: Workspace ownership transferred atomically, content: { application/json: { schema: { $ref: "#/components/schemas/OwnershipTransferResult" } } } } + Problem: + description: RFC 9457 problem + content: + application/problem+json: + schema: + $ref: '#/components/schemas/Problem' + Tokens: + description: Rotating user session + content: + application/json: + schema: + $ref: '#/components/schemas/TokenResponse' + OwnershipTransferResult: + description: Workspace ownership transferred atomically + content: + application/json: + schema: + $ref: '#/components/schemas/OwnershipTransferResult' schemas: - ManagementAPIStatus: + HealthStatus: type: object - required: [enabled, can_manage, active_clients, token_endpoint, api_base] + required: + - status properties: - enabled: { type: boolean } - can_manage: { type: boolean } - active_clients: { type: integer, minimum: 0 } - token_endpoint: { type: string, format: uri } - api_base: { type: string, format: uri } + status: + type: string + enum: + - ok + - ready additionalProperties: false - CreateManagementClient: + VersionInfo: type: object - required: [client_id, name] + required: + - version + - commit + - built_at + - schema properties: - client_id: { type: string, minLength: 1, maxLength: 160 } - name: { type: string, minLength: 1, maxLength: 200 } - allowed_scopes: { type: array, items: { type: string, const: /management/organizations/* }, default: [/management/organizations/*] } + version: + type: string + commit: + type: string + built_at: + type: string + schema: + type: string additionalProperties: false - OrganizationEnabledSettings: + SetupStatus: type: object - required: [public_registration, password_authentication, passwordless_authentication, personal_api_keys, delegation, organization_provider_overrides, application_provider_overrides, custom_events, webhooks] + required: + - available + - control_user_email_login_available + - control_auth_methods properties: - public_registration: { type: boolean } - password_authentication: { type: boolean } - passwordless_authentication: { type: boolean } - personal_api_keys: { type: boolean } - delegation: { type: boolean } - organization_provider_overrides: { type: boolean } - application_provider_overrides: { type: boolean } - custom_events: { type: boolean } - webhooks: { type: boolean } + available: + type: boolean + control_user_email_login_available: + type: boolean + control_auth_methods: + $ref: '#/components/schemas/ControlAuthMethods' additionalProperties: false - UpdateOrganizationPolicy: + SetupSession: type: object - required: [max_applications, max_users, enabled_settings] + required: + - access_token + - refresh_token + - token_type + - expires_in + - control_user_id properties: - max_applications: { type: [integer, "null"], minimum: 0, description: Null means unlimited. } - max_users: { type: [integer, "null"], minimum: 0, description: Null means unlimited across all applications in the organization. } - enabled_settings: { $ref: "#/components/schemas/OrganizationEnabledSettings" } + access_token: + type: string + writeOnly: true + refresh_token: + type: string + writeOnly: true + token_type: + const: Bearer + expires_in: + type: integer + control_user_id: + $ref: '#/components/schemas/UUID' additionalProperties: false - OrganizationPolicy: - allOf: - - { $ref: "#/components/schemas/UpdateOrganizationPolicy" } - - type: object - required: [organization_id, usage, version] - properties: - organization_id: { $ref: "#/components/schemas/UUID" } - usage: - type: object - required: [applications, users] - properties: - applications: { type: integer, minimum: 0 } - users: { type: integer, minimum: 0 } - additionalProperties: false - version: { type: integer, format: int64, minimum: 1 } - UUID: { type: string, format: uuid } - CreateStorageProvider: + SetupCompletion: type: object - required: [name, endpoint, region, access_key_id, secret_access_key] - properties: - name: { type: string, minLength: 1, maxLength: 200 } - endpoint: { type: string, format: uri, maxLength: 2000 } - region: { type: string, minLength: 1, maxLength: 100 } - access_key_id: { type: string, minLength: 1, writeOnly: true } - secret_access_key: { type: string, minLength: 1, writeOnly: true } - force_path_style: { type: boolean, default: false } - public_bucket: { type: string, minLength: 1 } - private_bucket: { type: string, minLength: 1 } - public_base_url: { type: string, format: uri } - inheritable: { type: boolean, default: false } - allow_private_endpoint: { type: boolean, default: false, description: Installation-scoped opt-in for local or private-network S3 endpoints. } - max_object_bytes: { type: integer, format: int64, minimum: 1, default: 26214400 } - max_email_image_bytes: { type: integer, format: int64, minimum: 1, default: 2097152 } - max_application_bytes: { type: integer, format: int64, minimum: 1, default: 10737418240 } - max_application_objects: { type: integer, format: int64, minimum: 1, default: 100000 } - anyOf: [{ required: [public_bucket] }, { required: [private_bucket] }] + required: + - access_token + - refresh_token + - token_type + - expires_in + - completed + properties: + access_token: + type: string + writeOnly: true + refresh_token: + type: string + writeOnly: true + token_type: + const: Bearer + expires_in: + type: integer + completed: + type: boolean + const: true additionalProperties: false - CreateStorageUpload: + ChallengeAccepted: type: object - required: [filename, content_type, size_bytes, visibility] + required: + - challenge_id + - expires_in properties: - filename: { type: string, minLength: 1, maxLength: 500 } - content_type: { type: string, minLength: 1, maxLength: 255 } - size_bytes: { type: integer, format: int64, minimum: 1 } - visibility: { enum: [public, private] } - purpose: { enum: [email_image] } - metadata: { type: object, additionalProperties: true } + challenge_id: + $ref: '#/components/schemas/UUID' + expires_in: + type: integer + minimum: 1 additionalProperties: false - StorageObject: + NotificationQueued: type: object - required: [id, provider_id, owner_type, visibility, filename, content_type, size_bytes, metadata, status, version, created_at, updated_at] - properties: - id: { $ref: "#/components/schemas/UUID" } - application_id: { type: [string, "null"], format: uuid } - provider_id: { $ref: "#/components/schemas/UUID" } - owner_type: { enum: [installation, application, user, workspace] } - owner_id: { type: [string, "null"], format: uuid } - visibility: { enum: [public, private] } - filename: { type: string } - content_type: { type: string } - size_bytes: { type: integer, format: int64 } - etag: { type: [string, "null"] } - metadata: { type: object, additionalProperties: true } - status: { enum: [pending, ready, deleting, failed] } - public_url: { type: [string, "null"], format: uri } - upload_expires_at: { type: [string, "null"], format: date-time } - ready_at: { type: [string, "null"], format: date-time } - last_error: { type: [string, "null"] } - version: { type: integer, format: int64 } + required: + - notification_id + - status + properties: + notification_id: + $ref: '#/components/schemas/UUID' + status: + type: string + const: queued + additionalProperties: false + InvitationResent: + type: object + required: + - id + - last_sent_at + - resend_available_at + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + last_sent_at: + type: string + format: date-time + resend_available_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + additionalProperties: false + ReconciliationAccepted: + type: object + required: + - id + - provider_id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + status: + type: string + const: pending + additionalProperties: false + WebhookTestAccepted: + type: object + required: + - event_id + - delivery_id + - status + properties: + event_id: + $ref: '#/components/schemas/UUID' + delivery_id: + $ref: '#/components/schemas/UUID' + status: + type: string + const: pending + additionalProperties: false + ControlUserAccount: + type: object + required: + - id + - email + - display_name + - status + - installation_role + - organizations + - sign_in_methods + - created_at + - updated_at + properties: + id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + display_name: + type: string + status: + enum: + - active + - suspended + - deleted + installation_role: + type: [string, 'null'] + enum: [owner, admin, auditor, null] + organizations: + type: array + items: + type: object + required: [id, name, role] + properties: + id: { $ref: '#/components/schemas/UUID' } + name: { type: string } + role: { enum: [owner, admin, member, auditor] } + additionalProperties: false + sign_in_methods: + type: object + required: [email_code, magic_link, password, external_identities] + properties: + email_code: { type: boolean } + magic_link: { type: boolean } + password: { type: boolean } + external_identities: + type: array + items: + type: object + required: [id, provider, metadata, available, created_at] + properties: + id: { $ref: '#/components/schemas/UUID' } + provider: { enum: [google, apple] } + metadata: { type: object, additionalProperties: true } + available: { type: boolean } + created_at: { type: string, format: date-time } + last_used_at: { type: [string, 'null'], format: date-time } + additionalProperties: false + additionalProperties: false created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } additionalProperties: false + Session: + type: object + required: + - id + - actor_type + - created_at + - expires_at + - revoked + properties: + id: + $ref: '#/components/schemas/UUID' + actor_type: + enum: + - control_user + - user + - client + user_agent: + type: + - string + - 'null' + ip_address: + type: + - string + - 'null' + amr: + type: array + items: + type: string + authenticated_at: + type: + - string + - 'null' + format: date-time + created_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + revoked: + type: boolean + additionalProperties: false + NotificationProvider: + type: object + required: + - id + - provider + - scope + - name + - sender_email + - sender_name + - inheritable + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + type: string + const: smtp + scope: + enum: + - installation + - organization + - application + organization_id: + type: + - string + - 'null' + format: uuid + application_id: + type: + - string + - 'null' + format: uuid + name: + type: string + sender_email: + type: string + format: email + sender_name: + type: string + inheritable: + type: boolean + verified: + type: boolean + credentials_configured: + type: boolean + effective: + type: boolean + verified_at: + type: + - string + - 'null' + format: date-time + disabled_at: + type: [string, 'null'] + format: date-time + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + AuthProvider: + type: object + required: + - id + - provider + - scope + - client_id + - inheritable + - control_login_enabled + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + enum: + - google + - apple + scope: + enum: + - installation + - organization + - application + organization_id: + type: + - string + - 'null' + format: uuid + application_id: + type: + - string + - 'null' + format: uuid + client_id: + type: string + team_id: + type: + - string + - 'null' + key_id: + type: + - string + - 'null' + inheritable: + type: boolean + control_login_enabled: + type: boolean + configured: + type: boolean + inherited: + type: boolean + linked_control_users: + type: integer + minimum: 0 + inheriting_applications: + type: integer + minimum: 0 + callback_uri: + type: string + format: uri + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + BillingProvider: + type: object + required: + - id + - provider + - public_id + - api_version + - status + - scope + - inheritable + - webhook_uri + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + type: string + const: stripe + public_id: + type: string + api_version: + type: string + status: + enum: + - active + - disabled + - error + scope: + enum: + - installation + - organization + - application + inheritable: + type: boolean + organization_id: + type: [string, 'null'] + format: uuid + application_id: + type: [string, 'null'] + format: uuid + inherited: + type: boolean + webhook_configured: + type: boolean + effective: + type: boolean + metadata: + type: object + additionalProperties: true + webhook_uri: + type: string + format: uri + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + ControlUser: + type: object + required: + - id + - email + - display_name + - status + - role + properties: + id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + display_name: + type: string + status: + enum: + - active + - suspended + - deleted + role: + enum: + - owner + - admin + - member + - auditor + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + ControlUserInvitation: + type: object + required: + - id + - email + - role + - onboarding_method + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + organization_id: + type: + - string + - 'null' + format: uuid + email: + type: string + format: email + role: + enum: + - owner + - admin + - member + - auditor + onboarding_method: + enum: + - email + - google + - apple + status: + enum: + - pending + - accepted + - revoked + - expired + expires_at: + type: string + format: date-time + invitation_token: + type: string + writeOnly: true + token_returned_once: + type: boolean + invited_by: + type: string + format: uuid + accepted_by: + type: [string, 'null'] + format: uuid + accepted_at: + type: [string, 'null'] + format: date-time + revoked_at: + type: [string, 'null'] + format: date-time + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + SigningKey: + type: object + required: + - id + - kid + - algorithm + - status + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + kid: + type: string + algorithm: + type: string + const: RS256 + status: + enum: + - active + - retiring + - retired + created_at: + type: string + format: date-time + retires_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + SecretCredential: + type: object + required: + - secret + - secret_returned_once + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + secret: + type: string + writeOnly: true + secret_returned_once: + type: boolean + previous_secret_valid_for_seconds: + type: integer + minimum: 0 + additionalProperties: false + ManagementClient: + type: object + required: + - id + - client_id + - name + - allowed_scopes + - status + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + name: + type: string + allowed_scopes: + type: array + items: + type: string + status: + enum: + - active + - disabled + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Organization: + type: object + required: + - id + - slug + - name + - version + properties: + id: + $ref: '#/components/schemas/UUID' + slug: + type: string + name: + type: string + version: + type: integer + format: int64 + role: + type: string + retired_at: + type: [string, 'null'] + format: date-time + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Application: + type: object + required: + - id + - organization_id + - slug + - name + - version + properties: + id: + $ref: '#/components/schemas/UUID' + organization_id: + $ref: '#/components/schemas/UUID' + slug: + type: string + name: + type: string + version: + type: integer + format: int64 + issuer: + type: string + format: uri + audience: + type: string + auth_config: + type: object + additionalProperties: true + public_config: + type: object + additionalProperties: true + internal_config: + type: object + additionalProperties: true + retired_at: + type: [string, 'null'] + format: date-time + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + ApplicationStatistics: + type: object + required: + - users + - workspaces + - active_products + - active_entitlements + - pending_local_requests + - live_subscriptions + - notification_failures + - webhook_failures + - events_last_24_hours + properties: + users: + type: object + required: [total, active, suspended] + properties: + total: { type: integer, minimum: 0 } + active: { type: integer, minimum: 0 } + suspended: { type: integer, minimum: 0 } + additionalProperties: false + workspaces: + type: integer + minimum: 0 + active_products: + type: integer + minimum: 0 + active_entitlements: + type: integer + minimum: 0 + pending_local_requests: + type: integer + minimum: 0 + live_subscriptions: + type: integer + minimum: 0 + notification_failures: + type: integer + minimum: 0 + webhook_failures: + type: integer + minimum: 0 + events_last_24_hours: + type: integer + minimum: 0 + additionalProperties: false + ApplicationDomain: + type: object + required: + - id + - hostname + - status + properties: + id: + $ref: '#/components/schemas/UUID' + hostname: + type: string + format: hostname + status: + enum: + - pending + - verified + - disabled + created_at: + type: string + format: date-time + additionalProperties: false + OAuthClient: + type: object + required: + - id + - client_id + - name + - client_type + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + name: + type: string + client_type: + enum: + - public + - confidential + - machine + redirect_uris: + type: array + items: + type: string + format: uri + post_logout_redirect_uris: + type: array + items: + type: string + format: uri + allowed_scopes: + type: array + items: + type: string + allowed_grants: + type: array + items: + type: string + client_secret: + type: [string, 'null'] + writeOnly: true + secret: + type: string + writeOnly: true + secret_returned_once: + type: boolean + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Workspace: + type: object + required: + - id + - owner_user_id + - key + - name + - metadata + - version + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + owner_user_id: + $ref: '#/components/schemas/UUID' + key: + type: string + name: + type: string + metadata: + type: object + additionalProperties: true + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + WorkspaceMember: + type: object + required: + - workspace_id + - user_id + - role_keys + properties: + workspace_id: + $ref: '#/components/schemas/UUID' + user_id: + $ref: '#/components/schemas/UUID' + role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + RoleAssignmentRecord: + type: object + required: + - id + - role_id + properties: + id: + $ref: '#/components/schemas/UUID' + user_id: + type: + - string + - 'null' + format: uuid + client_id: + type: + - string + - 'null' + format: uuid + role_id: + $ref: '#/components/schemas/UUID' + workspace_id: + type: + - string + - 'null' + format: uuid + created_at: + type: string + format: date-time + additionalProperties: false + Delegation: + type: object + required: + - id + - user_id + - scopes + - reason + - status + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + user_id: + $ref: '#/components/schemas/UUID' + workspace_id: + type: + - string + - 'null' + format: uuid + scopes: + type: array + items: + type: string + reason: + type: string + status: + enum: + - pending + - exchanged + - revoked + - expired + exchange_code: + type: string + writeOnly: true + expires_at: + type: string + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + ApplicationInvitation: + type: object + required: + - id + - application_id + - email + - status + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + workspace_id: + type: + - string + - 'null' + format: uuid + email: + type: string + format: email + application_role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + workspace_role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + status: + enum: + - pending + - accepted + - revoked + - expired + code: + type: string + writeOnly: true + link_token: + type: string + writeOnly: true + link: + type: string + format: uri + expires_at: + type: string + format: date-time + accepted_user_id: + type: + - string + - 'null' + format: uuid + created_at: + type: string + format: date-time + additionalProperties: false + RevokedSessionCount: + type: object + required: + - revoked_sessions + properties: + revoked_sessions: + type: integer + minimum: 0 + additionalProperties: false + AuthMethods: + type: object + required: + - methods + - registration_enabled + - registration_mode + properties: + methods: + type: array + items: + enum: + - password + - email_code + - magic_link + - google + - apple + - totp + - webauthn + registration_enabled: + type: boolean + registration_mode: + enum: + - public + - invite_only + additionalProperties: false + WebAuthnChallenge: + type: object + required: + - ceremony_id + - options + - expires_at + properties: + ceremony_id: + $ref: '#/components/schemas/UUID' + options: + type: object + additionalProperties: true + expires_at: + type: string + format: date-time + additionalProperties: false + InvitationExchangeResult: + type: object + required: + - authorization_code + - redirect_uri + - expires_in + properties: + authorization_code: + type: string + writeOnly: true + redirect_uri: + type: string + format: uri + expires_in: + type: integer + minimum: 1 + mfa_challenge_id: + type: + - string + - 'null' + format: uuid + additionalProperties: false + PersonalAPIKeyCreated: + type: object + required: + - token + - api_key + properties: + token: + type: string + writeOnly: true + api_key: + type: object + required: + - id + - label + - token_prefix + - scopes + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + label: + type: string + token_prefix: + type: string + scopes: + type: array + items: + type: string + expires_at: + type: string + format: date-time + additionalProperties: false + additionalProperties: false + Feature: + type: object + required: + - id + - key + - name + - value_type + - metadata + properties: + id: + $ref: '#/components/schemas/UUID' + key: + type: string + name: + type: string + value_type: + enum: + - boolean + - number + - string + - free_form + free_form_format: + type: + - string + - 'null' + enum: + - text + - csv + - json + - null + metadata: + type: object + additionalProperties: true + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Product: + type: object + required: + - id + - key + - name + - listable + - status + - metadata + - entitlement_config + - features + - version + properties: + id: + $ref: '#/components/schemas/UUID' + key: + type: string + name: + type: string + description: + type: + - string + - 'null' + listable: + type: boolean + status: + enum: + - active + - archived + metadata: + type: object + additionalProperties: true + entitlement_config: + type: object + additionalProperties: true + features: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + version: + type: integer + format: int64 + prices: + type: array + items: + $ref: '#/components/schemas/Price' + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Price: + type: object + required: + - id + - key + - mode + - currency + - currency_exponent + - tax_behavior + - checkout_config + - entitlement_config + - features + properties: + id: + $ref: '#/components/schemas/UUID' + product_id: + $ref: '#/components/schemas/UUID' + key: + type: string + mode: + enum: + - recurring + - one_time + - local + amount_minor: + type: + - integer + - 'null' + format: int64 + currency: + type: string + currency_exponent: + type: integer + tax_behavior: + enum: + - inclusive + - exclusive + - unspecified + checkout_config: + type: object + additionalProperties: true + entitlement_config: + type: object + additionalProperties: true + features: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + status: + enum: + - active + - archived + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + additionalProperties: false + EntitlementGrant: + type: object + required: + - id + - subject_type + - subject_id + - source_type + - feature_values + - configuration + - starts_at + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + source_type: + enum: + - manual + - local_request + - subscription + - checkout + source_id: + type: + - string + - 'null' + format: uuid + feature_values: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + configuration: + type: object + additionalProperties: true + starts_at: + type: string + format: date-time + expires_at: + type: + - string + - 'null' + format: date-time + revoked_at: + type: + - string + - 'null' + format: date-time + external_reference: + type: + - string + - 'null' + created_at: + type: string + format: date-time + additionalProperties: false + EffectiveEntitlements: + type: object + required: + - workspace_id + - effective + - provenance + - sources + properties: + workspace_id: + type: + - string + - 'null' + format: uuid + effective: + type: object + additionalProperties: + $ref: '#/components/schemas/FeatureValue' + provenance: + type: object + additionalProperties: + type: array + items: + $ref: '#/components/schemas/UUID' + sources: + type: array + items: + $ref: '#/components/schemas/EntitlementGrant' + additionalProperties: false + LocalEntitlementRequest: + type: object + required: + - id + - status + - subject_type + - subject_id + - product_snapshot + - price_snapshot + - feature_snapshot + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - pending + - approved + - rejected + - cancelled + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + product_snapshot: + type: object + additionalProperties: true + price_snapshot: + type: object + additionalProperties: true + feature_snapshot: + type: object + additionalProperties: true + address_snapshot: + type: + - object + - 'null' + additionalProperties: true + external_reference: + type: + - string + - 'null' + entitlement_grant_id: + type: + - string + - 'null' + format: uuid + reason: + type: + - string + - 'null' + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + LocalEntitlementApproval: + type: object + required: + - status + - entitlement_grant_id + properties: + status: + type: string + const: approved + entitlement_grant_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + CheckoutSession: + type: object + required: + - id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - open + - complete + - expired + checkout_uri: + type: + - string + - 'null' + format: uri + provider_session_id: + type: + - string + - 'null' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + external_reference: + type: + - string + - 'null' + created_at: + type: string + format: date-time + expires_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + PortalSession: + type: object + required: + - provider_session_id + - portal_uri + properties: + provider_session_id: + type: string + portal_uri: + type: string + format: uri + additionalProperties: false + Subscription: + type: object + required: + - id + - subject_type + - subject_id + - price_id + - provider_id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + price_id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + provider_subscription_id: + type: string + status: + type: string + current_period_start: + type: + - string + - 'null' + format: date-time + current_period_end: + type: + - string + - 'null' + format: date-time + cancel_at_period_end: + type: boolean + external_reference: + type: + - string + - 'null' + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + Invoice: + type: object + required: + - id + - subject_type + - subject_id + - status + - amount_due_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + subscription_id: + type: + - string + - 'null' + format: uuid + provider_invoice_id: + type: string + status: + type: string + amount_due_minor: + type: integer + format: int64 + amount_paid_minor: + type: integer + format: int64 + currency: + type: string + hosted_invoice_uri: + type: + - string + - 'null' + format: uri + external_reference: + type: + - string + - 'null' + created_at: + type: string + format: date-time + additionalProperties: false + Payment: + type: object + required: + - id + - subject_type + - subject_id + - status + - amount_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + invoice_id: + type: + - string + - 'null' + format: uuid + provider_payment_id: + type: string + status: + type: string + amount_minor: + type: integer + format: int64 + currency: + type: string + external_reference: + type: + - string + - 'null' + created_at: + type: string + format: date-time + additionalProperties: false + Refund: + type: object + required: + - id + - status + - amount_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + payment_id: + $ref: '#/components/schemas/UUID' + provider_refund_id: + type: string + status: + type: string + amount_minor: + type: integer + format: int64 + currency: + type: string + reason: + type: + - string + - 'null' + external_reference: + type: + - string + - 'null' + created_at: + type: string + format: date-time + additionalProperties: false + Dispute: + type: object + required: + - id + - status + - amount_minor + - currency + properties: + id: + $ref: '#/components/schemas/UUID' + payment_id: + type: + - string + - 'null' + format: uuid + provider_dispute_id: + type: string + status: + type: string + amount_minor: + type: integer + format: int64 + currency: + type: string + reason: + type: + - string + - 'null' + created_at: + type: string + format: date-time + additionalProperties: false + BillingStatistics: + type: object + required: + - from + - to + - revenue_minor_by_currency + - refunds_minor_by_currency + - status_counts + properties: + from: + type: string + format: date-time + to: + type: string + format: date-time + revenue_minor_by_currency: + type: array + items: + $ref: '#/components/schemas/CurrencyTotal' + refunds_minor_by_currency: + type: array + items: + $ref: '#/components/schemas/CurrencyTotal' + status_counts: + type: object + additionalProperties: + type: object + additionalProperties: + type: integer + minimum: 0 + additionalProperties: false + CurrencyTotal: + type: object + required: [currency, amount_minor] + properties: + currency: + type: string + pattern: '^[A-Z]{3}$' + amount_minor: + type: integer + format: int64 + additionalProperties: false + BillingProviderEvent: + type: object + required: + - id + - provider_event_id + - event_type + - status + - received_at + properties: + id: + $ref: '#/components/schemas/UUID' + provider_event_id: + type: string + event_type: + type: string + status: + enum: + - pending + - processed + - failed + - ignored + attempts: + type: integer + last_error: + type: + - string + - 'null' + received_at: + type: string + format: date-time + processed_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + ReconciliationRun: + type: object + required: + - id + - provider_id + - status + - findings + - repairs + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + status: + enum: + - pending + - running + - completed + - failed + findings: + type: integer + minimum: 0 + repairs: + type: integer + minimum: 0 + last_error: + type: + - string + - 'null' + started_at: + type: + - string + - 'null' + format: date-time + completed_at: + type: + - string + - 'null' + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + BillingProfile: + type: object + required: + - id + - subject_type + - subject_id + - version + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + name: + type: + - string + - 'null' + email: + type: + - string + - 'null' + format: email + tax_id: + type: + - string + - 'null' + default_address_id: + type: + - string + - 'null' + format: uuid + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + BillingSummary: + type: object + required: + - subject_type + - subject_id + - billing_profile + - subscriptions + properties: + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + billing_profile: + type: + - object + - 'null' + allOf: + - $ref: '#/components/schemas/BillingProfile' + subscriptions: + type: array + items: + $ref: '#/components/schemas/Subscription' + additionalProperties: false + Address: + type: object + required: + - id + - subject_type + - subject_id + - line1 + - city + - postal_code + - country + - active + - version + properties: + id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + name: + type: + - string + - 'null' + line1: + type: string + line2: + type: + - string + - 'null' + city: + type: string + region: + type: + - string + - 'null' + postal_code: + type: string + country: + type: string + active: + type: boolean + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + AccountExport: + type: object + required: + - exported_at + - user + - addresses + properties: + exported_at: + type: string + format: date-time + user: + $ref: '#/components/schemas/User' + addresses: + type: array + items: + $ref: '#/components/schemas/Address' + additionalProperties: false + MFAEnrollment: + type: object + required: + - method_id + - secret + - provisioning_uri + properties: + method_id: + $ref: '#/components/schemas/UUID' + secret: + type: string + writeOnly: true + provisioning_uri: + type: string + format: uri + additionalProperties: false + MFAActivation: + type: object + required: + - method_id + - recovery_codes + properties: + method_id: + $ref: '#/components/schemas/UUID' + recovery_codes: + type: array + items: + type: string + writeOnly: true + additionalProperties: false + RecoveryCodes: + type: object + required: + - recovery_codes + properties: + recovery_codes: + type: array + items: + type: string + writeOnly: true + additionalProperties: false + MFAMethod: + type: object + required: + - id + - type + - status + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + type: + enum: + - totp + - webauthn + name: + type: + - string + - 'null' + status: + enum: + - pending + - active + - disabled + last_used_at: + type: + - string + - 'null' + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + ExternalIdentity: + type: object + required: + - id + - provider + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + enum: + - google + - apple + email: + type: + - string + - 'null' + format: email + created_at: + type: string + format: date-time + last_used_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + PermissionCheckResult: + type: object + required: + - workspace_id + - results + properties: + workspace_id: + type: + - string + - 'null' + format: uuid + results: + type: object + additionalProperties: + type: boolean + additionalProperties: false + AuditRecord: + type: object + required: + - id + - actor_type + - action + - target_type + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + organization_id: + type: + - string + - 'null' + format: uuid + application_id: + type: + - string + - 'null' + format: uuid + actor_type: + enum: + - control_user + - user + - client + - system + actor_id: + type: + - string + - 'null' + format: uuid + action: + type: string + target_type: + type: string + target_id: + type: + - string + - 'null' + reason: + type: + - string + - 'null' + request_id: + type: + - string + - 'null' + changes: + type: object + additionalProperties: true + created_at: + type: string + format: date-time + additionalProperties: false + AuditExportRecord: + type: object + required: + - id + - record_count + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + record_count: + type: integer + minimum: 0 + filters: + type: object + additionalProperties: true + status: + enum: + - pending + - ready + - expired + - failed + download_uri: + type: + - string + - 'null' + format: uri + expires_at: + type: string + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + Webhook: + type: object + required: + - id + - uri + - event_filters + - disabled + properties: + id: + $ref: '#/components/schemas/UUID' + uri: + type: string + format: uri + event_filters: + type: array + items: + type: string + secret: + type: string + writeOnly: true + secret_returned_once: + type: boolean + disabled: + type: boolean + disabled_at: + type: + - string + - 'null' + format: date-time + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + WebhookDelivery: + type: object + required: + - id + - event_id + - webhook_id + - status + - attempt_count + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + event_id: + $ref: '#/components/schemas/UUID' + webhook_id: + $ref: '#/components/schemas/UUID' + status: + enum: + - pending + - delivered + - failed + - dead + attempt_count: + type: integer + minimum: 0 + response_status: + type: + - integer + - 'null' + last_error: + type: + - string + - 'null' + next_attempt_at: + type: + - string + - 'null' + format: date-time + created_at: + type: string + format: date-time + delivered_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + SenderIdentity: + type: object + required: + - id + - provider_id + - email + - name + - is_default + - verified + properties: + id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + name: + type: string + is_default: + type: boolean + verified: + type: boolean + created_at: + type: string + format: date-time + additionalProperties: false + NotificationTemplate: + type: object + required: + - id + - key + - locale + - category + - version + - status + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + type: + - string + - 'null' + format: uuid + key: + type: string + locale: + $ref: '#/components/schemas/Locale' + category: + type: string + subject_template: + type: string + text_template: + type: string + html_template: + type: + - string + - 'null' + version: + type: integer + status: + enum: + - draft + - active + - archived + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + TemplateVariables: + type: object + required: + - protected + - optional + properties: + protected: + type: array + items: + type: string + optional: + type: array + items: + type: string + additionalProperties: false + NotificationTemplatePreview: + type: object + required: + - template_id + - version + - subject + - text + - html + properties: + template_id: + $ref: '#/components/schemas/UUID' + version: + type: integer + subject: + type: string + text: + type: string + html: + type: + - string + - 'null' + additionalProperties: false + NotificationStatistics: + type: object + required: + - notification_status_counts + - attempts_delivered + - attempts_failed + properties: + notification_status_counts: + type: object + additionalProperties: + type: integer + minimum: 0 + attempts_delivered: + type: integer + minimum: 0 + attempts_failed: + type: integer + minimum: 0 + additionalProperties: false + Notification: + type: object + required: + - id + - template_key + - recipient + - status + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + template_key: + type: string + recipient: + type: string + format: email + locale: + $ref: '#/components/schemas/Locale' + status: + enum: + - queued + - sending + - delivered + - failed + - suppressed + - dead + attempt_count: + type: integer + minimum: 0 + last_error: + type: + - string + - 'null' + created_at: + type: string + format: date-time + delivered_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + NotificationPreference: + type: object + required: + - category + - email_enabled + properties: + category: + type: string + email_enabled: + type: boolean + updated_at: + type: string + format: date-time + additionalProperties: false + StorageProvider: + type: object + required: + - id + - provider + - scope + - name + - endpoint + - region + - force_path_style + - status + - inheritable + - credentials_configured + - allow_private_endpoint + - max_object_bytes + - max_email_image_bytes + - max_application_bytes + - max_application_objects + - version + properties: + id: + $ref: '#/components/schemas/UUID' + provider: + type: string + const: s3 + scope: + enum: + - installation + - organization + - application + organization_id: + type: + - string + - 'null' + format: uuid + application_id: + type: + - string + - 'null' + format: uuid + name: + type: string + endpoint: + type: string + format: uri + region: + type: string + force_path_style: + type: boolean + public_bucket: + type: + - string + - 'null' + private_bucket: + type: + - string + - 'null' + public_base_url: + type: + - string + - 'null' + format: uri + status: + enum: + - active + - disabled + - unverified + - error + inheritable: + type: boolean + credentials_configured: + type: boolean + allow_private_endpoint: + type: boolean + verified_at: + type: + - string + - 'null' + format: date-time + disabled_at: + type: [string, 'null'] + format: date-time + last_error: + type: [string, 'null'] + max_object_bytes: + type: integer + format: int64 + max_email_image_bytes: + type: integer + format: int64 + max_application_bytes: + type: integer + format: int64 + max_application_objects: + type: integer + format: int64 + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + StorageProviderStatus: + type: object + required: + - id + - status + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - active + - disabled + - unverified + - error + additionalProperties: false + StorageDownload: + type: object + required: + - url + - expires_at + - visibility + properties: + url: + type: string + format: uri + expires_at: + type: string + format: date-time + visibility: + enum: + - public + - private + additionalProperties: false + OIDCDiscovery: + type: object + required: + - issuer + - authorization_endpoint + - token_endpoint + - jwks_uri + - response_types_supported + - subject_types_supported + - id_token_signing_alg_values_supported + properties: + issuer: + type: string + format: uri + authorization_endpoint: + type: string + format: uri + token_endpoint: + type: string + format: uri + userinfo_endpoint: + type: string + format: uri + revocation_endpoint: + type: string + format: uri + introspection_endpoint: + type: string + format: uri + jwks_uri: + type: string + format: uri + response_types_supported: + type: array + items: + type: string + grant_types_supported: + type: array + items: + type: string + subject_types_supported: + type: array + items: + type: string + id_token_signing_alg_values_supported: + type: array + items: + type: string + code_challenge_methods_supported: + type: array + items: + type: string + scopes_supported: + type: array + items: + type: string + additionalProperties: false + JWKS: + type: object + required: + - keys + properties: + keys: + type: array + items: + type: object + required: + - kty + - kid + - use + - alg + - n + - e + properties: + kty: + type: string + kid: + type: string + use: + type: string + alg: + type: string + n: + type: string + e: + type: string + additionalProperties: false + additionalProperties: false + AuthorizationRedirect: + type: object + required: + - redirect_to + properties: + redirect_to: + type: string + format: uri + additionalProperties: false + TokenIntrospection: + type: object + required: + - active + properties: + active: + type: boolean + sub: + type: string + aud: + oneOf: + - type: string + - type: array + items: + type: string + iss: + type: string + format: uri + exp: + type: integer + format: int64 + iat: + type: integer + format: int64 + scope: + type: string + client_id: + type: string + token_type: + type: string + actor_type: + enum: + - control_user + - user + - client + application_id: + type: string + format: uuid + roles: + $ref: '#/components/schemas/StructuredRoles' + additionalProperties: false + UserInfo: + type: object + required: + - sub + - application_id + - actor_type + properties: + sub: + type: string + application_id: + $ref: '#/components/schemas/UUID' + actor_type: + enum: + - user + - client + email: + type: string + format: email + email_verified: + type: boolean + given_name: + type: string + family_name: + type: string + locale: + $ref: '#/components/schemas/Locale' + scope: + type: string + roles: + $ref: '#/components/schemas/StructuredRoles' + custom_claims: + type: object + additionalProperties: true + additionalProperties: false + WebhookAcknowledgement: + type: object + required: + - received + properties: + received: + type: boolean + additionalProperties: false + OrganizationMember: + type: object + required: + - control_user_id + - email + - display_name + - role + - status + properties: + control_user_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + display_name: + type: string + role: + enum: + - owner + - admin + - member + - auditor + status: + enum: + - active + - suspended + - deleted + joined_at: + type: string + format: date-time + additionalProperties: false + PersonalAPIKey: + type: object + required: + - id + - label + - token_prefix + - scopes + - status + - expires_at + properties: + id: + $ref: '#/components/schemas/UUID' + label: + type: string + token_prefix: + type: string + scopes: + type: array + items: + type: string + status: + enum: + - active + - revoked + - expired + last_used_at: + type: + - string + - 'null' + format: date-time + expires_at: + type: string + format: date-time + created_at: + type: string + format: date-time + additionalProperties: false + OAuthConsent: + type: object + required: + - id + - client_id + - scopes + - created_at + properties: + id: + $ref: '#/components/schemas/UUID' + client_id: + type: string + client_name: + type: string + scopes: + type: array + items: + type: string + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false + WorkspaceAccessEntry: + type: object + required: + - type + - workspace_id + properties: + type: + enum: + - owner + - member + - invitation + workspace_id: + $ref: '#/components/schemas/UUID' + user_id: + type: + - string + - 'null' + format: uuid + email: + type: + - string + - 'null' + format: email + role_keys: + type: array + items: + $ref: '#/components/schemas/RoleKey' + invitation_id: + type: + - string + - 'null' + format: uuid + status: + type: string + expires_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + EmptyResponse: + type: object + maxProperties: 0 + additionalProperties: false + SessionPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Session' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + NotificationProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/NotificationProvider' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + AuthProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/AuthProvider' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + BillingProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/BillingProvider' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ControlUserPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ControlUser' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ControlUserInvitationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ControlUserInvitation' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + SigningKeyPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/SigningKey' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ManagementClientPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ManagementClient' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ApplicationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Application' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + OrganizationMemberPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/OrganizationMember' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ApplicationDomainPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ApplicationDomain' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + OAuthClientPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/OAuthClient' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + RolePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Role' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + WorkspacePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Workspace' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + WorkspaceMemberPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/WorkspaceMember' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + RoleAssignmentPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/RoleAssignmentRecord' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + PermissionGrantPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/PermissionGrant' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + DelegationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Delegation' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ApplicationInvitationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ApplicationInvitation' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + UserPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/User' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + EntitlementGrantPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/EntitlementGrant' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + AddressPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Address' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + OAuthConsentPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/OAuthConsent' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + FeaturePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Feature' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ProductPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Product' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + PricePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Price' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + LocalEntitlementRequestPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/LocalEntitlementRequest' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + SubscriptionPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Subscription' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + InvoicePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Invoice' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + PaymentPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Payment' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + RefundPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Refund' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + DisputePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Dispute' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + BillingProviderEventPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/BillingProviderEvent' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ReconciliationRunPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ReconciliationRun' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + MFAMethodPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/MFAMethod' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + ExternalIdentityPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/ExternalIdentity' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + WorkspaceAccessPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/WorkspaceAccessEntry' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + EventPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/EventEnvelope' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + EventTypePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/EventTypeDefinition' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + AuditRecordPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/AuditRecord' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + WebhookPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Webhook' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + WebhookDeliveryPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/WebhookDelivery' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + SenderIdentityPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/SenderIdentity' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + NotificationTemplatePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/NotificationTemplate' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + NotificationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Notification' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + NotificationPreferencePage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/NotificationPreference' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + StorageProviderPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/StorageProvider' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + StorageObjectPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/StorageObject' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + PersonalAPIKeyPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/PersonalAPIKey' + next_cursor: + type: + - string + - 'null' + additionalProperties: false + CompleteSetup: + type: object + properties: + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + additionalProperties: false + ControlEmailStart: + type: object + required: + - email + properties: + email: + type: string + format: email + delivery: + enum: + - code + - link + - both + default: both + additionalProperties: false + UpdateControlUserAccount: + type: object + required: + - display_name + properties: + display_name: + type: string + minLength: 1 + maxLength: 200 + additionalProperties: false + ControlInvitationProviderStart: + type: object + required: + - invitation_token + properties: + invitation_token: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + UpdateControlInvitationMethod: + type: object + properties: + onboarding_method: + enum: + - email + - google + - apple + additionalProperties: false + UpdateManagementAPI: + type: object + required: + - enabled + properties: + enabled: + type: boolean + additionalProperties: false + RefreshToken: + type: object + required: + - refresh_token + properties: + refresh_token: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + ConfigureAuthProvider: + type: object + required: + - client_id + properties: + client_id: + type: string + minLength: 1 + maxLength: 500 + client_secret: + type: string + minLength: 1 + writeOnly: true + team_id: + type: string + minLength: 1 + maxLength: 100 + key_id: + type: string + minLength: 1 + maxLength: 100 + private_key_pem: + type: string + minLength: 1 + writeOnly: true + inheritable: + type: boolean + default: false + control_login_enabled: + type: boolean + additionalProperties: false + UpdateSMTPProvider: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 200 + host: + type: string + minLength: 1 + maxLength: 255 + port: + type: integer + minimum: 1 + maximum: 65535 + username: + type: string + password: + type: string + writeOnly: true + tls_mode: + enum: + - starttls + - implicit_tls + sender_email: + type: string + format: email + sender_name: + type: string + maxLength: 200 + inheritable: + type: boolean + additionalProperties: false + TestNotificationProvider: + type: object + required: + - recipient + properties: + recipient: + type: string + format: email + additionalProperties: false + UpdateBillingProvider: + type: object + minProperties: 1 + properties: + secret: + type: string + writeOnly: true + webhook_secret: + type: string + writeOnly: true + metadata: + type: object + additionalProperties: true + inheritable: + type: boolean + additionalProperties: false + MembershipRole: + type: object + required: + - role + properties: + role: + enum: + - owner + - admin + - member + - auditor + additionalProperties: false + CreateApplicationDomain: + type: object + required: + - hostname + properties: + hostname: + type: string + minLength: 1 + maxLength: 253 + additionalProperties: false + CreateClient: + type: object + required: + - client_id + - name + - client_type + properties: + client_id: + type: string + minLength: 1 + maxLength: 160 + name: + type: string + minLength: 1 + maxLength: 200 + client_type: + enum: + - public + - confidential + redirect_uris: + type: array + uniqueItems: true + items: + type: string + format: uri + allowed_grants: + type: array + uniqueItems: true + items: + enum: + - authorization_code + - refresh_token + - client_credentials + allowed_scopes: + type: array + uniqueItems: true + items: + type: string + additionalProperties: false + UpdateClient: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 200 + redirect_uris: + type: array + uniqueItems: true + items: + type: string + format: uri + allowed_grants: + type: array + uniqueItems: true + items: + enum: + - authorization_code + - refresh_token + - client_credentials + allowed_scopes: + type: array + uniqueItems: true + items: + type: string + additionalProperties: false + CreateWorkspace: + type: object + required: + - key + - name + properties: + key: + type: string + minLength: 1 + maxLength: 100 + name: + type: string + minLength: 1 + maxLength: 255 + owner_user_id: + $ref: '#/components/schemas/UUID' + metadata: + type: object + additionalProperties: true + additionalProperties: false + UpdateWorkspace: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 255 + metadata: + type: object + additionalProperties: true + additionalProperties: false + ReplaceWorkspaceMemberRoles: + type: object + required: + - role_keys + properties: + role_keys: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/RoleKey' + additionalProperties: false + CreateDelegation: + type: object + required: + - user_id + - reason + - redirect_uri + - permissions + properties: + user_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + reason: + type: string + minLength: 1 + maxLength: 500 + redirect_uri: + type: string + format: uri + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + expires_in: + type: integer + format: int64 + minimum: 60 + maximum: 3600 + additionalProperties: false + ExchangeDelegation: + type: object + required: + - exchange_code + properties: + exchange_code: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + CreateUser: + type: object + required: + - email + properties: + email: + type: string + format: email + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + first_name: + type: string + maxLength: 200 + last_name: + type: string + maxLength: 200 + username: + type: + - string + - 'null' + maxLength: 200 + locale: + $ref: '#/components/schemas/Locale' + email_verified: + type: boolean + is_org_verified: + type: boolean + custom_attributes: + type: object + additionalProperties: true + additionalProperties: false + UpdateUser: + type: object + minProperties: 1 + properties: + first_name: + type: string + maxLength: 200 + last_name: + type: string + maxLength: 200 + username: + type: + - string + - 'null' + maxLength: 200 + locale: + $ref: '#/components/schemas/Locale' + status: + enum: + - active + - suspended + - pending_deletion + email_verified: + type: boolean + is_org_verified: + type: boolean + custom_attributes: + type: object + additionalProperties: true + reason: + type: string + maxLength: 500 + additionalProperties: false + AuditReason: + type: object + required: + - reason + properties: + reason: + type: string + minLength: 1 + maxLength: 500 + additionalProperties: false + PasswordResetStart: + type: object + required: + - email + properties: + email: + type: string + format: email + additionalProperties: false + PasswordResetVerify: + type: object + required: + - challenge_id + - password + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + minLength: 8 + maxLength: 8 + writeOnly: true + link_token: + type: string + writeOnly: true + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + additionalProperties: false + ExternalAuthStartRequest: + type: object + required: + - redirect_uri + properties: + flow: + enum: + - sign_in + - sign_up + - automatic + - link + default: automatic + redirect_uri: + type: string + format: uri + login_hint: + type: string + format: email + additionalProperties: false + ExternalAuthExchange: + type: object + required: + - exchange + properties: + exchange: + type: string + minLength: 1 + writeOnly: true + additionalProperties: false + VerifyMFA: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + writeOnly: true + recovery_code: + type: string + writeOnly: true + oneOf: + - required: + - code + - required: + - recovery_code + additionalProperties: false + BeginWebAuthnAuthentication: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + origin: + type: string + format: uri + additionalProperties: false + BeginWebAuthnRegistration: + type: object + properties: + origin: + type: string + format: uri + label: + type: string + maxLength: 120 + additionalProperties: false + FinishWebAuthnCeremony: + type: object + required: + - ceremony_id + - credential + properties: + ceremony_id: + $ref: '#/components/schemas/UUID' + credential: + type: object + additionalProperties: true + additionalProperties: false + CreateEntitlement: + type: object + required: + - subject_type + - subject_id + properties: + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + product_id: + $ref: '#/components/schemas/UUID' + price_id: + $ref: '#/components/schemas/UUID' + feature_values: + type: object + additionalProperties: true + configuration: + type: object + additionalProperties: true + starts_at: + type: string + format: date-time + expires_at: + type: string + format: date-time + reason: + type: string + maxLength: 500 + external_reference: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false + AdjustEntitlement: + type: object + properties: + expires_at: + type: + - string + - 'null' + format: date-time + reason: + type: string + maxLength: 500 + additionalProperties: false + CreatePortalSession: + type: object + required: + - provider_id + - return_uri + properties: + provider_id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + default: user + subject_id: + $ref: '#/components/schemas/UUID' + return_uri: + type: string + format: uri + additionalProperties: false + CancelSubscription: + type: object + properties: + at_period_end: + type: boolean + additionalProperties: false + ChangeSubscriptionPrice: + type: object + required: + - price_id + properties: + price_id: + $ref: '#/components/schemas/UUID' + proration_behavior: + enum: + - create_prorations + - always_invoice + - none + default: create_prorations + additionalProperties: false + CreateRefund: + type: object + properties: + amount_minor: + type: integer + format: int64 + minimum: 1 + reason: + type: string + maxLength: 500 + additionalProperties: false + AccountChallenge: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + minLength: 8 + maxLength: 8 + writeOnly: true + link_token: + type: string + writeOnly: true + additionalProperties: false + EmailAddress: + type: object + required: + - email + properties: + email: + type: string + format: email + additionalProperties: false + PasswordChange: + type: object + required: + - current_password + - new_password + properties: + current_password: + type: string + writeOnly: true + new_password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true + additionalProperties: false + StartTOTP: + type: object + properties: + label: + type: string + maxLength: 120 + additionalProperties: false + ActivateTOTP: + type: object + required: + - code + properties: + code: + type: string + minLength: 6 + maxLength: 8 + writeOnly: true + additionalProperties: false + CreateAddress: + type: object + required: + - name + - line1 + - city + - postal_code + - country_code + properties: + name: + type: string + minLength: 1 + maxLength: 200 + line1: + type: string + minLength: 1 + maxLength: 500 + line2: + type: string + maxLength: 500 + city: + type: string + minLength: 1 + maxLength: 200 + region: + type: string + maxLength: 200 + postal_code: + type: string + minLength: 1 + maxLength: 50 + country_code: + type: string + pattern: ^[A-Za-z]{2}$ + tax_id: + type: + - string + - 'null' + maxLength: 100 + active: + type: boolean + default: true + additionalProperties: false + UpdateAddress: + type: object + required: + - version + properties: + name: + type: string + minLength: 1 + maxLength: 200 + line1: + type: string + minLength: 1 + maxLength: 500 + line2: + type: string + maxLength: 500 + city: + type: string + minLength: 1 + maxLength: 200 + region: + type: string + maxLength: 200 + postal_code: + type: string + minLength: 1 + maxLength: 50 + country_code: + type: string + pattern: ^[A-Za-z]{2}$ + tax_id: + type: + - string + - 'null' + maxLength: 100 + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + UpdateBillingProfile: + type: object + required: + - version + properties: + name: + type: string + maxLength: 200 + email: + type: string + format: email + tax_id: + type: string + maxLength: 100 + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + PermissionCheck: + type: object + required: + - permissions + properties: + permissions: + type: array + minItems: 1 + maxItems: 100 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + workspace_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + AuditExport: + type: object + properties: + start: + type: string + format: date-time + end: + type: string + format: date-time + actor_type: + enum: + - control_user + - user + - client + - system + action: + type: string + target_type: + type: string + additionalProperties: false + CreateWebhook: + type: object + required: + - uri + properties: + uri: + type: string + format: uri + event_filters: + type: array + uniqueItems: true + items: + type: string + additionalProperties: false + UpdateWebhook: + type: object + minProperties: 1 + properties: + uri: + type: string + format: uri + event_filters: + type: array + uniqueItems: true + items: + type: string + enabled: + type: boolean + additionalProperties: false + CreateSenderIdentity: + type: object + required: + - provider_id + - email + properties: + provider_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + name: + type: string + maxLength: 200 + is_default: + type: boolean + default: false + additionalProperties: false + CreateNotificationTemplate: + type: object + required: + - key + - category + - subject_template + - text_template + properties: + key: + type: string + pattern: ^[a-z][a-z0-9_.-]{2,100}$ + locale: + $ref: '#/components/schemas/Locale' + category: + enum: + - security + - billing + - transactional + - marketing + subject_template: + type: string + minLength: 1 + maxLength: 500 + text_template: + type: string + minLength: 1 + maxLength: 100000 + html_template: + type: string + maxLength: 200000 + variable_schema: + type: object + additionalProperties: true + additionalProperties: false + UpdateNotificationTemplate: + type: object + minProperties: 1 + properties: + category: + enum: + - security + - billing + - transactional + - marketing + subject_template: + type: string + minLength: 1 + maxLength: 500 + text_template: + type: string + minLength: 1 + maxLength: 100000 + html_template: + type: string + maxLength: 200000 + variable_schema: + type: object + additionalProperties: true + additionalProperties: false + PreviewNotificationTemplate: + type: object + required: + - variables + properties: + variables: + type: object + additionalProperties: true + user_id: + $ref: '#/components/schemas/UUID' + recipient: + type: string + format: email + additionalProperties: false + UpdateNotificationPreference: + type: object + required: + - email_enabled + properties: + email_enabled: + type: boolean + additionalProperties: false + UpdateStorageProvider: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 200 + endpoint: + type: string + format: uri + maxLength: 2000 + region: + type: string + minLength: 1 + maxLength: 100 + access_key_id: + type: string + minLength: 1 + writeOnly: true + secret_access_key: + type: string + minLength: 1 + writeOnly: true + force_path_style: + type: boolean + public_bucket: + type: string + private_bucket: + type: string + public_base_url: + type: string + format: uri + inheritable: + type: boolean + allow_private_endpoint: + type: boolean + max_object_bytes: + type: integer + format: int64 + minimum: 1 + max_email_image_bytes: + type: integer + format: int64 + minimum: 1 + max_application_bytes: + type: integer + format: int64 + minimum: 1 + max_application_objects: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + ManagementAPIStatus: + type: object + required: + - enabled + - can_manage + - active_clients + - token_endpoint + - api_base + properties: + enabled: + type: boolean + can_manage: + type: boolean + active_clients: + type: integer + minimum: 0 + token_endpoint: + type: string + format: uri + api_base: + type: string + format: uri + additionalProperties: false + CreateManagementClient: + type: object + required: + - client_id + - name + properties: + client_id: + type: string + minLength: 1 + maxLength: 160 + name: + type: string + minLength: 1 + maxLength: 200 + allowed_scopes: + type: array + items: + type: string + const: /management/organizations/* + default: + - /management/organizations/* + additionalProperties: false + OrganizationEnabledSettings: + type: object + required: + - public_registration + - password_authentication + - passwordless_authentication + - personal_api_keys + - delegation + - organization_provider_overrides + - application_provider_overrides + - custom_events + - webhooks + properties: + public_registration: + type: boolean + password_authentication: + type: boolean + passwordless_authentication: + type: boolean + personal_api_keys: + type: boolean + delegation: + type: boolean + organization_provider_overrides: + type: boolean + application_provider_overrides: + type: boolean + custom_events: + type: boolean + webhooks: + type: boolean + additionalProperties: false + UpdateOrganizationPolicy: + type: object + required: + - max_applications + - max_users + - enabled_settings + properties: + max_applications: + type: + - integer + - 'null' + minimum: 0 + description: Null means unlimited. + max_users: + type: + - integer + - 'null' + minimum: 0 + description: Null means unlimited across all applications in the organization. + enabled_settings: + $ref: '#/components/schemas/OrganizationEnabledSettings' + additionalProperties: false + OrganizationPolicy: + type: object + required: + - max_applications + - max_users + - enabled_settings + - organization_id + - usage + - version + properties: + max_applications: + type: + - integer + - 'null' + minimum: 0 + description: Null means unlimited. + max_users: + type: + - integer + - 'null' + minimum: 0 + description: Null means unlimited across all applications in the organization. + enabled_settings: + $ref: '#/components/schemas/OrganizationEnabledSettings' + organization_id: + $ref: '#/components/schemas/UUID' + usage: + type: object + required: + - applications + - users + properties: + applications: + type: integer + minimum: 0 + users: + type: integer + minimum: 0 + additionalProperties: false + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + UUID: + type: string + format: uuid + CreateStorageProvider: + type: object + required: + - name + - endpoint + - region + - access_key_id + - secret_access_key + properties: + name: + type: string + minLength: 1 + maxLength: 200 + endpoint: + type: string + format: uri + maxLength: 2000 + region: + type: string + minLength: 1 + maxLength: 100 + access_key_id: + type: string + minLength: 1 + writeOnly: true + secret_access_key: + type: string + minLength: 1 + writeOnly: true + force_path_style: + type: boolean + default: false + public_bucket: + type: string + minLength: 1 + private_bucket: + type: string + minLength: 1 + public_base_url: + type: string + format: uri + inheritable: + type: boolean + default: false + allow_private_endpoint: + type: boolean + default: false + description: Installation-scoped opt-in for local or private-network S3 endpoints. + max_object_bytes: + type: integer + format: int64 + minimum: 1 + default: 26214400 + max_email_image_bytes: + type: integer + format: int64 + minimum: 1 + default: 2097152 + max_application_bytes: + type: integer + format: int64 + minimum: 1 + default: 10737418240 + max_application_objects: + type: integer + format: int64 + minimum: 1 + default: 100000 + anyOf: + - required: + - public_bucket + - required: + - private_bucket + additionalProperties: false + CreateStorageUpload: + type: object + required: + - filename + - content_type + - size_bytes + - visibility + properties: + filename: + type: string + minLength: 1 + maxLength: 500 + content_type: + type: string + minLength: 1 + maxLength: 255 + size_bytes: + type: integer + format: int64 + minimum: 1 + visibility: + enum: + - public + - private + purpose: + enum: + - email_image + metadata: + type: object + additionalProperties: true + additionalProperties: false + StorageObject: + type: object + required: + - id + - provider_id + - owner_type + - visibility + - filename + - content_type + - size_bytes + - metadata + - status + - version + - created_at + - updated_at + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + type: + - string + - 'null' + format: uuid + provider_id: + $ref: '#/components/schemas/UUID' + owner_type: + enum: + - installation + - application + - user + - workspace + owner_id: + type: + - string + - 'null' + format: uuid + visibility: + enum: + - public + - private + filename: + type: string + content_type: + type: string + size_bytes: + type: integer + format: int64 + etag: + type: + - string + - 'null' + metadata: + type: object + additionalProperties: true + status: + enum: + - pending + - ready + - deleting + - failed + public_url: + type: + - string + - 'null' + format: uri + upload_expires_at: + type: + - string + - 'null' + format: date-time + ready_at: + type: + - string + - 'null' + format: date-time + last_error: + type: + - string + - 'null' + version: + type: integer + format: int64 + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false StorageUploadAuthorization: type: object - required: [object, upload_url, upload_expires_at, required_headers] + required: + - object + - upload_url + - upload_expires_at + - required_headers properties: - object: { $ref: "#/components/schemas/StorageObject" } - upload_url: { type: string, format: uri, writeOnly: true } - upload_expires_at: { type: string, format: date-time } - required_headers: { type: object, additionalProperties: { type: string } } + object: + $ref: '#/components/schemas/StorageObject' + upload_url: + type: string + format: uri + writeOnly: true + upload_expires_at: + type: string + format: date-time + required_headers: + type: object + additionalProperties: + type: string additionalProperties: false RuntimeStorageConfig: type: object - required: [public_uploads_enabled, private_uploads_enabled] - properties: - public_uploads_enabled: { type: boolean } - private_uploads_enabled: { type: boolean } - max_public_object_bytes: { type: integer, format: int64 } - max_private_object_bytes: { type: integer, format: int64 } - max_email_image_bytes: { type: integer, format: int64 } - public_provider_scope: { enum: [installation, organization, application] } - private_provider_scope: { enum: [installation, organization, application] } - additionalProperties: false - Locale: { type: string, maxLength: 35, description: "Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference." } - Problem: { type: object, required: [type, title, status, code], properties: { type: { type: string, format: uri-reference }, title: { type: string }, status: { type: integer }, detail: { type: string }, code: { type: string }, request_id: { type: string } } } - Page: { type: object, required: [items, next_cursor], properties: { items: { type: array, items: {} }, next_cursor: { type: [string, "null"] } } } - OrganizationPage: { type: object, required: [items, next_cursor, installation_role], properties: { items: { type: array, items: { type: object, additionalProperties: true } }, next_cursor: { type: [string, "null"] }, installation_role: { type: [string, "null"], enum: [owner, admin, auditor, null], description: "The current operator's installation-wide role, or null for organization-only access." } } } - BootstrapRequest: { type: object, required: [credential, email], properties: { credential: { type: string, writeOnly: true }, email: { type: string, format: email }, display_name: { type: string } } } - AcceptOrganizationInvitation: { type: object, required: [invitation_token], properties: { invitation_token: { type: string, minLength: 1, writeOnly: true }, display_name: { type: string, maxLength: 200 } }, additionalProperties: false } - ApplicationFlowConfig: { type: object, required: [oauth_client_id, sign_in_redirect_uri, invitation_redirect_uri], additionalProperties: false, properties: { oauth_client_id: { type: string, minLength: 1 }, sign_in_redirect_uri: { type: string, format: uri }, invitation_redirect_uri: { type: string, format: uri } } } - ApplicationAuthConfig: { type: object, additionalProperties: false, properties: { flows: { $ref: "#/components/schemas/ApplicationFlowConfig" } } } - ApplicationInternalConfig: { type: object, additionalProperties: false, properties: { registration_mode: { type: string, enum: [public, invite_only] }, password_enabled: { type: boolean }, passwordless_enabled: { type: boolean }, personal_api_keys_enabled: { type: boolean }, delegation_enabled: { type: boolean } } } - RuntimeAuthConfig: { type: object, required: [registration_mode, registration_enabled, password_enabled, passwordless_enabled], additionalProperties: false, properties: { registration_mode: { type: string, enum: [public, invite_only] }, registration_enabled: { type: boolean }, password_enabled: { type: boolean }, passwordless_enabled: { type: boolean }, flows: { $ref: "#/components/schemas/ApplicationFlowConfig" } } } - RuntimeConfig: { type: object, required: [schema_version, api_base, issuer, application_id, public_config, auth, storage], properties: { schema_version: { type: string }, api_base: { type: string, format: uri }, issuer: { type: string, format: uri }, application_id: { $ref: "#/components/schemas/UUID" }, public_config: { type: object, additionalProperties: true }, auth: { $ref: "#/components/schemas/RuntimeAuthConfig" }, storage: { $ref: "#/components/schemas/RuntimeStorageConfig" } } } - PasswordSignIn: { type: object, required: [email, password], properties: { email: { type: string, format: email }, password: { type: string, writeOnly: true, minLength: 12, maxLength: 1024 } } } - PasswordSignUp: { allOf: [{ $ref: "#/components/schemas/PasswordSignIn" }, { type: object, properties: { first_name: { type: string }, last_name: { type: string }, locale: { $ref: "#/components/schemas/Locale" } } }] } - EmailStart: { type: object, required: [email, intent, delivery], properties: { email: { type: string, format: email }, intent: { enum: [sign_in, sign_up, automatic] }, delivery: { enum: [code, link, both] }, redirect_uri: { type: string, format: uri } } } - EmailVerify: { type: object, required: [challenge_id], properties: { challenge_id: { $ref: "#/components/schemas/UUID" }, code: { type: string, minLength: 8, maxLength: 8, writeOnly: true }, link_token: { type: string, writeOnly: true } } } - TokenResponse: { type: object, required: [access_token, refresh_token, token_type, expires_in], properties: { access_token: { type: string, writeOnly: true }, refresh_token: { type: string, writeOnly: true }, token_type: { const: Bearer }, expires_in: { type: integer } } } - User: { type: object, required: [id, application_id, email, locale, email_verified, is_org_verified, status], properties: { id: { $ref: "#/components/schemas/UUID" }, application_id: { $ref: "#/components/schemas/UUID" }, email: { type: string, format: email }, first_name: { type: string }, last_name: { type: string }, username: { type: [string, "null"] }, locale: { $ref: "#/components/schemas/Locale" }, email_verified: { type: boolean }, is_org_verified: { type: boolean }, status: { enum: [active, suspended, pending_deletion, anonymized, deleted] }, custom_attributes: { type: object, additionalProperties: true }, version: { type: integer, format: int64 } } } + required: + - public_uploads_enabled + - private_uploads_enabled + properties: + public_uploads_enabled: + type: boolean + private_uploads_enabled: + type: boolean + max_public_object_bytes: + type: integer + format: int64 + max_private_object_bytes: + type: integer + format: int64 + max_email_image_bytes: + type: integer + format: int64 + public_provider_scope: + enum: + - installation + - organization + - application + private_provider_scope: + enum: + - installation + - organization + - application + additionalProperties: false + Locale: + type: string + maxLength: 35 + description: Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Problem: + type: object + required: + - type + - title + - status + - code + properties: + type: + type: string + format: uri-reference + title: + type: string + status: + type: integer + detail: + type: string + code: + type: string + request_id: + type: string + affected_users: + type: integer + minimum: 0 + additionalProperties: false + OrganizationPage: + type: object + required: + - items + - next_cursor + properties: + items: + type: array + items: + $ref: '#/components/schemas/Organization' + next_cursor: + type: + - string + - 'null' + installation_role: + type: + - string + - 'null' + enum: + - owner + - admin + - auditor + - null + description: The current Platform user's installation-wide role, or null for organization-only access. + additionalProperties: false + BootstrapRequest: + type: object + required: + - credential + - email + properties: + credential: + type: string + writeOnly: true + email: + type: string + format: email + display_name: + type: string + additionalProperties: false + AcceptControlUserInvitation: + type: object + required: + - invitation_token + properties: + invitation_token: + type: string + minLength: 1 + writeOnly: true + display_name: + type: string + maxLength: 200 + additionalProperties: false + CreateControlUserInvitation: + type: object + required: + - email + - role + properties: + email: + type: string + format: email + role: + enum: + - owner + - admin + - member + - auditor + onboarding_method: + enum: + - email + - google + - apple + default: email + expires_in: + type: integer + minimum: 300 + maximum: 2592000 + additionalProperties: false + ControlAuthPolicy: + type: object + required: + - email_code_enabled + - magic_link_enabled + - password_enabled + properties: + email_code_enabled: + type: boolean + magic_link_enabled: + type: boolean + password_enabled: + type: boolean + additionalProperties: false + UpdateControlAuthPolicy: + type: object + required: + - email_code_enabled + - magic_link_enabled + - password_enabled + properties: + email_code_enabled: + type: boolean + magic_link_enabled: + type: boolean + password_enabled: + type: boolean + confirm_affected_users: + type: boolean + additionalProperties: false + ControlAuthMethods: + type: object + required: + - email_code + - magic_link + - password + - providers + properties: + email_code: + type: boolean + magic_link: + type: boolean + password: + type: boolean + providers: + type: array + items: + enum: + - google + - apple + additionalProperties: false + ExternalAuthStart: + type: object + required: + - provider + - authorize_url + - expires_in + properties: + provider: + enum: + - google + - apple + authorize_url: + type: string + format: uri + expires_in: + type: integer + additionalProperties: false + UpdateInstallationAuthProvider: + type: object + properties: + inheritable: + type: boolean + control_login_enabled: + type: boolean + confirm_affected_users: + type: boolean + minProperties: 1 + additionalProperties: false + ApplicationFlowConfig: + type: object + required: + - oauth_client_id + - sign_in_redirect_uri + - invitation_redirect_uri + additionalProperties: false + properties: + oauth_client_id: + type: string + minLength: 1 + sign_in_redirect_uri: + type: string + format: uri + description: Exact registered HTTPS, loopback HTTP, or public-client native application redirect URI. + invitation_redirect_uri: + type: string + format: uri + description: Invitation destination using the same origin or native scheme authority as the sign-in redirect. + ApplicationAuthConfig: + type: object + additionalProperties: false + properties: + flows: + $ref: '#/components/schemas/ApplicationFlowConfig' + ApplicationInternalConfig: + type: object + additionalProperties: false + properties: + registration_mode: + type: string + enum: + - public + - invite_only + password_enabled: + type: boolean + passwordless_enabled: + type: boolean + personal_api_keys_enabled: + type: boolean + delegation_enabled: + type: boolean + user_invitations_enabled: + type: boolean + default: false + custom_token_claim_keys: + type: array + maxItems: 32 + items: + type: string + minLength: 1 + maxLength: 64 + pattern: ^[A-Za-z0-9_.-]+$ + RuntimeAuthConfig: + type: object + required: + - registration_mode + - registration_enabled + - password_enabled + - passwordless_enabled + additionalProperties: false + properties: + registration_mode: + type: string + enum: + - public + - invite_only + registration_enabled: + type: boolean + password_enabled: + type: boolean + passwordless_enabled: + type: boolean + flows: + $ref: '#/components/schemas/ApplicationFlowConfig' + RuntimeConfig: + type: object + required: + - schema_version + - api_base + - issuer + - application_id + - public_config + - auth + - storage + properties: + schema_version: + type: string + api_base: + type: string + format: uri + issuer: + type: string + format: uri + application_id: + $ref: '#/components/schemas/UUID' + public_config: + type: object + additionalProperties: true + auth: + $ref: '#/components/schemas/RuntimeAuthConfig' + storage: + $ref: '#/components/schemas/RuntimeStorageConfig' + additionalProperties: false + PasswordSignIn: + type: object + required: + - email + - password + properties: + email: + type: string + format: email + password: + type: string + writeOnly: true + minLength: 12 + maxLength: 1024 + additionalProperties: false + PasswordSignUp: + type: object + required: + - email + - password + properties: + email: + type: string + format: email + password: + type: string + writeOnly: true + minLength: 12 + maxLength: 1024 + first_name: + type: string + last_name: + type: string + locale: + $ref: '#/components/schemas/Locale' + additionalProperties: false + EmailStart: + type: object + required: + - email + - intent + - delivery + properties: + email: + type: string + format: email + intent: + enum: + - sign_in + - sign_up + - automatic + delivery: + enum: + - code + - link + - both + redirect_uri: + type: string + format: uri + additionalProperties: false + EmailVerify: + type: object + required: + - challenge_id + properties: + challenge_id: + $ref: '#/components/schemas/UUID' + code: + type: string + minLength: 8 + maxLength: 8 + writeOnly: true + link_token: + type: string + writeOnly: true + additionalProperties: false + TokenResponse: + type: object + required: + - access_token + - refresh_token + - token_type + - expires_in + properties: + access_token: + type: string + writeOnly: true + refresh_token: + type: string + writeOnly: true + token_type: + const: Bearer + expires_in: + type: integer + additionalProperties: false + User: + type: object + required: + - id + - application_id + - email + - locale + - email_verified + - is_org_verified + - status + properties: + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + first_name: + type: string + last_name: + type: string + username: + type: + - string + - 'null' + locale: + $ref: '#/components/schemas/Locale' + email_verified: + type: boolean + is_org_verified: + type: boolean + status: + enum: + - active + - suspended + - pending_deletion + - anonymized + - deleted + custom_attributes: + type: object + additionalProperties: true + version: + type: integer + format: int64 + additionalProperties: false UpdateUserProfile: type: object properties: - first_name: { type: string } - last_name: { type: string } - username: { type: [string, "null"] } - locale: { $ref: "#/components/schemas/Locale" } + first_name: + type: string + last_name: + type: string + username: + type: + - string + - 'null' + locale: + $ref: '#/components/schemas/Locale' additionalProperties: false QueueNotification: type: object - required: [template_key] + required: + - template_key properties: - template_key: { type: string, minLength: 3, maxLength: 101 } - locale: { $ref: "#/components/schemas/Locale", description: Explicit locale override. When omitted, the selected user's locale is used. } - recipient: { type: string, format: email } - user_id: { $ref: "#/components/schemas/UUID" } - variables: { type: object, additionalProperties: true } + template_key: + type: string + minLength: 3 + maxLength: 101 + locale: + $ref: '#/components/schemas/Locale' + description: Explicit locale override. When omitted + the selected user's locale is used.: null + recipient: + type: string + format: email + user_id: + $ref: '#/components/schemas/UUID' + variables: + type: object + additionalProperties: true attachments: type: array items: type: object - required: [filename, content_type, content_base64] + required: + - filename + - content_type + - content_base64 properties: - filename: { type: string } - content_type: { type: string } - content_base64: { type: string, format: byte } + filename: + type: string + content_type: + type: string + content_base64: + type: string + format: byte additionalProperties: false additionalProperties: false QueuedNotification: type: object - required: [id, status, requested_locale, resolved_locale, fallback_used] + required: + - id + - status + - requested_locale + - resolved_locale + - fallback_used + properties: + id: + $ref: '#/components/schemas/UUID' + status: + enum: + - queued + - suppressed + requested_locale: + $ref: '#/components/schemas/Locale' + resolved_locale: + $ref: '#/components/schemas/Locale' + fallback_used: + type: boolean + additionalProperties: false + CreateInvitation: + type: object + required: + - email + properties: + email: + type: string + format: email + workspace_id: + $ref: '#/components/schemas/UUID' + application_role_keys: + type: array + items: + type: string + maxItems: 20 + workspace_role_keys: + type: array + items: + type: string + maxItems: 20 + expires_in: + type: integer + format: int64 + minimum: 300 + maximum: 2592000 + default: 604800 + additionalProperties: false + ExchangeInvitation: + type: object + required: + - code_challenge + oneOf: + - required: + - email + - code + - required: + - invitation_id + - link_token properties: - id: { $ref: "#/components/schemas/UUID" } - status: { enum: [queued, suppressed] } - requested_locale: { $ref: "#/components/schemas/Locale" } - resolved_locale: { $ref: "#/components/schemas/Locale" } - fallback_used: { type: boolean } + invitation_id: + $ref: '#/components/schemas/UUID' + email: + type: string + format: email + code: + type: string + minLength: 8 + maxLength: 8 + pattern: ^[ABCDEFGHJKLMNPQRSTUVWXYZ23456789]{8}$ + writeOnly: true + link_token: + type: string + writeOnly: true + code_challenge: + type: string + minLength: 43 + maxLength: 43 + pattern: ^[A-Za-z0-9_-]{43}$ + writeOnly: true + additionalProperties: false + RedeemInvitation: + type: object + required: + - authorization_code + - code_verifier + properties: + authorization_code: + type: string + writeOnly: true + code_verifier: + type: string + minLength: 43 + maxLength: 128 + pattern: ^[A-Za-z0-9._~-]{43,128}$ + writeOnly: true additionalProperties: false RoleAssignment: type: object - required: [role_id] - oneOf: [{ required: [user_id] }, { required: [client_id] }] + required: + - role_id + oneOf: + - required: + - user_id + - required: + - client_id + properties: + user_id: + $ref: '#/components/schemas/UUID' + client_id: + $ref: '#/components/schemas/UUID' + role_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + PermissionKey: + type: string + minLength: 1 + maxLength: 160 + pattern: ^(\*|[a-z0-9][a-z0-9._-]{0,63}(:[a-z0-9][a-z0-9._-]{0,63})*(:\*)?)$ + RoleKey: + type: string + minLength: 1 + maxLength: 63 + pattern: ^[a-z][a-z0-9_-]{0,62}$ + CreateRole: + type: object + required: + - key + - name + - scope + - permissions + properties: + key: + $ref: '#/components/schemas/RoleKey' + name: + type: string + minLength: 1 + maxLength: 255 + scope: + type: string + enum: + - application + - workspace + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + additionalProperties: false + UpdateRole: + type: object + minProperties: 1 + properties: + name: + type: string + minLength: 1 + maxLength: 255 + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + additionalProperties: false + Role: + type: object + required: + - key + - name + - scope + - permissions + - id + - built_in + - version + properties: + key: + $ref: '#/components/schemas/RoleKey' + name: + type: string + minLength: 1 + maxLength: 255 + scope: + type: string + enum: + - application + - workspace + permissions: + type: array + minItems: 1 + maxItems: 200 + uniqueItems: true + items: + $ref: '#/components/schemas/PermissionKey' + id: + $ref: '#/components/schemas/UUID' + built_in: + type: boolean + version: + type: integer + format: int64 + minimum: 1 + additionalProperties: false + StructuredRoles: + type: object + required: + - application + - workspaces + properties: + application: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/RoleKey' + workspaces: + type: object + additionalProperties: + type: array + uniqueItems: true + items: + $ref: '#/components/schemas/RoleKey' + additionalProperties: false + CreatePermissionGrant: + type: object + required: + - subject_type + - subject_id + - permission + properties: + subject_type: + type: string + enum: + - user + - client + subject_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + permission: + $ref: '#/components/schemas/PermissionKey' + reason: + type: string + maxLength: 500 + additionalProperties: false + PermissionGrant: + type: object + required: + - subject_type + - subject_id + - permission + - id + - application_id + - canonical_scope + - status + - version + - created_at + properties: + subject_type: + type: string + enum: + - user + - client + subject_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + permission: + $ref: '#/components/schemas/PermissionKey' + reason: + type: string + maxLength: 500 + id: + $ref: '#/components/schemas/UUID' + application_id: + $ref: '#/components/schemas/UUID' + canonical_scope: + type: string + status: + type: string + enum: + - active + - revoked + version: + type: integer + format: int64 + minimum: 1 + created_at: + type: string + format: date-time + revoked_at: + type: + - string + - 'null' + format: date-time + additionalProperties: false + EffectiveAccess: + type: object + required: + - subject_type + - subject_id + - roles + - scopes + - provenance properties: - user_id: { $ref: "#/components/schemas/UUID" } - client_id: { $ref: "#/components/schemas/UUID" } - role_id: { $ref: "#/components/schemas/UUID" } - workspace_id: { $ref: "#/components/schemas/UUID" } + subject_type: + type: string + enum: + - user + - client + subject_id: + $ref: '#/components/schemas/UUID' + roles: + $ref: '#/components/schemas/StructuredRoles' + scopes: + type: array + uniqueItems: true + items: + type: string + provenance: + type: array + items: + type: object + required: + - scope + - source + properties: + scope: + type: string + source: + type: string + enum: + - role_marker + - role + - direct + - workspace_owner + role_key: + $ref: '#/components/schemas/RoleKey' + grant_id: + $ref: '#/components/schemas/UUID' + workspace_id: + $ref: '#/components/schemas/UUID' + permission: + $ref: '#/components/schemas/PermissionKey' + additionalProperties: false additionalProperties: false OwnershipTransfer: type: object - required: [new_owner_user_id] + required: + - new_owner_user_id properties: - new_owner_user_id: { $ref: "#/components/schemas/UUID" } - previous_owner_disposition: { enum: [member, remove], default: member } + new_owner_user_id: + $ref: '#/components/schemas/UUID' + previous_owner_disposition: + enum: + - member + - remove + default: member additionalProperties: false OwnershipTransferResult: type: object - required: [workspace_id, owner_user_id, previous_owner_user_id, previous_owner_disposition] + required: + - workspace_id + - owner_user_id + - previous_owner_user_id + - previous_owner_disposition properties: - workspace_id: { $ref: "#/components/schemas/UUID" } - owner_user_id: { $ref: "#/components/schemas/UUID" } - previous_owner_user_id: { $ref: "#/components/schemas/UUID" } - previous_owner_disposition: { enum: [member, remove] } - OperatorPasswordLogin: + workspace_id: + $ref: '#/components/schemas/UUID' + owner_user_id: + $ref: '#/components/schemas/UUID' + previous_owner_user_id: + $ref: '#/components/schemas/UUID' + previous_owner_disposition: + enum: + - member + - remove + additionalProperties: false + ControlUserPasswordLogin: type: object - required: [email, password] + required: + - email + - password properties: - email: { type: string, format: email } - password: { type: string, minLength: 12, maxLength: 1024, writeOnly: true } + email: + type: string + format: email + password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true additionalProperties: false - OperatorPasswordChange: + ControlUserPasswordChange: type: object - required: [new_password] + required: + - new_password properties: - current_password: { type: string, maxLength: 1024, writeOnly: true } - new_password: { type: string, minLength: 12, maxLength: 1024, writeOnly: true } + current_password: + type: string + maxLength: 1024 + writeOnly: true + new_password: + type: string + minLength: 12 + maxLength: 1024 + writeOnly: true additionalProperties: false CreateEventType: type: object - required: [name, data_schema, example_subject, example_data] + required: + - name + - data_schema + - example_subject + - example_data properties: - name: { type: string, pattern: '^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$', maxLength: 160 } - description: { type: string, maxLength: 500 } - schema_version: { type: string, pattern: '^[1-9][0-9]*\.[0-9]+$', default: '1.0' } - data_schema: { type: object, additionalProperties: true, description: JSON Schema 2020-12 with an object root. } - example_subject: { type: string, minLength: 1, maxLength: 500 } - example_data: { type: object, additionalProperties: true, description: Must validate against data_schema. } + name: + type: string + pattern: ^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$ + maxLength: 160 + description: + type: string + maxLength: 500 + schema_version: + type: string + pattern: ^[1-9][0-9]*\.[0-9]+$ + default: '1.0' + data_schema: + type: object + additionalProperties: true + description: JSON Schema 2020-12 with an object root. + example_subject: + type: string + minLength: 1 + maxLength: 500 + example_data: + type: object + additionalProperties: true + description: Must validate against data_schema. additionalProperties: false UpdateEventType: type: object properties: - description: { type: string, maxLength: 500 } - schema_version: { type: string, pattern: '^[1-9][0-9]*\.[0-9]+$' } - data_schema: { type: object, additionalProperties: true } - example_subject: { type: string, minLength: 1, maxLength: 500 } - example_data: { type: object, additionalProperties: true } - status: { enum: [active, archived] } + description: + type: string + maxLength: 500 + schema_version: + type: string + pattern: ^[1-9][0-9]*\.[0-9]+$ + data_schema: + type: object + additionalProperties: true + example_subject: + type: string + minLength: 1 + maxLength: 500 + example_data: + type: object + additionalProperties: true + status: + enum: + - active + - archived additionalProperties: false EventEnvelope: type: object - required: [specversion, id, source, type, contract_source, time, application_id, schema_version, data] - properties: - specversion: { type: string, const: '1.0' } - id: { $ref: "#/components/schemas/UUID" } - source: { type: string, format: uri } - type: { type: string } - contract_source: { type: string, enum: [platform93, application] } - time: { type: string, format: date-time } - application_id: { $ref: "#/components/schemas/UUID" } - schema_version: { type: string, pattern: '^[1-9][0-9]*\.[0-9]+$' } - subject: { type: [string, "null"] } - actor: { type: [object, "null"], additionalProperties: true } - correlation_id: { type: [string, "null"], format: uuid } - causation_id: { type: [string, "null"], format: uuid } - data: { type: object, additionalProperties: true } + required: + - specversion + - id + - source + - type + - contract_source + - time + - application_id + - schema_version + - data + properties: + specversion: + type: string + const: '1.0' + id: + $ref: '#/components/schemas/UUID' + source: + type: string + format: uri + type: + type: string + contract_source: + type: string + enum: + - platform93 + - application + time: + type: string + format: date-time + application_id: + $ref: '#/components/schemas/UUID' + schema_version: + type: string + pattern: ^[1-9][0-9]*\.[0-9]+$ + subject: + type: + - string + - 'null' + actor: + type: + - object + - 'null' + additionalProperties: true + correlation_id: + type: + - string + - 'null' + format: uuid + causation_id: + type: + - string + - 'null' + format: uuid + data: + type: object + additionalProperties: true additionalProperties: false EventTypeDefinition: type: object - required: [id, name, description, schema_version, data_schema, example_subject, example_data, example_event, source, status, version] - properties: - id: { $ref: "#/components/schemas/UUID" } - name: { type: string } - description: { type: string } - schema_version: { type: string } - data_schema: { type: object, additionalProperties: true } - example_subject: { type: string } - example_data: { type: object, additionalProperties: true } - example_event: { $ref: "#/components/schemas/EventEnvelope" } - source: { type: string, enum: [platform93, application] } - status: { type: string, enum: [active, archived] } - version: { type: integer, format: int64 } - event_count: { type: integer, format: int64 } - last_occurred_at: { type: [string, "null"], format: date-time } - created_at: { type: string, format: date-time } - updated_at: { type: string, format: date-time } + required: + - id + - name + - description + - schema_version + - data_schema + - example_subject + - example_data + - example_event + - source + - status + - version + properties: + id: + $ref: '#/components/schemas/UUID' + name: + type: string + description: + type: string + schema_version: + type: string + data_schema: + type: object + additionalProperties: true + example_subject: + type: string + example_data: + type: object + additionalProperties: true + example_event: + $ref: '#/components/schemas/EventEnvelope' + source: + type: string + enum: + - platform93 + - application + status: + type: string + enum: + - active + - archived + version: + type: integer + format: int64 + event_count: + type: integer + format: int64 + last_occurred_at: + type: + - string + - 'null' + format: date-time + created_at: + type: string + format: date-time + updated_at: + type: string + format: date-time + additionalProperties: false PublishCustomEvent: type: object - required: [type, subject, data] - properties: - type: { type: string, pattern: '^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$', maxLength: 160 } - subject: { type: string, minLength: 1, maxLength: 500 } - data: { type: object, additionalProperties: true } - correlation_id: { $ref: "#/components/schemas/UUID" } - causation_id: { $ref: "#/components/schemas/UUID" } - additionalProperties: false - CreatePersonalAPIKey: { type: object, properties: { label: { type: string, maxLength: 255 }, expires_in_days: { type: integer, minimum: 1, maximum: 366, default: 365 }, scopes: { type: array, items: { type: string } } } } - CreateFeature: { type: object, required: [key, name, value_type], properties: { key: { type: string, minLength: 1 }, name: { type: string, minLength: 1 }, value_type: { type: string, enum: [boolean, quantity, free_form] }, free_form_format: { type: string, enum: [text, csv, json], description: Required when value_type is free_form and forbidden otherwise. }, metadata: { type: object, additionalProperties: true } }, additionalProperties: false } - FeatureValue: { type: object, required: [feature_id], properties: { feature_id: { $ref: "#/components/schemas/UUID" }, boolean_value: { type: boolean }, quantity_value: { type: integer, minimum: 0 }, free_form_value: { description: "A string for text or CSV features, or any valid JSON value for JSON features." } }, additionalProperties: false } - CreateProduct: { type: object, required: [key, name], properties: { key: { type: string }, name: { type: string }, description: { type: string }, listable: { type: boolean, default: true }, status: { enum: [draft, active, archived] }, metadata: { type: object }, entitlement_config: { type: object, additionalProperties: true }, features: { type: array, items: { $ref: "#/components/schemas/FeatureValue" } } } } - UpdateProduct: { type: object, properties: { name: { type: string }, description: { type: string }, listable: { type: boolean }, status: { enum: [draft, active, archived] }, metadata: { type: object }, entitlement_config: { type: object, additionalProperties: true }, features: { type: array, items: { $ref: "#/components/schemas/FeatureValue" } } }, additionalProperties: false } - CreatePrice: { type: object, required: [key, mode, amount_minor, currency], properties: { key: { type: string }, mode: { enum: [recurring, one_time, local] }, amount_minor: { type: integer, minimum: 0 }, currency: { type: string, minLength: 3, maxLength: 3 }, currency_exponent: { type: integer, default: 2 }, interval_unit: { enum: [day, week, month, year] }, interval_count: { type: integer, minimum: 1 }, validity_seconds: { type: integer, minimum: 1 }, grace_seconds: { type: integer, minimum: 0 }, tax_behavior: { enum: [inclusive, exclusive, unspecified] }, checkout_config: { type: object }, entitlement_config: { type: object, additionalProperties: true }, features: { type: array, items: { $ref: "#/components/schemas/FeatureValue" } } } } - LocalCheckout: { type: object, required: [price_id], properties: { price_id: { $ref: "#/components/schemas/UUID" }, subject_type: { enum: [user, workspace] }, subject_id: { $ref: "#/components/schemas/UUID" }, address_id: { $ref: "#/components/schemas/UUID" }, local_reference: { type: string } } } - CreateBillingProvider: { type: object, required: [provider, secret], properties: { provider: { const: stripe }, secret: { type: string, writeOnly: true }, webhook_secret: { type: string, writeOnly: true }, api_version: { const: 2026-04-22.dahlia }, inheritable: { type: boolean, default: false } } } - CreateCheckout: { type: object, required: [price_id, success_uri, cancel_uri], properties: { price_id: { $ref: "#/components/schemas/UUID" }, provider_id: { $ref: "#/components/schemas/UUID", description: Optional provider pin; omission resolves the effective application, organization, or installation provider. }, subject_type: { enum: [user, workspace] }, subject_id: { $ref: "#/components/schemas/UUID" }, payment_methods: { type: array, items: { enum: [card, twint] } }, success_uri: { type: string, format: uri }, cancel_uri: { type: string, format: uri } } } + required: + - type + - subject + - data + properties: + type: + type: string + pattern: ^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$ + maxLength: 160 + subject: + type: string + minLength: 1 + maxLength: 500 + data: + type: object + additionalProperties: true + correlation_id: + $ref: '#/components/schemas/UUID' + causation_id: + $ref: '#/components/schemas/UUID' + additionalProperties: false + CreatePersonalAPIKey: + type: object + properties: + label: + type: string + maxLength: 255 + expires_in_days: + type: integer + minimum: 1 + maximum: 366 + default: 365 + scopes: + type: array + items: + type: string + additionalProperties: false + CreateFeature: + type: object + required: + - key + - name + - value_type + properties: + key: + type: string + minLength: 1 + name: + type: string + minLength: 1 + value_type: + type: string + enum: + - boolean + - quantity + - free_form + free_form_format: + type: string + enum: + - text + - csv + - json + description: Required when value_type is free_form and forbidden otherwise. + metadata: + type: object + additionalProperties: true + additionalProperties: false + FeatureValue: + type: object + required: + - feature_id + properties: + feature_id: + $ref: '#/components/schemas/UUID' + boolean_value: + type: boolean + quantity_value: + type: integer + minimum: 0 + free_form_value: + description: A string for text or CSV features, or any valid JSON value for JSON features. + additionalProperties: false + CreateProduct: + type: object + required: + - key + - name + properties: + key: + type: string + name: + type: string + description: + type: string + listable: + type: boolean + default: true + status: + enum: + - draft + - active + - archived + metadata: + type: object + entitlement_config: + type: object + additionalProperties: true + features: + type: array + items: + $ref: '#/components/schemas/FeatureValue' + additionalProperties: false + UpdateProduct: + type: object + properties: + name: + type: string + description: + type: string + listable: + type: boolean + status: + enum: + - draft + - active + - archived + metadata: + type: object + entitlement_config: + type: object + additionalProperties: true + features: + type: array + items: + $ref: '#/components/schemas/FeatureValue' + additionalProperties: false + CreatePrice: + type: object + required: + - key + - mode + - amount_minor + - currency + properties: + key: + type: string + mode: + enum: + - recurring + - one_time + - local + amount_minor: + type: integer + minimum: 0 + currency: + type: string + minLength: 3 + maxLength: 3 + currency_exponent: + type: integer + default: 2 + interval_unit: + enum: + - day + - week + - month + - year + interval_count: + type: integer + minimum: 1 + validity_seconds: + type: integer + minimum: 1 + grace_seconds: + type: integer + minimum: 0 + tax_behavior: + enum: + - inclusive + - exclusive + - unspecified + checkout_config: + type: object + entitlement_config: + type: object + additionalProperties: true + features: + type: array + items: + $ref: '#/components/schemas/FeatureValue' + additionalProperties: false + LocalCheckout: + type: object + required: + - price_id + properties: + price_id: + $ref: '#/components/schemas/UUID' + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + address_id: + $ref: '#/components/schemas/UUID' + external_reference: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false + CreateBillingProvider: + type: object + required: + - provider + - secret + properties: + provider: + const: stripe + secret: + type: string + writeOnly: true + webhook_secret: + type: string + writeOnly: true + api_version: + const: 2026-04-22.dahlia + inheritable: + type: boolean + default: false + additionalProperties: false + CreateCheckout: + type: object + required: + - price_id + - success_uri + - cancel_uri + properties: + price_id: + $ref: '#/components/schemas/UUID' + provider_id: + $ref: '#/components/schemas/UUID' + description: Optional provider pin; omission resolves the effective application + organization: null + or installation provider.: null + subject_type: + enum: + - user + - workspace + subject_id: + $ref: '#/components/schemas/UUID' + payment_methods: + type: array + items: + enum: + - card + - twint + success_uri: + type: string + format: uri + cancel_uri: + type: string + format: uri + external_reference: + type: string + minLength: 1 + maxLength: 255 + additionalProperties: false diff --git a/cmd/platform93/main.go b/cmd/platform93/main.go index 107889b..2a95ba4 100644 --- a/cmd/platform93/main.go +++ b/cmd/platform93/main.go @@ -48,7 +48,11 @@ func run() error { if err := database.Status(databaseURL); err != nil { return err } + if err := database.ValidateAuthorization(databaseURL); err != nil { + return err + } fmt.Println("database: ready") + fmt.Println("authorization: valid") return nil case "backup": if len(os.Args) != 3 { diff --git a/conformance/jwt.json b/conformance/jwt.json index feff044..bac778c 100644 --- a/conformance/jwt.json +++ b/conformance/jwt.json @@ -16,7 +16,17 @@ { "name": "missing_application", "mutation": "missing_application", "accept": false }, { "name": "missing_token_kind", "mutation": "missing_token_kind", "accept": false }, { "name": "missing_actor_type", "mutation": "missing_actor_type", "accept": false }, - { "name": "operator_actor_rejected", "mutation": "operator_actor", "accept": false }, + { "name": "missing_roles", "mutation": "missing_roles", "accept": false }, + { "name": "space_injected_scope", "mutation": "space_injected_scope", "accept": false }, + { "name": "tab_injected_scope", "mutation": "tab_injected_scope", "accept": false }, + { "name": "unicode_injected_scope", "mutation": "unicode_injected_scope", "accept": false }, + { "name": "encoded_space_scope", "mutation": "encoded_space_scope", "accept": false }, + { "name": "cross_application_scope", "mutation": "cross_application_scope", "accept": false }, + { "name": "embedded_wildcard_scope", "mutation": "embedded_wildcard_scope", "accept": false }, + { "name": "duplicate_scope", "mutation": "duplicate_scope", "accept": false }, + { "name": "invalid_roles", "mutation": "invalid_roles", "accept": false }, + { "name": "delegated_roles", "mutation": "delegated_roles", "accept": false }, + { "name": "control_user_actor_rejected", "mutation": "control_user_actor", "accept": false }, { "name": "algorithm_confusion", "mutation": "wrong_algorithm", "accept": false }, { "name": "missing_key_id", "mutation": "missing_kid", "accept": false }, { "name": "unknown_key_id", "mutation": "unknown_kid", "accept": false }, diff --git a/conformance/webhook.json b/conformance/webhook.json index 1ae7504..1f2d3bf 100644 --- a/conformance/webhook.json +++ b/conformance/webhook.json @@ -1,6 +1,6 @@ { - "raw_body": "{\"specversion\":\"1.0\",\"id\":\"01900000-0000-7000-8000-000000000001\",\"source\":\"platform93://applications/01900000-0000-7000-8000-000000000003\",\"type\":\"user.created\",\"contract_source\":\"platform93\",\"time\":\"2027-01-15T08:00:00Z\",\"application_id\":\"01900000-0000-7000-8000-000000000003\",\"schema_version\":\"1.0\",\"subject\":\"user/01900000-0000-7000-8000-000000000002\",\"actor\":{\"type\":\"operator\",\"id\":\"01900000-0000-7000-8000-000000000004\"},\"correlation_id\":null,\"causation_id\":null,\"data\":{\"user_id\":\"01900000-0000-7000-8000-000000000002\",\"email_verified\":false,\"is_org_verified\":false}}", + "raw_body": "{\"specversion\":\"1.0\",\"id\":\"01900000-0000-7000-8000-000000000001\",\"source\":\"platform93://applications/01900000-0000-7000-8000-000000000003\",\"type\":\"user.created\",\"contract_source\":\"platform93\",\"time\":\"2027-01-15T08:00:00Z\",\"application_id\":\"01900000-0000-7000-8000-000000000003\",\"schema_version\":\"1.0\",\"subject\":\"user/01900000-0000-7000-8000-000000000002\",\"actor\":{\"type\":\"control_user\",\"id\":\"01900000-0000-7000-8000-000000000004\"},\"correlation_id\":null,\"causation_id\":null,\"data\":{\"user_id\":\"01900000-0000-7000-8000-000000000002\",\"email_verified\":false,\"is_org_verified\":false}}", "secret": "p93_whsec_conformance", "timestamp": 1800000000, - "signature": "t=1800000000,v1=3c6a1a33573a6a9cd72840de3ef3ec153f7f4a728e6c321b973beeaa48287231" + "signature": "t=1800000000,v1=971db0085450a1bb7d60645af1541328eb88f23dd865ed2e5b33d82eb35d0415" } diff --git a/docs/adr/0003-synchronized-release-train.md b/docs/adr/0003-synchronized-release-train.md index 85f93cf..0ba95db 100644 --- a/docs/adr/0003-synchronized-release-train.md +++ b/docs/adr/0003-synchronized-release-train.md @@ -14,5 +14,5 @@ keyless publishing where supported, and images include SBOM and provenance metad Components do not drift across independent versions. A failed verification prevents all publication, but a registry outage can still produce a partial external release; -reruns must be idempotent and operators must verify every registry before announcing +reruns must be idempotent and maintainers must verify every registry before announcing the release. diff --git a/docs/adr/0005-application-workspace-model.md b/docs/adr/0005-application-workspace-model.md index ba736e9..b5e6ebf 100644 --- a/docs/adr/0005-application-workspace-model.md +++ b/docs/adr/0005-application-workspace-model.md @@ -12,12 +12,12 @@ workspace. Workspaces are optional application resources; a user can own or join multiple workspaces, and ownership is stored separately from membership. The installation has one `/oidc` issuer and signing-key lifecycle. Control tokens -use audience `platform93:control` and actor type `operator`. Application tokens use +use audience `platform93:control` and actor type `control_user`. Application tokens use audience `platform93:application:{application_id}` and actor type `user` or `client`. Every verifier must validate issuer, exact audience, actor type, and application ID. -Operators are installation-wide identities stored independently from application -users. An operator can hold one installation role and multiple organization roles. +Platform users are installation-wide identities stored independently from application +users. A Platform user can hold one installation role and multiple organization roles. Installation roles grant deployment-wide control; organization roles grant control over every application in that organization. Application user creation never grants control-plane authority, even when both records use the same email address. diff --git a/docs/application-configuration.md b/docs/application-configuration.md index 75a1b65..2a90d1d 100644 --- a/docs/application-configuration.md +++ b/docs/application-configuration.md @@ -21,6 +21,21 @@ The generated client also exports the lower-level `publicConfig(...)` operation. The authentication package uses this same endpoint when it builds PKCE authorization requests from the application's public flow configuration. +## Browser Origins + +Platform93 permits direct browser SDK requests only from exact origins derived from +an enabled public OAuth client's web redirect URIs or from a verified application +domain. Register `https://app.example/auth/callback` on a public client to permit +the origin `https://app.example`; paths do not widen access beyond that origin. +Loopback HTTP origins are supported for development through the same exact redirect +registration. Custom mobile schemes do not create browser CORS origins. + +Cross-origin requests never include Platform93 control cookies. Allowed application +origins may send bearer tokens and the documented `Content-Type`, `Authorization`, +`Idempotency-Key`, and `If-Match` headers. Unknown origins, methods, and request +headers fail closed. OIDC discovery and JWKS are public; token and userinfo access +uses the same registered public-client origin policy. + Use it for client-safe values such as branding, support links, feature display preferences, or public service identifiers. Never store credentials, tokens, provider secrets, private endpoints, or operational data in this object. @@ -47,12 +62,20 @@ enforces these values on the server rather than relying on clients to hide UI: prevents outstanding email challenges from being exchanged. - `personal_api_keys_enabled`: permits users to create and use personal API keys. Disabling it revokes every active personal key in the application. -- `delegation_enabled`: permits audited operator delegation into application-user +- `delegation_enabled`: permits audited Platform user delegation into application-user access. Disabling it revokes active delegations and their delegated sessions. +- `user_invitations_enabled`: permits workspace owners and members with invitation + management permission to create and resend invitations. Administrative Platform users + and machine clients remain governed by their own permissions. Disabling this does + not invalidate invitations that were already sent. +- `custom_token_claim_keys`: allowlists user `custom_attributes` keys that may be + copied under the JWT and userinfo `custom_claims` object. Standard claims cannot + be replaced, and the serialized object is limited to 4 KiB. New applications default to public registration, password and passwordless authentication enabled, and personal API keys and delegation disabled. Provider credentials and inheritance remain separate from both configuration objects. +User-managed invitations are disabled and the custom-claim allowlist is empty. All configuration writes use the application ETag through `If-Match`. Public configuration writes replace the complete public object. Internal writes are diff --git a/docs/architecture.md b/docs/architecture.md index 5010e2d..0640b37 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,30 +8,31 @@ Platform93 is being designed as a modular monolith backed by PostgreSQL. ## Boundaries - The hierarchy is installation, organization, application, workspace, and user. -- Installation operators administer organizations and their applications. There are - no application-level operator memberships. -- Control-plane identities are called operators, not users. An operator may have an +- Platform users administer organizations and their applications. There are no + application-level Platform user memberships. +- A Platform user is a control-plane identity, stored independently from application + users. A Platform user may have an installation role, one or more organization memberships, or both. Installation roles are `owner`, `admin`, and `auditor`; organization roles are `owner`, `admin`, `auditor`, and `member`. -- Installation owners and admins add installation operators directly. Organization +- Installation owners and admins add Platform users directly. Organization owners and admins issue one-time organization invitations; accepting an invitation - creates or reuses the operator identity, adds the membership, and starts a control + creates or reuses the Platform user identity, adds the membership, and starts a control session. This acceptance flow works without SMTP when the credential is shared out of band. -- Operators sign in with email codes or magic links and may add an Argon2id password +- Platform users sign in with email codes or magic links and may add an Argon2id password after a recent email-authenticated session. Password changes revoke every other - operator session. External operator identities require a dedicated control-plane + control session. External Platform user identities require a dedicated control-plane linking flow and never inherit application-user login providers implicitly. - A user belongs to exactly one application, can exist without a workspace, and can own or join multiple workspaces. - Workspaces are optional for consuming applications and can model teams, customer accounts, or other shared billing and authorization subjects. - One installation issuer signs all JWTs. Exact audience and `actor_type` checks keep - operator, user, and machine-client tokens non-interchangeable. + Platform user, application user, and machine-client tokens non-interchangeable. - Applications isolate identities, credentials, products, billing, entitlements, events, and data. -- Operator middleware resolves application ownership through the organization - membership before any application administration handler runs. Read-only operator +- Control-user middleware resolves application ownership through the organization + membership before any application administration handler runs. Read-only Platform user roles cannot perform mutations. - PostgreSQL RLS is a required pre-1.0 defense-in-depth layer and is not yet enabled; the current runtime must not be represented as RLS-backed. @@ -40,6 +41,9 @@ Platform93 is being designed as a modular monolith backed by PostgreSQL. - Control JWTs use audience `platform93:control`. Application JWTs use audience `platform93:application:{application_id}` and include that exact `application_id`. +- Platform user JWTs use `actor_type=control_user`; normal control sessions use + `token_kind=control`. Application users use `actor_type=user`, while backend OAuth + clients use `actor_type=client` and `token_kind=machine`. - Application and workspace role markers plus expanded permission paths are emitted in the standard space-delimited `scope` claim and recomputed at login and refresh. - Access JWTs expire after five minutes. Permission changes do not require live checks diff --git a/docs/authorization.md b/docs/authorization.md new file mode 100644 index 0000000..3636a97 --- /dev/null +++ b/docs/authorization.md @@ -0,0 +1,58 @@ +# Application authorization + +Platform93 authorizes application requests from the JWT `scope` claim. The +structured `roles` claim is for user interfaces and diagnostics; applications +must not authorize from role names alone. + +## Permission keys + +Role definitions, direct grants, delegation requests, and permission checks use +relative permission keys. A key is one or more lowercase ASCII segments joined +by `:`, for example `invoices:read`, `members:42:read`, or `members:42:*`. + +Each segment starts with a lowercase letter or digit and may then contain +lowercase letters, digits, `.`, `_`, or `-`. `*` is valid only as the complete +final segment. A key is at most 160 characters. Whitespace, Unicode, `%`, path +separators, empty segments, traversal segments, and embedded wildcards are +rejected rather than escaped or normalized. + +API callers never submit complete `/applications/...` paths. Platform93 combines +validated permission keys with trusted application and optional workspace UUIDs: + +```text +invoices:read +-> /applications/{application_id}/invoices/read + +members:42:* +-> /applications/{application_id}/workspaces/{workspace_id}/members/42/* +``` + +Wildcards match only complete path boundaries. A grant ending in `/*` does not +match a similarly prefixed sibling resource or another workspace. + +## Roles and direct scopes + +Roles are reusable application- or workspace-scoped permission sets. Direct +grants are immutable, additive assignments to one user or machine client and +are intended for dynamic resource-specific access. Revocation records who +revoked the grant and when; it does not mutate the original grant definition. + +Workspace ownership is never represented by a grant. It remains a live database +fact and contributes the workspace owner wildcard only while ownership is active. +Invitations assign roles, not direct grants. + +Tokens contain the sorted, deduplicated union of role markers, expanded role +permissions, active direct grants, and current workspace-owner wildcards. PATs +can only reduce the user's current effective scopes. Delegated tokens contain +only their validated reduction and expose empty structured roles. + +## Verification + +Use a Platform93 server SDK verifier. Verifiers require RS256, the installation +issuer, exact application audience and ID, a valid actor/token-kind pair, and +canonical authorization claims. A malformed, duplicated, cross-application, or +whitespace-injected scope invalidates the whole JWT. + +Applications with many workspace assignments can produce large JWTs. Configure +ingress proxies and application servers to accept the required Authorization +header size; do not truncate the header or parse only a prefix. diff --git a/docs/invitations.md b/docs/invitations.md new file mode 100644 index 0000000..af7c75b --- /dev/null +++ b/docs/invitations.md @@ -0,0 +1,32 @@ +# Application And Workspace Invitations + +Platform93 uses one application invitation model. An invitation can create basic +application access, assign application roles, and optionally add the recipient to +one workspace with workspace roles. It works independently of whether public +registration is enabled. + +`internal_config.user_invitations_enabled` controls invitations created by +application users and defaults to `false`. When enabled, workspace owners and +members with the workspace invitation-management permission can invite recipients +to that workspace and assign workspace roles. Control-plane administrators and +machine clients with invitation-management permission are not affected by this +toggle. Disabling it does not revoke pending invitations. + +Invitation links are sent to the application's configured +`auth_config.flows.invitation_redirect_uri`. The browser application uses +`@supaapps/platform93-auth` to parse the link or collect the email and eight-character +code. The package generates an S256 PKCE pair, exchanges the invitation, and redeems +the returned one-time authorization code. Acceptance verifies the email, creates or +reuses the application user, and applies roles and workspace membership atomically. + +Backend automation uses an OAuth machine client with +`/applications/{application_id}/invitations/manage`, or the corresponding workspace +permission. Workspace owners can list active members and pending recipients through: + +```text +GET /v1/applications/{application_id}/workspaces/{workspace_id}/access +``` + +Resend rotates both credentials, invalidates prior links/codes, extends expiry, and +is limited to once per 60 seconds. Pending invitations expire after seven days by +default; callers may choose between five minutes and thirty days. diff --git a/docs/migrating-from-supaapps-platform.md b/docs/migrating-from-supaapps-platform.md new file mode 100644 index 0000000..4f07bd0 --- /dev/null +++ b/docs/migrating-from-supaapps-platform.md @@ -0,0 +1,82 @@ +# Migrating From Supaapps Platform + +Platform93 is a native replacement contract, not a legacy API or database clone. +Applications replace their SDK configuration and migrate their own identifiers; +Platform93 does not import an old database or automatically adopt Stripe objects. + +## Identity And Authorization + +| Supaapps platform | Platform93 | +| --- | --- | +| Root realm | Installation control plane | +| Application realm | Application | +| Realm user | Application user | +| Workspace | Workspace | +| Root scopes | Installation and organization administrative roles | +| Realm/workspace scopes | Application and workspace roles with expanded permission paths | +| Auth guard packages | Platform93 TypeScript, Go, PHP, or Python verifier | +| Config fetcher | Public application configuration SDK method | + +Password, email-code, magic-link, Google, Apple, MFA, email verification, rotating +sessions, personal API keys, and delegation have native Platform93 flows. OAuth +browser integrations use authorization code with PKCE. Application invitations +and optional workspace role assignment use the unified invitation API; invitation +links always return to the application's configured redirect URI. + +## Billing And Entitlements + +| Supaapps platform | Platform93 | +| --- | --- | +| `product_key` | Product `key` | +| Product `config` | Typed feature values and `entitlement_config` | +| `config_version` | Immutable price snapshot | +| `local_reference` | `external_reference` | +| Entitlement/subscription messages | Signed, versioned webhooks | + +Platform93 owns its catalog. Products define entitlement defaults and immutable +prices snapshot effective feature values and configuration. Stripe metadata carries +only Platform93 application, product, price, checkout, subject, and external +reference identifiers; entitlement configuration is not copied into Stripe. + +Existing Stripe products and subscriptions are not adopted automatically. Recreate +or explicitly map catalog records before moving checkout traffic. Application- +triggered no-payment trials remain a documented deferred capability. + +## Notifications And Events + +Replace notification queue messages with the backend machine SDK. Machine clients +use OAuth client credentials and explicit `notifications:send` or +`notifications:send_external` permissions. Callers select an active template and +provide validated variables; raw subject/body delivery is intentionally unsupported. + +Replace RabbitMQ entitlement and subscription consumers with outgoing Platform93 +webhooks. Verify signatures against the raw body, dispatch Platform93 events by +their versioned contract, and handle application-defined events as custom JSON. +Event handlers must be idempotent because delivery is at least once. + +## Package Replacement + +| Previous integration responsibility | Platform93 package | +| --- | --- | +| Browser API/config client | `@supaapps/platform93-sdk` | +| Browser password, passwordless, invitation, PKCE, and MFA flows | `@supaapps/platform93-auth` and `@supaapps/platform93-react` | +| Node backend guard and machine service calls | `@supaapps/platform93-server` | +| TypeScript webhook contracts and dispatch | `@supaapps/platform93-events` | +| PHP guard, webhook verification, and machine calls | `supaapps/platform93` | +| Python guard and machine calls | `supaapps-platform93-auth` | +| Python webhook verification | `supaapps-platform93-webhooks` | +| Go guard, webhook dispatch, and machine calls | `github.com/supaapps/platform93/sdk/go/...` | + +Public configuration is read from the application runtime-config endpoint through +the browser-safe SDK. Backend configuration and credentials remain in the consuming +application's secret manager; Platform93 does not recreate the old config-fetcher +process or distribute machine secrets to browsers. + +## Cutover Checklist + +1. Create the organization, application, public OAuth client, machine clients, and roles. +2. Configure redirects, providers, application policy, templates, and public config. +3. Recreate products, immutable prices, feature values, and provider mappings. +4. Replace backend auth guards, notification publishing, event consumers, and billing correlation fields. +5. Replace browser authentication and invitation handling with Platform93 SDK flows. +6. Validate issuer, exact application audience, actor type, permissions, webhooks, and reconciliation before switching traffic. diff --git a/docs/native-mobile-auth.md b/docs/native-mobile-auth.md new file mode 100644 index 0000000..141c299 --- /dev/null +++ b/docs/native-mobile-auth.md @@ -0,0 +1,52 @@ +# Native mobile authentication + +Expo and React Native applications use a dedicated Platform93 public OAuth client. +Register the app's exact callback URI, for example `sampleapp://auth/callback`, in that +client's `redirect_uris` and allow `authorization_code` and `refresh_token`. + +Platform93 accepts custom schemes only for public clients. Redirect matching is exact; +there are no scheme, host, or path wildcards. HTTPS remains required for normal web +origins, while HTTP is limited to loopback development addresses. Unsafe schemes such +as `javascript`, `data`, and `file` are rejected. + +The application-wide flow configuration may continue to point at the web client. A +native application passes its own client ID and redirect URI to +`createAuthorizationRequest`, or uses `@supaapps/platform93-expo` for Google and Apple: + +```ts +import * as SecureStore from "expo-secure-store"; +import * as WebBrowser from "expo-web-browser"; +import { makeRedirectUri } from "expo-auth-session"; +import { Platform93ExpoAuth } from "@supaapps/platform93-expo"; + +const redirectUri = makeRedirectUri({ scheme: "sampleapp", path: "auth/callback" }); +const auth = new Platform93ExpoAuth({ + baseUrl: "https://platform93.example.com", + applicationId: "019...", + redirectUri, + secureStore: SecureStore, + webBrowser: WebBrowser, +}); + +await auth.initialize(); +await auth.signInWithGoogle({ flow: "automatic" }); +``` + +Google and Apple redirect to Platform93's fixed provider callback first. Platform93 +then redirects to the native URI with a short-lived, single-use exchange credential. +The adapter exchanges it immediately and stores only the rotating refresh credential +in SecureStore. No OAuth client secret belongs in the mobile application. + +For a direct OIDC authorization-code flow, retain the returned verifier and state: + +```ts +const request = await auth.auth.createAuthorizationRequest({ + clientId: "mobile", + redirectUri, +}); +``` + +The consuming app must also register the custom scheme in its Expo/app configuration. +Production apps should prefer an HTTPS universal/app link when their deployment can +prove domain ownership, because operating systems cannot guarantee exclusive ownership +of arbitrary custom schemes. diff --git a/docs/notifications.md b/docs/notifications.md index 1e4b738..5f631b1 100644 --- a/docs/notifications.md +++ b/docs/notifications.md @@ -5,9 +5,9 @@ records. A draft can be previewed and then published; editing an existing versio Templates have a subject, a required plain-text fallback, an optional HTML body, and a typed schema for application-supplied variables. -Platform93 seeds published installation templates for operator sign-in, -application sign-in, email verification/change, password reset, organization -invitations, and workspace invitations. Applications list these basic templates +Platform93 seeds published installation templates for Platform user sign-in, +application sign-in, email verification/change, password reset, organization, +application, and workspace invitations. Applications list these basic templates as inherited defaults. Editing an inherited template creates an application draft; it does not mutate the installation version. Once that draft is published, it becomes the effective template for that application. Rendered subject, text, @@ -53,6 +53,7 @@ inserts it at the active cursor, and renders sample values without sending mail. These codes are resolved by Platform93 for every queued notification: - `application_id`, `application_name`, and `application_slug` +- `support_name`, `support_email`, and `support_url` from public application configuration - `recipient_email` - `current_year` - `message_locale` @@ -84,7 +85,7 @@ The response includes labels, descriptions, availability rules, declared types, and safe preview samples for admin tooling. System templates also declare flow-specific codes such as `code`, `magic_link`, -`invitation_link`, `invitation_token`, `workspace_name`, and `expires_at`. These +`invitation_code`, `invitation_link`, `workspace_name`, roles, and `expires_at`. These are populated only by Platform93; an application cannot supply or spoof them in a built-in security flow. @@ -99,9 +100,28 @@ development. Email magic links return to the configured sign-in URI with a one-time challenge. After consuming the challenge, `@supaapps/platform93-auth` can call `createAuthorizationRequest()` to generate a verifier, S256 code challenge, and -authorization URL. The invitation URI receives the one-time workspace invitation -credential; the application authenticates the user before calling the invitation -acceptance endpoint. +authorization URL. The invitation URI receives an application ID, invitation ID, +and one-time link credential. Applications exchange it through the browser auth +package; email plus the eight-character invitation code is the equivalent manual +path. + +## Machine Delivery + +Application backends send template notifications with an application machine +client. Create a machine client, assign `notification_sender` or a custom role, +and keep its client secret in the backend secret manager. The server SDK exchanges +client credentials, caches the short-lived JWT, and calls: + +```text +POST /v1/applications/{application_id}/notifications +``` + +`notifications:send` permits delivery to an application `user_id`. +`notifications:send_external` is separate and permits arbitrary recipients. +Application-user tokens, personal API keys, delegated sessions, Platform user tokens, +and browser requests are rejected by this endpoint. +Keys under `platform93.*` are reserved for internal security, invitation, account, +and billing flows and cannot be selected by a machine client. ## Delivery Safety diff --git a/docs/organization-management.md b/docs/organization-management.md index a0faac6..26a7036 100644 --- a/docs/organization-management.md +++ b/docs/organization-management.md @@ -1,6 +1,6 @@ # Organization management and governance -Platform93 can expose an optional machine-only API for installation provisioning systems. It is disabled by default and is independent of operator sessions and application OAuth clients. +Platform93 can expose an optional machine-only API for installation provisioning systems. It is disabled by default and is independent of Platform user sessions and application OAuth clients. ## Security boundary @@ -22,11 +22,11 @@ curl -fsS -H "Authorization: Bearer $ACCESS_TOKEN" \ https://platform93.example/v1/management/organizations ``` -The initial management scope is `/management/organizations/*`. It permits organization lifecycle, application lifecycle, and organization-policy operations. It does not grant installation provider, signing-key, operator, audit-export, or recovery access. +The initial management scope is `/management/organizations/*`. It permits organization lifecycle, application lifecycle, and organization-policy operations. It does not grant installation provider, signing-key, Platform user, audit-export, or recovery access. ## Organization policy -Every organization receives an installation-owned policy. Organization operators can read the policy and current usage, but only installation owners/administrators and management clients can update it. +Every organization receives an installation-owned policy. Organization Platform users can read the policy and current usage, but only installation owners/administrators and management clients can update it. Limits are nullable. `null` means unlimited and `0` prevents creation: @@ -35,7 +35,7 @@ Limits are nullable. `null` means unlimited and `0` prevents creation: Creation checks lock the policy row in the same transaction as the new application or user. Concurrent requests therefore cannot exceed a configured limit. -The policy can disable public registration, password authentication, passwordless authentication, personal API keys, operator delegation, organization provider overrides, application provider overrides, custom events, and outgoing webhooks. Existing installations default to all capabilities enabled. +The policy can disable public registration, password authentication, passwordless authentication, personal API keys, Platform user delegation, organization provider overrides, application provider overrides, custom events, and outgoing webhooks. Existing installations default to all capabilities enabled. Disabling a capability is immediate. Platform93 also applies these cleanup rules: @@ -50,4 +50,4 @@ Policy updates use optimistic concurrency. Read the `ETag` from `GET .../policy` The machine boundary supports organization lifecycle, application lifecycle, and policy operations under `/v1/management/organizations` as described in the OpenAPI document. -Organizations created through this API intentionally have no synthetic operator membership. Provisioning can separately invite or assign real control-plane operators through the operator workflow. +Organizations created through this API intentionally have no synthetic Platform user membership. Provisioning can separately invite or assign real Platform users through the control-plane invitation workflow. diff --git a/docs/platform-user-authentication.md b/docs/platform-user-authentication.md new file mode 100644 index 0000000..03f4dba --- /dev/null +++ b/docs/platform-user-authentication.md @@ -0,0 +1,40 @@ +# Platform user authentication + +Platform users administer the installation and organizations. They are not application users, even when both records use the same email address. + +Control access tokens always use the installation issuer, audience `platform93:control`, `actor_type=control_user`, and `token_kind=control`. Google and Apple identities linked to an application user are never reused for Platform access. Control tokens remain invalid at application endpoints. + +## Sign-in methods + +Installation owners configure the available methods under **Platform > Identity**: + +- Email code and magic-link sign-in require an active installation SMTP provider. +- Password sign-in is globally switchable and is available only to accounts that have stored a password. +- Google and Apple require an installation-scoped provider with **Platform user sign-in** enabled. +- Provider inheritance is independent. A provider may authenticate Platform users, be inherited by applications, do both, or do neither. + +The public `GET /v1/control/auth/methods` endpoint is the source of truth for rendering a login screen. Sessions record `authenticated_at` and `amr`; access tokens expose `amr` without changing the control audience. + +## External identities + +Platform93 uses the same installation-wide provider callback URLs for application and Platform flows: + +- Google: `/v1/auth/providers/google/callback` +- Apple: `/v1/auth/providers/apple/callback` + +Signed state resolves the pending flow. Organization- and application-scoped provider credentials can never authenticate a Platform user. + +Verified-email matching does not link or create a Platform account. A Google or Apple subject becomes usable only after either: + +1. An authenticated Platform user starts a recent-auth account-linking flow. +2. A Platform-user invitation explicitly requires that provider and the provider-verified email exactly matches the invitation. + +Disabling a provider preserves linked identities. Re-enabling the same provider configuration makes them usable again. + +## Invitations and lockout prevention + +Installation and organization Platform users are provisioned through invitations. Each invitation selects `email`, `google`, or `apple` for initial onboarding. Resending rotates the credential, refreshes expiry, and invalidates outstanding provider challenges. The selected method does not restrict later sign-in after acceptance. + +Platform93 blocks policy changes, provider disabling, and identity unlinking when the current Platform user or any active installation owner would lose every usable sign-in method. Changes affecting only non-owner accounts require explicit confirmation and return `affected_users` in the RFC 9457 problem response. + +If setup is completed without SMTP, the bootstrap owner must set a password. Recovery remains available through the `platform93 recover` command. diff --git a/docs/provider-inheritance.md b/docs/provider-inheritance.md index b02ade8..7a2e264 100644 --- a/docs/provider-inheritance.md +++ b/docs/provider-inheritance.md @@ -14,13 +14,13 @@ Inheritance can be enabled or disabled after a provider is created without resub ## Authentication -Google and Sign in with Apple can be configured at any scope. Each application still has its own users, external identities, challenges, sessions, redirect allowlist, and callback path even when it inherits provider credentials. +Google and Sign in with Apple can be configured at any scope. Each application still has its own users, external identities, challenges, sessions, and consuming-application redirect allowlist even when it inherits provider credentials. The provider callback is installation-wide: Platform93 resolves the application from the random, single-use sign-in state stored before redirecting to the provider. -Register these callback patterns with the provider: +Register these exact callback URLs once with the provider: ```text -https://platform.example/v1/applications/{application_id}/auth/providers/google/callback -https://platform.example/v1/applications/{application_id}/auth/providers/apple/callback +https://platform.example/v1/auth/providers/google/callback +https://platform.example/v1/auth/providers/apple/callback ``` Google requires a web OAuth client ID and client secret. Apple requires a Services ID, Team ID, Sign in with Apple Key ID, and ES256 private key. Apple posts the authorization result to the callback, so the public Platform93 URL must use HTTPS outside local development. diff --git a/internal/authorization/permission.go b/internal/authorization/permission.go new file mode 100644 index 0000000..2756bf8 --- /dev/null +++ b/internal/authorization/permission.go @@ -0,0 +1,195 @@ +package authorization + +import ( + "fmt" + "strings" + + "github.com/google/uuid" +) + +const ( + MaxPermissionLength = 160 + MaxRoleKeyLength = 63 +) + +// ValidateRelativePermission accepts only canonical, colon-delimited permission keys. +func ValidateRelativePermission(value string) error { + if value == "" || len(value) > MaxPermissionLength { + return fmt.Errorf("permission must contain 1 to %d ASCII characters", MaxPermissionLength) + } + if !isASCII(value) || strings.ContainsAny(value, " /\\%\t\r\n") { + return fmt.Errorf("permission must use lowercase ASCII colon-delimited segments") + } + segments := strings.Split(value, ":") + for index, segment := range segments { + if segment == "*" { + if index != len(segments)-1 { + return fmt.Errorf("wildcard must be the final complete segment") + } + continue + } + if !validSegment(segment) { + return fmt.Errorf("permission segment %d is invalid", index+1) + } + } + return nil +} + +func ValidateRoleKey(value string) error { + if value == "" || len(value) > MaxRoleKeyLength || !isASCII(value) { + return fmt.Errorf("role key must contain 1 to %d ASCII characters", MaxRoleKeyLength) + } + if value[0] < 'a' || value[0] > 'z' { + return fmt.Errorf("role key must start with a lowercase letter") + } + for index := 1; index < len(value); index++ { + character := value[index] + if character < 'a' || character > 'z' { + if character < '0' || character > '9' { + if character != '_' && character != '-' { + return fmt.Errorf("role key contains an invalid character") + } + } + } + } + return nil +} + +func CanonicalScope(applicationID string, workspaceID *string, permission string) (string, error) { + if err := ValidateRelativePermission(permission); err != nil { + return "", err + } + if !validIdentifier(applicationID) { + return "", fmt.Errorf("application identifier is invalid") + } + prefix := "/applications/" + applicationID + if workspaceID != nil { + if !validIdentifier(*workspaceID) { + return "", fmt.Errorf("workspace identifier is invalid") + } + prefix += "/workspaces/" + *workspaceID + } + return prefix + "/" + strings.ReplaceAll(permission, ":", "/"), nil +} + +func RoleMarker(applicationID string, workspaceID *string, roleKey string) (string, error) { + if err := ValidateRoleKey(roleKey); err != nil { + return "", err + } + prefix := "/applications/" + applicationID + if workspaceID != nil { + if !validIdentifier(*workspaceID) { + return "", fmt.Errorf("workspace identifier is invalid") + } + prefix += "/workspaces/" + *workspaceID + } + return prefix + "/roles/" + roleKey, nil +} + +// ValidateScopeClaim rejects non-canonical serialization as well as invalid paths. +func ValidateScopeClaim(scope, applicationID string) error { + if scope == "" { + return nil + } + if scope != strings.TrimSpace(scope) || strings.ContainsAny(scope, "\t\r\n") || strings.Contains(scope, " ") { + return fmt.Errorf("scope claim is not canonically space-delimited") + } + prefix := "/applications/" + applicationID + "/" + seen := map[string]struct{}{} + for _, value := range strings.Split(scope, " ") { + if _, duplicate := seen[value]; duplicate { + return fmt.Errorf("scope claim contains a duplicate value") + } + seen[value] = struct{}{} + if protocolScope(value) { + continue + } + if !strings.HasPrefix(value, prefix) || !validAbsolutePath(value) { + return fmt.Errorf("scope %q is invalid for the application", value) + } + } + return nil +} + +func ValidateScopeValues(values []string, applicationID string) error { + if len(values) == 0 { + return nil + } + return ValidateScopeClaim(strings.Join(values, " "), applicationID) +} + +func protocolScope(value string) bool { + switch value { + case "openid", "profile", "email", "offline_access": + return true + default: + return false + } +} + +func Match(granted, wanted string) bool { + if !validAbsolutePath(granted) || !validAbsolutePath(wanted) { + return false + } + if granted == wanted { + return true + } + if !strings.HasSuffix(granted, "/*") { + return false + } + base := strings.TrimSuffix(granted, "/*") + return wanted == base || strings.HasPrefix(wanted, base+"/") +} + +func validAbsolutePath(value string) bool { + if value == "" || value[0] != '/' || strings.ContainsAny(value, " :\\%\t\r\n") || !isASCII(value) { + return false + } + segments := strings.Split(value[1:], "/") + if len(segments) < 3 { + return false + } + for index, segment := range segments { + if segment == "*" { + if index != len(segments)-1 { + return false + } + continue + } + if !validSegment(segment) { + return false + } + } + return true +} + +func validSegment(value string) bool { + if value == "" || len(value) > 64 || value == "." || value == ".." { + return false + } + for index := 0; index < len(value); index++ { + character := value[index] + if character >= 'a' && character <= 'z' || character >= '0' && character <= '9' { + continue + } + if index > 0 && (character == '.' || character == '_' || character == '-') { + continue + } + return false + } + return true +} + +func validIdentifier(value string) bool { + _, err := uuid.Parse(value) + return err == nil +} + +func isASCII(value string) bool { + for index := 0; index < len(value); index++ { + if value[index] < 0x21 || value[index] > 0x7e { + return false + } + } + return true +} diff --git a/internal/authorization/permission_test.go b/internal/authorization/permission_test.go new file mode 100644 index 0000000..b8ee3d1 --- /dev/null +++ b/internal/authorization/permission_test.go @@ -0,0 +1,62 @@ +package authorization + +import "testing" + +func TestValidateRelativePermission(t *testing.T) { + valid := []string{"*", "invoices:read", "members:42:read", "members:42:*", "feature_name:read-only"} + for _, value := range valid { + if err := ValidateRelativePermission(value); err != nil { + t.Errorf("valid permission %q rejected: %v", value, err) + } + } + invalid := []string{"", "read write", "read\twrite", "read\nwrite", "read\u200bwrite", "read%20write", "read/write", `read\write`, ":read", "read:", "read::write", ".:read", "..:read", "read:*:write", "read*"} + for _, value := range invalid { + if err := ValidateRelativePermission(value); err == nil { + t.Errorf("invalid permission %q accepted", value) + } + } +} + +func FuzzValidateRelativePermission(f *testing.F) { + for _, seed := range []string{"invoices:read", "members:42:*", "read write", "read\u200bwrite", "../read"} { + f.Add(seed) + } + f.Fuzz(func(t *testing.T, value string) { + err := ValidateRelativePermission(value) + if err == nil { + applicationID := "01900000-0000-7000-8000-000000000001" + scope, canonicalErr := CanonicalScope(applicationID, nil, value) + if canonicalErr != nil || ValidateScopeClaim(scope, applicationID) != nil { + t.Fatalf("accepted permission did not produce a valid canonical scope: %q", value) + } + } + }) +} + +func TestCanonicalScopeAndMatch(t *testing.T) { + workspaceID := "01900000-0000-7000-8000-000000000002" + scope, err := CanonicalScope("01900000-0000-7000-8000-000000000001", &workspaceID, "members:42:*") + if err != nil { + t.Fatal(err) + } + expected := "/applications/01900000-0000-7000-8000-000000000001/workspaces/01900000-0000-7000-8000-000000000002/members/42/*" + if scope != expected || !Match(scope, expected[:len(expected)-1]+"read") { + t.Fatalf("unexpected canonical scope or match: %q", scope) + } + if Match(scope, "/applications/01900000-0000-7000-8000-000000000001/workspaces/other/members/42/read") { + t.Fatal("wildcard crossed a complete path boundary") + } +} + +func TestValidateScopeClaimRejectsWhitespaceInjection(t *testing.T) { + applicationID := "01900000-0000-7000-8000-000000000001" + valid := "/applications/" + applicationID + "/members/42/read" + if err := ValidateScopeClaim(valid, applicationID); err != nil { + t.Fatal(err) + } + for _, value := range []string{valid + " " + valid, valid + "\t" + valid, valid + "\n" + valid, "/applications/other/members/42/read"} { + if err := ValidateScopeClaim(value, applicationID); err == nil { + t.Errorf("invalid claim %q accepted", value) + } + } +} diff --git a/internal/database/database.go b/internal/database/database.go index 618423b..886b6e6 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -88,3 +88,27 @@ func Status(databaseURL string) error { } return nil } + +func ValidateAuthorization(databaseURL string) error { + pool, err := pgxpool.New(context.Background(), databaseURL) + if err != nil { + return err + } + defer pool.Close() + var invalidRoles int + if err = pool.QueryRow(context.Background(), `SELECT count(*) FROM roles +WHERE key !~ '^[a-z][a-z0-9_-]{0,62}$' OR NOT public.valid_permission_keys(permissions)`).Scan(&invalidRoles); err != nil { + return fmt.Errorf("validate role permissions: %w", err) + } + var invalidGrants int + if err = pool.QueryRow(context.Background(), `SELECT count(*) FROM permission_grants +WHERE NOT public.valid_permission_key(permission) OR split_part(permission,':',1)='roles' +OR canonical_scope <> '/applications/' || application_id::text || +CASE WHEN workspace_id IS NULL THEN '' ELSE '/workspaces/' || workspace_id::text END || '/' || replace(permission,':','/')`).Scan(&invalidGrants); err != nil { + return fmt.Errorf("validate direct permission grants: %w", err) + } + if invalidRoles != 0 || invalidGrants != 0 { + return fmt.Errorf("authorization data is invalid: roles=%d permission_grants=%d", invalidRoles, invalidGrants) + } + return nil +} diff --git a/internal/generated/openapi.gen.go b/internal/generated/openapi.gen.go index c3da901..ab6ae92 100644 --- a/internal/generated/openapi.gen.go +++ b/internal/generated/openapi.gen.go @@ -11,6 +11,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "net/http" "net/url" "path" @@ -25,9 +26,9 @@ import ( const ( BearerAuthScopes bearerAuthContextKey = "bearerAuth.Scopes" + ControlBearerScopes controlBearerContextKey = "controlBearer.Scopes" + ControlCookieScopes controlCookieContextKey = "controlCookie.Scopes" ManagementBearerScopes managementBearerContextKey = "managementBearer.Scopes" - OperatorBearerScopes operatorBearerContextKey = "operatorBearer.Scopes" - OperatorCookieScopes operatorCookieContextKey = "operatorCookie.Scopes" ) // Defines values for ApplicationInternalConfigRegistrationMode. @@ -48,6 +49,45 @@ func (e ApplicationInternalConfigRegistrationMode) Valid() bool { } } +// Defines values for BillingProviderProvider. +const ( + Stripe BillingProviderProvider = "stripe" +) + +// Valid indicates whether the value is a known member of the BillingProviderProvider enum. +func (e BillingProviderProvider) Valid() bool { + switch e { + case Stripe: + return true + default: + return false + } +} + +// Defines values for ControlUserAccountInstallationRole. +const ( + ControlUserAccountInstallationRoleAdmin ControlUserAccountInstallationRole = "admin" + ControlUserAccountInstallationRoleAuditor ControlUserAccountInstallationRole = "auditor" + ControlUserAccountInstallationRoleLessThannil ControlUserAccountInstallationRole = "" + ControlUserAccountInstallationRoleOwner ControlUserAccountInstallationRole = "owner" +) + +// Valid indicates whether the value is a known member of the ControlUserAccountInstallationRole enum. +func (e ControlUserAccountInstallationRole) Valid() bool { + switch e { + case ControlUserAccountInstallationRoleAdmin: + return true + case ControlUserAccountInstallationRoleAuditor: + return true + case ControlUserAccountInstallationRoleLessThannil: + return true + case ControlUserAccountInstallationRoleOwner: + return true + default: + return false + } +} + // Defines values for CreateFeatureFreeFormFormat. const ( Csv CreateFeatureFreeFormFormat = "csv" @@ -105,6 +145,84 @@ func (e CreateManagementClientAllowedScopes) Valid() bool { } } +// Defines values for CreatePermissionGrantSubjectType. +const ( + CreatePermissionGrantSubjectTypeClient CreatePermissionGrantSubjectType = "client" + CreatePermissionGrantSubjectTypeUser CreatePermissionGrantSubjectType = "user" +) + +// Valid indicates whether the value is a known member of the CreatePermissionGrantSubjectType enum. +func (e CreatePermissionGrantSubjectType) Valid() bool { + switch e { + case CreatePermissionGrantSubjectTypeClient: + return true + case CreatePermissionGrantSubjectTypeUser: + return true + default: + return false + } +} + +// Defines values for CreateRoleScope. +const ( + CreateRoleScopeApplication CreateRoleScope = "application" + CreateRoleScopeWorkspace CreateRoleScope = "workspace" +) + +// Valid indicates whether the value is a known member of the CreateRoleScope enum. +func (e CreateRoleScope) Valid() bool { + switch e { + case CreateRoleScopeApplication: + return true + case CreateRoleScopeWorkspace: + return true + default: + return false + } +} + +// Defines values for EffectiveAccessProvenanceSource. +const ( + EffectiveAccessProvenanceSourceDirect EffectiveAccessProvenanceSource = "direct" + EffectiveAccessProvenanceSourceRole EffectiveAccessProvenanceSource = "role" + EffectiveAccessProvenanceSourceRoleMarker EffectiveAccessProvenanceSource = "role_marker" + EffectiveAccessProvenanceSourceWorkspaceOwner EffectiveAccessProvenanceSource = "workspace_owner" +) + +// Valid indicates whether the value is a known member of the EffectiveAccessProvenanceSource enum. +func (e EffectiveAccessProvenanceSource) Valid() bool { + switch e { + case EffectiveAccessProvenanceSourceDirect: + return true + case EffectiveAccessProvenanceSourceRole: + return true + case EffectiveAccessProvenanceSourceRoleMarker: + return true + case EffectiveAccessProvenanceSourceWorkspaceOwner: + return true + default: + return false + } +} + +// Defines values for EffectiveAccessSubjectType. +const ( + EffectiveAccessSubjectTypeClient EffectiveAccessSubjectType = "client" + EffectiveAccessSubjectTypeUser EffectiveAccessSubjectType = "user" +) + +// Valid indicates whether the value is a known member of the EffectiveAccessSubjectType enum. +func (e EffectiveAccessSubjectType) Valid() bool { + switch e { + case EffectiveAccessSubjectTypeClient: + return true + case EffectiveAccessSubjectTypeUser: + return true + default: + return false + } +} + // Defines values for EventEnvelopeContractSource. const ( EventEnvelopeContractSourceApplication EventEnvelopeContractSource = "application" @@ -158,16 +276,103 @@ func (e EventTypeDefinitionSource) Valid() bool { // Defines values for EventTypeDefinitionStatus. const ( - Active EventTypeDefinitionStatus = "active" - Archived EventTypeDefinitionStatus = "archived" + EventTypeDefinitionStatusActive EventTypeDefinitionStatus = "active" + EventTypeDefinitionStatusArchived EventTypeDefinitionStatus = "archived" ) // Valid indicates whether the value is a known member of the EventTypeDefinitionStatus enum. func (e EventTypeDefinitionStatus) Valid() bool { switch e { - case Active: + case EventTypeDefinitionStatusActive: + return true + case EventTypeDefinitionStatusArchived: + return true + default: + return false + } +} + +// Defines values for FeatureFreeFormFormat. +const ( + FeatureFreeFormFormatCsv FeatureFreeFormFormat = "csv" + FeatureFreeFormFormatJson FeatureFreeFormFormat = "json" + FeatureFreeFormFormatLessThannil FeatureFreeFormFormat = "" + FeatureFreeFormFormatText FeatureFreeFormFormat = "text" +) + +// Valid indicates whether the value is a known member of the FeatureFreeFormFormat enum. +func (e FeatureFreeFormFormat) Valid() bool { + switch e { + case FeatureFreeFormFormatCsv: + return true + case FeatureFreeFormFormatJson: + return true + case FeatureFreeFormFormatLessThannil: + return true + case FeatureFreeFormFormatText: + return true + default: + return false + } +} + +// Defines values for HealthStatusStatus. +const ( + Ok HealthStatusStatus = "ok" + Ready HealthStatusStatus = "ready" +) + +// Valid indicates whether the value is a known member of the HealthStatusStatus enum. +func (e HealthStatusStatus) Valid() bool { + switch e { + case Ok: + return true + case Ready: + return true + default: + return false + } +} + +// Defines values for LocalEntitlementApprovalStatus. +const ( + Approved LocalEntitlementApprovalStatus = "approved" +) + +// Valid indicates whether the value is a known member of the LocalEntitlementApprovalStatus enum. +func (e LocalEntitlementApprovalStatus) Valid() bool { + switch e { + case Approved: + return true + default: + return false + } +} + +// Defines values for NotificationProviderProvider. +const ( + Smtp NotificationProviderProvider = "smtp" +) + +// Valid indicates whether the value is a known member of the NotificationProviderProvider enum. +func (e NotificationProviderProvider) Valid() bool { + switch e { + case Smtp: return true - case Archived: + default: + return false + } +} + +// Defines values for NotificationQueuedStatus. +const ( + Queued NotificationQueuedStatus = "queued" +) + +// Valid indicates whether the value is a known member of the NotificationQueuedStatus enum. +func (e NotificationQueuedStatus) Valid() bool { + switch e { + case Queued: return true default: return false @@ -198,6 +403,75 @@ func (e OrganizationPageInstallationRole) Valid() bool { } } +// Defines values for PermissionGrantStatus. +const ( + PermissionGrantStatusActive PermissionGrantStatus = "active" + PermissionGrantStatusRevoked PermissionGrantStatus = "revoked" +) + +// Valid indicates whether the value is a known member of the PermissionGrantStatus enum. +func (e PermissionGrantStatus) Valid() bool { + switch e { + case PermissionGrantStatusActive: + return true + case PermissionGrantStatusRevoked: + return true + default: + return false + } +} + +// Defines values for PermissionGrantSubjectType. +const ( + PermissionGrantSubjectTypeClient PermissionGrantSubjectType = "client" + PermissionGrantSubjectTypeUser PermissionGrantSubjectType = "user" +) + +// Valid indicates whether the value is a known member of the PermissionGrantSubjectType enum. +func (e PermissionGrantSubjectType) Valid() bool { + switch e { + case PermissionGrantSubjectTypeClient: + return true + case PermissionGrantSubjectTypeUser: + return true + default: + return false + } +} + +// Defines values for ReconciliationAcceptedStatus. +const ( + ReconciliationAcceptedStatusPending ReconciliationAcceptedStatus = "pending" +) + +// Valid indicates whether the value is a known member of the ReconciliationAcceptedStatus enum. +func (e ReconciliationAcceptedStatus) Valid() bool { + switch e { + case ReconciliationAcceptedStatusPending: + return true + default: + return false + } +} + +// Defines values for RoleScope. +const ( + RoleScopeApplication RoleScope = "application" + RoleScopeWorkspace RoleScope = "workspace" +) + +// Valid indicates whether the value is a known member of the RoleScope enum. +func (e RoleScope) Valid() bool { + switch e { + case RoleScopeApplication: + return true + case RoleScopeWorkspace: + return true + default: + return false + } +} + // Defines values for RuntimeAuthConfigRegistrationMode. const ( RuntimeAuthConfigRegistrationModeInviteOnly RuntimeAuthConfigRegistrationMode = "invite_only" @@ -216,6 +490,66 @@ func (e RuntimeAuthConfigRegistrationMode) Valid() bool { } } +// Defines values for SetupCompletionCompleted. +const ( + True SetupCompletionCompleted = true +) + +// Valid indicates whether the value is a known member of the SetupCompletionCompleted enum. +func (e SetupCompletionCompleted) Valid() bool { + switch e { + case True: + return true + default: + return false + } +} + +// Defines values for SigningKeyAlgorithm. +const ( + RS256 SigningKeyAlgorithm = "RS256" +) + +// Valid indicates whether the value is a known member of the SigningKeyAlgorithm enum. +func (e SigningKeyAlgorithm) Valid() bool { + switch e { + case RS256: + return true + default: + return false + } +} + +// Defines values for StorageProviderProvider. +const ( + S3 StorageProviderProvider = "s3" +) + +// Valid indicates whether the value is a known member of the StorageProviderProvider enum. +func (e StorageProviderProvider) Valid() bool { + switch e { + case S3: + return true + default: + return false + } +} + +// Defines values for WebhookTestAcceptedStatus. +const ( + WebhookTestAcceptedStatusPending WebhookTestAcceptedStatus = "pending" +) + +// Valid indicates whether the value is a known member of the WebhookTestAcceptedStatus enum. +func (e WebhookTestAcceptedStatus) Valid() bool { + switch e { + case WebhookTestAcceptedStatusPending: + return true + default: + return false + } +} + // Defines values for OAuthCodeChallengeMethod. const ( OAuthCodeChallengeMethodS256 OAuthCodeChallengeMethod = "S256" @@ -246,6 +580,42 @@ func (e OAuthResponseType) Valid() bool { } } +// Defines values for OptionalPermissionSubjectType. +const ( + OptionalPermissionSubjectTypeClient OptionalPermissionSubjectType = "client" + OptionalPermissionSubjectTypeUser OptionalPermissionSubjectType = "user" +) + +// Valid indicates whether the value is a known member of the OptionalPermissionSubjectType enum. +func (e OptionalPermissionSubjectType) Valid() bool { + switch e { + case OptionalPermissionSubjectTypeClient: + return true + case OptionalPermissionSubjectTypeUser: + return true + default: + return false + } +} + +// Defines values for PermissionSubjectType. +const ( + PermissionSubjectTypeClient PermissionSubjectType = "client" + PermissionSubjectTypeUser PermissionSubjectType = "user" +) + +// Valid indicates whether the value is a known member of the PermissionSubjectType enum. +func (e PermissionSubjectType) Valid() bool { + switch e { + case PermissionSubjectTypeClient: + return true + case PermissionSubjectTypeUser: + return true + default: + return false + } +} + // Defines values for BeginOIDCAuthorizationParamsResponseType. const ( BeginOIDCAuthorizationParamsResponseTypeCode BeginOIDCAuthorizationParamsResponseType = "code" @@ -306,36 +676,343 @@ func (e DecideOIDCAuthorizationFormdataBodyResponseType) Valid() bool { } } -// AcceptOrganizationInvitation defines model for AcceptOrganizationInvitation. -type AcceptOrganizationInvitation struct { +// AcceptControlUserInvitation defines model for AcceptControlUserInvitation. +type AcceptControlUserInvitation struct { DisplayName *string `json:"display_name,omitempty"` InvitationToken *string `json:"invitation_token,omitempty"` } +// AccountChallenge defines model for AccountChallenge. +type AccountChallenge struct { + ChallengeId UUID `json:"challenge_id"` + Code *string `json:"code,omitempty"` + LinkToken *string `json:"link_token,omitempty"` +} + +// AccountExport defines model for AccountExport. +type AccountExport struct { + Addresses []Address `json:"addresses"` + ExportedAt time.Time `json:"exported_at"` + User User `json:"user"` +} + +// ActivateTOTP defines model for ActivateTOTP. +type ActivateTOTP struct { + Code *string `json:"code,omitempty"` +} + +// Address defines model for Address. +type Address struct { + Active bool `json:"active"` + City string `json:"city"` + Country string `json:"country"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + Line1 string `json:"line1"` + Line2 *string `json:"line2,omitempty"` + Name *string `json:"name,omitempty"` + PostalCode string `json:"postal_code"` + Region *string `json:"region,omitempty"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Version int64 `json:"version"` +} + +// AddressPage defines model for AddressPage. +type AddressPage struct { + Items []Address `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// AdjustEntitlement defines model for AdjustEntitlement. +type AdjustEntitlement struct { + ExpiresAt *time.Time `json:"expires_at,omitempty"` + Reason *string `json:"reason,omitempty"` +} + +// Application defines model for Application. +type Application struct { + Audience *string `json:"audience,omitempty"` + AuthConfig *map[string]interface{} `json:"auth_config,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + InternalConfig *map[string]interface{} `json:"internal_config,omitempty"` + Issuer *string `json:"issuer,omitempty"` + Name string `json:"name"` + OrganizationId UUID `json:"organization_id"` + PublicConfig *map[string]interface{} `json:"public_config,omitempty"` + RetiredAt *time.Time `json:"retired_at,omitempty"` + Slug string `json:"slug"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Version int64 `json:"version"` +} + // ApplicationAuthConfig defines model for ApplicationAuthConfig. type ApplicationAuthConfig struct { Flows *ApplicationFlowConfig `json:"flows,omitempty"` } +// ApplicationDomain defines model for ApplicationDomain. +type ApplicationDomain struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Hostname string `json:"hostname"` + Id UUID `json:"id"` + Status interface{} `json:"status"` +} + +// ApplicationDomainPage defines model for ApplicationDomainPage. +type ApplicationDomainPage struct { + Items []ApplicationDomain `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // ApplicationFlowConfig defines model for ApplicationFlowConfig. type ApplicationFlowConfig struct { + // InvitationRedirectUri Invitation destination using the same origin or native scheme authority as the sign-in redirect. InvitationRedirectUri string `json:"invitation_redirect_uri"` OauthClientId string `json:"oauth_client_id"` - SignInRedirectUri string `json:"sign_in_redirect_uri"` + + // SignInRedirectUri Exact registered HTTPS, loopback HTTP, or public-client native application redirect URI. + SignInRedirectUri string `json:"sign_in_redirect_uri"` } // ApplicationInternalConfig defines model for ApplicationInternalConfig. type ApplicationInternalConfig struct { + CustomTokenClaimKeys *[]string `json:"custom_token_claim_keys,omitempty"` DelegationEnabled *bool `json:"delegation_enabled,omitempty"` PasswordEnabled *bool `json:"password_enabled,omitempty"` PasswordlessEnabled *bool `json:"passwordless_enabled,omitempty"` PersonalApiKeysEnabled *bool `json:"personal_api_keys_enabled,omitempty"` RegistrationMode *ApplicationInternalConfigRegistrationMode `json:"registration_mode,omitempty"` + UserInvitationsEnabled *bool `json:"user_invitations_enabled,omitempty"` } // ApplicationInternalConfigRegistrationMode defines model for ApplicationInternalConfig.RegistrationMode. type ApplicationInternalConfigRegistrationMode string +// ApplicationInvitation defines model for ApplicationInvitation. +type ApplicationInvitation struct { + AcceptedUserId *openapi_types.UUID `json:"accepted_user_id,omitempty"` + ApplicationId UUID `json:"application_id"` + ApplicationRoleKeys *[]RoleKey `json:"application_role_keys,omitempty"` + Code *string `json:"code,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Email openapi_types.Email `json:"email"` + ExpiresAt time.Time `json:"expires_at"` + Id UUID `json:"id"` + Link *string `json:"link,omitempty"` + LinkToken *string `json:"link_token,omitempty"` + Status interface{} `json:"status"` + WorkspaceId *openapi_types.UUID `json:"workspace_id,omitempty"` + WorkspaceRoleKeys *[]RoleKey `json:"workspace_role_keys,omitempty"` +} + +// ApplicationInvitationPage defines model for ApplicationInvitationPage. +type ApplicationInvitationPage struct { + Items []ApplicationInvitation `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// ApplicationPage defines model for ApplicationPage. +type ApplicationPage struct { + Items []Application `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// ApplicationStatistics defines model for ApplicationStatistics. +type ApplicationStatistics struct { + ActiveEntitlements int `json:"active_entitlements"` + ActiveProducts int `json:"active_products"` + EventsLast24Hours int `json:"events_last_24_hours"` + LiveSubscriptions int `json:"live_subscriptions"` + NotificationFailures int `json:"notification_failures"` + PendingLocalRequests int `json:"pending_local_requests"` + Users struct { + Active int `json:"active"` + Suspended int `json:"suspended"` + Total int `json:"total"` + } `json:"users"` + WebhookFailures int `json:"webhook_failures"` + Workspaces int `json:"workspaces"` +} + +// AuditExport defines model for AuditExport. +type AuditExport struct { + Action *string `json:"action,omitempty"` + ActorType interface{} `json:"actor_type,omitempty"` + End *time.Time `json:"end,omitempty"` + Start *time.Time `json:"start,omitempty"` + TargetType *string `json:"target_type,omitempty"` +} + +// AuditExportRecord defines model for AuditExportRecord. +type AuditExportRecord struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + DownloadUri *string `json:"download_uri,omitempty"` + ExpiresAt time.Time `json:"expires_at"` + Filters *map[string]interface{} `json:"filters,omitempty"` + Id UUID `json:"id"` + RecordCount int `json:"record_count"` + Status interface{} `json:"status,omitempty"` +} + +// AuditReason defines model for AuditReason. +type AuditReason struct { + Reason string `json:"reason"` +} + +// AuditRecord defines model for AuditRecord. +type AuditRecord struct { + Action string `json:"action"` + ActorId *openapi_types.UUID `json:"actor_id,omitempty"` + ActorType interface{} `json:"actor_type"` + ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` + Changes *map[string]interface{} `json:"changes,omitempty"` + CreatedAt time.Time `json:"created_at"` + Id UUID `json:"id"` + OrganizationId *openapi_types.UUID `json:"organization_id,omitempty"` + Reason *string `json:"reason,omitempty"` + RequestId *string `json:"request_id,omitempty"` + TargetId *string `json:"target_id,omitempty"` + TargetType string `json:"target_type"` +} + +// AuditRecordPage defines model for AuditRecordPage. +type AuditRecordPage struct { + Items []AuditRecord `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// AuthMethods defines model for AuthMethods. +type AuthMethods struct { + Methods []interface{} `json:"methods"` + RegistrationEnabled bool `json:"registration_enabled"` + RegistrationMode interface{} `json:"registration_mode"` +} + +// AuthProvider defines model for AuthProvider. +type AuthProvider struct { + ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` + CallbackUri *string `json:"callback_uri,omitempty"` + ClientId string `json:"client_id"` + Configured *bool `json:"configured,omitempty"` + ControlLoginEnabled bool `json:"control_login_enabled"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + Inheritable bool `json:"inheritable"` + Inherited *bool `json:"inherited,omitempty"` + InheritingApplications *int `json:"inheriting_applications,omitempty"` + KeyId *string `json:"key_id,omitempty"` + LinkedControlUsers *int `json:"linked_control_users,omitempty"` + OrganizationId *openapi_types.UUID `json:"organization_id,omitempty"` + Provider interface{} `json:"provider"` + Scope interface{} `json:"scope"` + TeamId *string `json:"team_id,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// AuthProviderPage defines model for AuthProviderPage. +type AuthProviderPage struct { + Items []AuthProvider `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// AuthorizationRedirect defines model for AuthorizationRedirect. +type AuthorizationRedirect struct { + RedirectTo string `json:"redirect_to"` +} + +// BeginWebAuthnAuthentication defines model for BeginWebAuthnAuthentication. +type BeginWebAuthnAuthentication struct { + ChallengeId UUID `json:"challenge_id"` + Origin *string `json:"origin,omitempty"` +} + +// BeginWebAuthnRegistration defines model for BeginWebAuthnRegistration. +type BeginWebAuthnRegistration struct { + Label *string `json:"label,omitempty"` + Origin *string `json:"origin,omitempty"` +} + +// BillingProfile defines model for BillingProfile. +type BillingProfile struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + DefaultAddressId *openapi_types.UUID `json:"default_address_id,omitempty"` + Email *openapi_types.Email `json:"email,omitempty"` + Id UUID `json:"id"` + Name *string `json:"name,omitempty"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` + TaxId *string `json:"tax_id,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Version int64 `json:"version"` +} + +// BillingProvider defines model for BillingProvider. +type BillingProvider struct { + ApiVersion string `json:"api_version"` + ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Effective *bool `json:"effective,omitempty"` + Id UUID `json:"id"` + Inheritable bool `json:"inheritable"` + Inherited *bool `json:"inherited,omitempty"` + Metadata *map[string]interface{} `json:"metadata,omitempty"` + OrganizationId *openapi_types.UUID `json:"organization_id,omitempty"` + Provider BillingProviderProvider `json:"provider"` + PublicId string `json:"public_id"` + Scope interface{} `json:"scope"` + Status interface{} `json:"status"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + WebhookConfigured *bool `json:"webhook_configured,omitempty"` + WebhookUri string `json:"webhook_uri"` +} + +// BillingProviderProvider defines model for BillingProvider.Provider. +type BillingProviderProvider string + +// BillingProviderEvent defines model for BillingProviderEvent. +type BillingProviderEvent struct { + Attempts *int `json:"attempts,omitempty"` + EventType string `json:"event_type"` + Id UUID `json:"id"` + LastError *string `json:"last_error,omitempty"` + ProcessedAt *time.Time `json:"processed_at,omitempty"` + ProviderEventId string `json:"provider_event_id"` + ReceivedAt time.Time `json:"received_at"` + Status interface{} `json:"status"` +} + +// BillingProviderEventPage defines model for BillingProviderEventPage. +type BillingProviderEventPage struct { + Items []BillingProviderEvent `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// BillingProviderPage defines model for BillingProviderPage. +type BillingProviderPage struct { + Items []BillingProvider `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// BillingStatistics defines model for BillingStatistics. +type BillingStatistics struct { + From time.Time `json:"from"` + RefundsMinorByCurrency []CurrencyTotal `json:"refunds_minor_by_currency"` + RevenueMinorByCurrency []CurrencyTotal `json:"revenue_minor_by_currency"` + StatusCounts map[string]map[string]int `json:"status_counts"` + To time.Time `json:"to"` +} + +// BillingSummary defines model for BillingSummary. +type BillingSummary struct { + BillingProfile *BillingProfile `json:"billing_profile"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` + Subscriptions []Subscription `json:"subscriptions"` +} + // BootstrapRequest defines model for BootstrapRequest. type BootstrapRequest struct { Credential *string `json:"credential,omitempty"` @@ -343,6 +1020,182 @@ type BootstrapRequest struct { Email openapi_types.Email `json:"email"` } +// CancelSubscription defines model for CancelSubscription. +type CancelSubscription struct { + AtPeriodEnd *bool `json:"at_period_end,omitempty"` +} + +// ChallengeAccepted defines model for ChallengeAccepted. +type ChallengeAccepted struct { + ChallengeId UUID `json:"challenge_id"` + ExpiresIn int `json:"expires_in"` +} + +// ChangeSubscriptionPrice defines model for ChangeSubscriptionPrice. +type ChangeSubscriptionPrice struct { + PriceId UUID `json:"price_id"` + ProrationBehavior interface{} `json:"proration_behavior,omitempty"` +} + +// CheckoutSession defines model for CheckoutSession. +type CheckoutSession struct { + CheckoutUri *string `json:"checkout_uri,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + Id UUID `json:"id"` + ProviderSessionId *string `json:"provider_session_id,omitempty"` + Status interface{} `json:"status"` + SubjectId *UUID `json:"subject_id,omitempty"` + SubjectType interface{} `json:"subject_type,omitempty"` +} + +// CompleteSetup defines model for CompleteSetup. +type CompleteSetup struct { + Password *string `json:"password,omitempty"` +} + +// ConfigureAuthProvider defines model for ConfigureAuthProvider. +type ConfigureAuthProvider struct { + ClientId string `json:"client_id"` + ClientSecret *string `json:"client_secret,omitempty"` + ControlLoginEnabled *bool `json:"control_login_enabled,omitempty"` + Inheritable *bool `json:"inheritable,omitempty"` + KeyId *string `json:"key_id,omitempty"` + PrivateKeyPem *string `json:"private_key_pem,omitempty"` + TeamId *string `json:"team_id,omitempty"` +} + +// ControlAuthMethods defines model for ControlAuthMethods. +type ControlAuthMethods struct { + EmailCode bool `json:"email_code"` + MagicLink bool `json:"magic_link"` + Password bool `json:"password"` + Providers []interface{} `json:"providers"` +} + +// ControlAuthPolicy defines model for ControlAuthPolicy. +type ControlAuthPolicy struct { + EmailCodeEnabled bool `json:"email_code_enabled"` + MagicLinkEnabled bool `json:"magic_link_enabled"` + PasswordEnabled bool `json:"password_enabled"` +} + +// ControlEmailStart defines model for ControlEmailStart. +type ControlEmailStart struct { + Delivery interface{} `json:"delivery,omitempty"` + Email openapi_types.Email `json:"email"` +} + +// ControlInvitationProviderStart defines model for ControlInvitationProviderStart. +type ControlInvitationProviderStart struct { + InvitationToken *string `json:"invitation_token,omitempty"` +} + +// ControlUser defines model for ControlUser. +type ControlUser struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + DisplayName string `json:"display_name"` + Email openapi_types.Email `json:"email"` + Id UUID `json:"id"` + Role interface{} `json:"role"` + Status interface{} `json:"status"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// ControlUserAccount defines model for ControlUserAccount. +type ControlUserAccount struct { + CreatedAt time.Time `json:"created_at"` + DisplayName string `json:"display_name"` + Email openapi_types.Email `json:"email"` + Id UUID `json:"id"` + InstallationRole *ControlUserAccountInstallationRole `json:"installation_role"` + Organizations []struct { + Id UUID `json:"id"` + Name string `json:"name"` + Role interface{} `json:"role"` + } `json:"organizations"` + SignInMethods struct { + EmailCode bool `json:"email_code"` + ExternalIdentities []struct { + Available bool `json:"available"` + CreatedAt time.Time `json:"created_at"` + Id UUID `json:"id"` + LastUsedAt *time.Time `json:"last_used_at,omitempty"` + Metadata map[string]interface{} `json:"metadata"` + Provider interface{} `json:"provider"` + } `json:"external_identities"` + MagicLink bool `json:"magic_link"` + Password bool `json:"password"` + } `json:"sign_in_methods"` + Status interface{} `json:"status"` + UpdatedAt time.Time `json:"updated_at"` +} + +// ControlUserAccountInstallationRole defines model for ControlUserAccount.InstallationRole. +type ControlUserAccountInstallationRole string + +// ControlUserInvitation defines model for ControlUserInvitation. +type ControlUserInvitation struct { + AcceptedAt *time.Time `json:"accepted_at,omitempty"` + AcceptedBy *openapi_types.UUID `json:"accepted_by,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Email openapi_types.Email `json:"email"` + ExpiresAt time.Time `json:"expires_at"` + Id UUID `json:"id"` + InvitationToken *string `json:"invitation_token,omitempty"` + InvitedBy *openapi_types.UUID `json:"invited_by,omitempty"` + OnboardingMethod interface{} `json:"onboarding_method"` + OrganizationId *openapi_types.UUID `json:"organization_id,omitempty"` + RevokedAt *time.Time `json:"revoked_at,omitempty"` + Role interface{} `json:"role"` + Status interface{} `json:"status,omitempty"` + TokenReturnedOnce *bool `json:"token_returned_once,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// ControlUserInvitationPage defines model for ControlUserInvitationPage. +type ControlUserInvitationPage struct { + Items []ControlUserInvitation `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// ControlUserPage defines model for ControlUserPage. +type ControlUserPage struct { + Items []ControlUser `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// ControlUserPasswordChange defines model for ControlUserPasswordChange. +type ControlUserPasswordChange struct { + CurrentPassword *string `json:"current_password,omitempty"` + NewPassword *string `json:"new_password,omitempty"` +} + +// ControlUserPasswordLogin defines model for ControlUserPasswordLogin. +type ControlUserPasswordLogin struct { + Email openapi_types.Email `json:"email"` + Password *string `json:"password,omitempty"` +} + +// CreateAddress defines model for CreateAddress. +type CreateAddress struct { + Active *bool `json:"active,omitempty"` + City string `json:"city"` + CountryCode string `json:"country_code"` + Line1 string `json:"line1"` + Line2 *string `json:"line2,omitempty"` + Name string `json:"name"` + PostalCode string `json:"postal_code"` + Region *string `json:"region,omitempty"` + TaxId *string `json:"tax_id,omitempty"` +} + +// CreateApplicationDomain defines model for CreateApplicationDomain. +type CreateApplicationDomain struct { + Hostname string `json:"hostname"` +} + // CreateBillingProvider defines model for CreateBillingProvider. type CreateBillingProvider struct { ApiVersion interface{} `json:"api_version,omitempty"` @@ -354,13 +1207,56 @@ type CreateBillingProvider struct { // CreateCheckout defines model for CreateCheckout. type CreateCheckout struct { - CancelUri string `json:"cancel_uri"` - PaymentMethods *[]interface{} `json:"payment_methods,omitempty"` - PriceId UUID `json:"price_id"` - ProviderId *UUID `json:"provider_id,omitempty"` - SubjectId *UUID `json:"subject_id,omitempty"` - SubjectType interface{} `json:"subject_type,omitempty"` - SuccessUri string `json:"success_uri"` + CancelUri string `json:"cancel_uri"` + ExternalReference *string `json:"external_reference,omitempty"` + PaymentMethods *[]interface{} `json:"payment_methods,omitempty"` + PriceId UUID `json:"price_id"` + ProviderId *UUID `json:"provider_id,omitempty"` + SubjectId *UUID `json:"subject_id,omitempty"` + SubjectType interface{} `json:"subject_type,omitempty"` + SuccessUri string `json:"success_uri"` +} + +// CreateClient defines model for CreateClient. +type CreateClient struct { + AllowedGrants *[]interface{} `json:"allowed_grants,omitempty"` + AllowedScopes *[]string `json:"allowed_scopes,omitempty"` + ClientId string `json:"client_id"` + ClientType interface{} `json:"client_type"` + Name string `json:"name"` + RedirectUris *[]string `json:"redirect_uris,omitempty"` +} + +// CreateControlUserInvitation defines model for CreateControlUserInvitation. +type CreateControlUserInvitation struct { + Email openapi_types.Email `json:"email"` + ExpiresIn *int `json:"expires_in,omitempty"` + OnboardingMethod interface{} `json:"onboarding_method,omitempty"` + Role interface{} `json:"role"` +} + +// CreateDelegation defines model for CreateDelegation. +type CreateDelegation struct { + ExpiresIn *int64 `json:"expires_in,omitempty"` + Permissions []PermissionKey `json:"permissions"` + Reason string `json:"reason"` + RedirectUri string `json:"redirect_uri"` + UserId UUID `json:"user_id"` + WorkspaceId *UUID `json:"workspace_id,omitempty"` +} + +// CreateEntitlement defines model for CreateEntitlement. +type CreateEntitlement struct { + Configuration *map[string]interface{} `json:"configuration,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + FeatureValues *map[string]interface{} `json:"feature_values,omitempty"` + PriceId *UUID `json:"price_id,omitempty"` + ProductId *UUID `json:"product_id,omitempty"` + Reason *string `json:"reason,omitempty"` + StartsAt *time.Time `json:"starts_at,omitempty"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` } // CreateEventType defines model for CreateEventType. @@ -392,6 +1288,15 @@ type CreateFeatureFreeFormFormat string // CreateFeatureValueType defines model for CreateFeature.ValueType. type CreateFeatureValueType string +// CreateInvitation defines model for CreateInvitation. +type CreateInvitation struct { + ApplicationRoleKeys *[]string `json:"application_role_keys,omitempty"` + Email openapi_types.Email `json:"email"` + ExpiresIn *int64 `json:"expires_in,omitempty"` + WorkspaceId *UUID `json:"workspace_id,omitempty"` + WorkspaceRoleKeys *[]string `json:"workspace_role_keys,omitempty"` +} + // CreateManagementClient defines model for CreateManagementClient. type CreateManagementClient struct { AllowedScopes *[]CreateManagementClientAllowedScopes `json:"allowed_scopes,omitempty"` @@ -402,6 +1307,31 @@ type CreateManagementClient struct { // CreateManagementClientAllowedScopes defines model for CreateManagementClient.AllowedScopes. type CreateManagementClientAllowedScopes string +// CreateNotificationTemplate defines model for CreateNotificationTemplate. +type CreateNotificationTemplate struct { + Category interface{} `json:"category"` + HtmlTemplate *string `json:"html_template,omitempty"` + Key string `json:"key"` + + // Locale Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Locale *Locale `json:"locale,omitempty"` + SubjectTemplate string `json:"subject_template"` + TextTemplate string `json:"text_template"` + VariableSchema *map[string]interface{} `json:"variable_schema,omitempty"` +} + +// CreatePermissionGrant defines model for CreatePermissionGrant. +type CreatePermissionGrant struct { + Permission PermissionKey `json:"permission"` + Reason *string `json:"reason,omitempty"` + SubjectId UUID `json:"subject_id"` + SubjectType CreatePermissionGrantSubjectType `json:"subject_type"` + WorkspaceId *UUID `json:"workspace_id,omitempty"` +} + +// CreatePermissionGrantSubjectType defines model for CreatePermissionGrant.SubjectType. +type CreatePermissionGrantSubjectType string + // CreatePersonalAPIKey defines model for CreatePersonalAPIKey. type CreatePersonalAPIKey struct { ExpiresInDays *int `json:"expires_in_days,omitempty"` @@ -409,6 +1339,14 @@ type CreatePersonalAPIKey struct { Scopes *[]string `json:"scopes,omitempty"` } +// CreatePortalSession defines model for CreatePortalSession. +type CreatePortalSession struct { + ProviderId UUID `json:"provider_id"` + ReturnUri string `json:"return_uri"` + SubjectId *UUID `json:"subject_id,omitempty"` + SubjectType interface{} `json:"subject_type,omitempty"` +} + // CreatePrice defines model for CreatePrice. type CreatePrice struct { AmountMinor int `json:"amount_minor"` @@ -438,6 +1376,31 @@ type CreateProduct struct { Status interface{} `json:"status,omitempty"` } +// CreateRefund defines model for CreateRefund. +type CreateRefund struct { + AmountMinor *int64 `json:"amount_minor,omitempty"` + Reason *string `json:"reason,omitempty"` +} + +// CreateRole defines model for CreateRole. +type CreateRole struct { + Key RoleKey `json:"key"` + Name string `json:"name"` + Permissions []PermissionKey `json:"permissions"` + Scope CreateRoleScope `json:"scope"` +} + +// CreateRoleScope defines model for CreateRole.Scope. +type CreateRoleScope string + +// CreateSenderIdentity defines model for CreateSenderIdentity. +type CreateSenderIdentity struct { + Email openapi_types.Email `json:"email"` + IsDefault *bool `json:"is_default,omitempty"` + Name *string `json:"name,omitempty"` + ProviderId UUID `json:"provider_id"` +} + // CreateStorageProvider defines model for CreateStorageProvider. type CreateStorageProvider struct { AccessKeyId *string `json:"access_key_id,omitempty"` @@ -476,6 +1439,113 @@ type CreateStorageUpload struct { Visibility interface{} `json:"visibility"` } +// CreateUser defines model for CreateUser. +type CreateUser struct { + CustomAttributes *map[string]interface{} `json:"custom_attributes,omitempty"` + Email openapi_types.Email `json:"email"` + EmailVerified *bool `json:"email_verified,omitempty"` + FirstName *string `json:"first_name,omitempty"` + IsOrgVerified *bool `json:"is_org_verified,omitempty"` + LastName *string `json:"last_name,omitempty"` + + // Locale Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Locale *Locale `json:"locale,omitempty"` + Password *string `json:"password,omitempty"` + Username *string `json:"username,omitempty"` +} + +// CreateWebhook defines model for CreateWebhook. +type CreateWebhook struct { + EventFilters *[]string `json:"event_filters,omitempty"` + Uri string `json:"uri"` +} + +// CreateWorkspace defines model for CreateWorkspace. +type CreateWorkspace struct { + Key string `json:"key"` + Metadata *map[string]interface{} `json:"metadata,omitempty"` + Name string `json:"name"` + OwnerUserId *UUID `json:"owner_user_id,omitempty"` +} + +// CurrencyTotal defines model for CurrencyTotal. +type CurrencyTotal struct { + AmountMinor int64 `json:"amount_minor"` + Currency string `json:"currency"` +} + +// Delegation defines model for Delegation. +type Delegation struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + ExchangeCode *string `json:"exchange_code,omitempty"` + ExpiresAt time.Time `json:"expires_at"` + Id UUID `json:"id"` + Reason string `json:"reason"` + Scopes []string `json:"scopes"` + Status interface{} `json:"status"` + UserId UUID `json:"user_id"` + WorkspaceId *openapi_types.UUID `json:"workspace_id,omitempty"` +} + +// DelegationPage defines model for DelegationPage. +type DelegationPage struct { + Items []Delegation `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// Dispute defines model for Dispute. +type Dispute struct { + AmountMinor int64 `json:"amount_minor"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Currency string `json:"currency"` + Id UUID `json:"id"` + PaymentId *openapi_types.UUID `json:"payment_id,omitempty"` + ProviderDisputeId *string `json:"provider_dispute_id,omitempty"` + Reason *string `json:"reason,omitempty"` + Status string `json:"status"` +} + +// DisputePage defines model for DisputePage. +type DisputePage struct { + Items []Dispute `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// EffectiveAccess defines model for EffectiveAccess. +type EffectiveAccess struct { + Provenance []struct { + GrantId *UUID `json:"grant_id,omitempty"` + Permission *PermissionKey `json:"permission,omitempty"` + RoleKey *RoleKey `json:"role_key,omitempty"` + Scope string `json:"scope"` + Source EffectiveAccessProvenanceSource `json:"source"` + WorkspaceId *UUID `json:"workspace_id,omitempty"` + } `json:"provenance"` + Roles StructuredRoles `json:"roles"` + Scopes []string `json:"scopes"` + SubjectId UUID `json:"subject_id"` + SubjectType EffectiveAccessSubjectType `json:"subject_type"` +} + +// EffectiveAccessProvenanceSource defines model for EffectiveAccess.Provenance.Source. +type EffectiveAccessProvenanceSource string + +// EffectiveAccessSubjectType defines model for EffectiveAccess.SubjectType. +type EffectiveAccessSubjectType string + +// EffectiveEntitlements defines model for EffectiveEntitlements. +type EffectiveEntitlements struct { + Effective map[string]FeatureValue `json:"effective"` + Provenance map[string][]UUID `json:"provenance"` + Sources []EntitlementGrant `json:"sources"` + WorkspaceId *openapi_types.UUID `json:"workspace_id"` +} + +// EmailAddress defines model for EmailAddress. +type EmailAddress struct { + Email openapi_types.Email `json:"email"` +} + // EmailStart defines model for EmailStart. type EmailStart struct { Delivery interface{} `json:"delivery"` @@ -491,6 +1561,31 @@ type EmailVerify struct { LinkToken *string `json:"link_token,omitempty"` } +// EmptyResponse defines model for EmptyResponse. +type EmptyResponse = map[string]interface{} + +// EntitlementGrant defines model for EntitlementGrant. +type EntitlementGrant struct { + Configuration map[string]interface{} `json:"configuration"` + CreatedAt *time.Time `json:"created_at,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + FeatureValues map[string]FeatureValue `json:"feature_values"` + Id UUID `json:"id"` + RevokedAt *time.Time `json:"revoked_at,omitempty"` + SourceId *openapi_types.UUID `json:"source_id,omitempty"` + SourceType interface{} `json:"source_type"` + StartsAt time.Time `json:"starts_at"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` +} + +// EntitlementGrantPage defines model for EntitlementGrantPage. +type EntitlementGrantPage struct { + Items []EntitlementGrant `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // EventEnvelope defines model for EventEnvelope. type EventEnvelope struct { Actor *map[string]interface{} `json:"actor,omitempty"` @@ -514,6 +1609,12 @@ type EventEnvelopeContractSource string // EventEnvelopeSpecversion defines model for EventEnvelope.Specversion. type EventEnvelopeSpecversion string +// EventPage defines model for EventPage. +type EventPage struct { + Items []EventEnvelope `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // EventTypeDefinition defines model for EventTypeDefinition. type EventTypeDefinition struct { CreatedAt *time.Time `json:"created_at,omitempty"` @@ -539,6 +1640,88 @@ type EventTypeDefinitionSource string // EventTypeDefinitionStatus defines model for EventTypeDefinition.Status. type EventTypeDefinitionStatus string +// EventTypePage defines model for EventTypePage. +type EventTypePage struct { + Items []EventTypeDefinition `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// ExchangeDelegation defines model for ExchangeDelegation. +type ExchangeDelegation struct { + ExchangeCode *string `json:"exchange_code,omitempty"` +} + +// ExchangeInvitation defines model for ExchangeInvitation. +type ExchangeInvitation struct { + Code *string `json:"code,omitempty"` + CodeChallenge *string `json:"code_challenge,omitempty"` + Email *openapi_types.Email `json:"email,omitempty"` + InvitationId *UUID `json:"invitation_id,omitempty"` + LinkToken *string `json:"link_token,omitempty"` + union json.RawMessage +} + +// ExchangeInvitation0 defines model for . +type ExchangeInvitation0 = interface{} + +// ExchangeInvitation1 defines model for . +type ExchangeInvitation1 = interface{} + +// ExternalAuthExchange defines model for ExternalAuthExchange. +type ExternalAuthExchange struct { + Exchange *string `json:"exchange,omitempty"` +} + +// ExternalAuthStart defines model for ExternalAuthStart. +type ExternalAuthStart struct { + AuthorizeUrl string `json:"authorize_url"` + ExpiresIn int `json:"expires_in"` + Provider interface{} `json:"provider"` +} + +// ExternalAuthStartRequest defines model for ExternalAuthStartRequest. +type ExternalAuthStartRequest struct { + Flow interface{} `json:"flow,omitempty"` + LoginHint *openapi_types.Email `json:"login_hint,omitempty"` + RedirectUri string `json:"redirect_uri"` +} + +// ExternalIdentity defines model for ExternalIdentity. +type ExternalIdentity struct { + CreatedAt time.Time `json:"created_at"` + Email *openapi_types.Email `json:"email,omitempty"` + Id UUID `json:"id"` + LastUsedAt *time.Time `json:"last_used_at,omitempty"` + Provider interface{} `json:"provider"` +} + +// ExternalIdentityPage defines model for ExternalIdentityPage. +type ExternalIdentityPage struct { + Items []ExternalIdentity `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// Feature defines model for Feature. +type Feature struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + FreeFormFormat *FeatureFreeFormFormat `json:"free_form_format,omitempty"` + Id UUID `json:"id"` + Key string `json:"key"` + Metadata map[string]interface{} `json:"metadata"` + Name string `json:"name"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + ValueType interface{} `json:"value_type"` +} + +// FeatureFreeFormFormat defines model for Feature.FreeFormFormat. +type FeatureFreeFormFormat string + +// FeaturePage defines model for FeaturePage. +type FeaturePage struct { + Items []Feature `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // FeatureValue defines model for FeatureValue. type FeatureValue struct { BooleanValue *bool `json:"boolean_value,omitempty"` @@ -549,18 +1732,143 @@ type FeatureValue struct { QuantityValue *int `json:"quantity_value,omitempty"` } +// FinishWebAuthnCeremony defines model for FinishWebAuthnCeremony. +type FinishWebAuthnCeremony struct { + CeremonyId UUID `json:"ceremony_id"` + Credential map[string]interface{} `json:"credential"` +} + +// HealthStatus defines model for HealthStatus. +type HealthStatus struct { + Status HealthStatusStatus `json:"status"` +} + +// HealthStatusStatus defines model for HealthStatus.Status. +type HealthStatusStatus string + +// InvitationExchangeResult defines model for InvitationExchangeResult. +type InvitationExchangeResult struct { + AuthorizationCode *string `json:"authorization_code,omitempty"` + ExpiresIn int `json:"expires_in"` + MfaChallengeId *openapi_types.UUID `json:"mfa_challenge_id,omitempty"` + RedirectUri string `json:"redirect_uri"` +} + +// InvitationResent defines model for InvitationResent. +type InvitationResent struct { + ExpiresAt time.Time `json:"expires_at"` + Id UUID `json:"id"` + LastSentAt time.Time `json:"last_sent_at"` + ResendAvailableAt time.Time `json:"resend_available_at"` +} + +// Invoice defines model for Invoice. +type Invoice struct { + AmountDueMinor int64 `json:"amount_due_minor"` + AmountPaidMinor *int64 `json:"amount_paid_minor,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Currency string `json:"currency"` + ExternalReference *string `json:"external_reference,omitempty"` + HostedInvoiceUri *string `json:"hosted_invoice_uri,omitempty"` + Id UUID `json:"id"` + ProviderInvoiceId *string `json:"provider_invoice_id,omitempty"` + Status string `json:"status"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` + SubscriptionId *openapi_types.UUID `json:"subscription_id,omitempty"` +} + +// InvoicePage defines model for InvoicePage. +type InvoicePage struct { + Items []Invoice `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// JWKS defines model for JWKS. +type JWKS struct { + Keys []struct { + Alg string `json:"alg"` + E string `json:"e"` + Kid string `json:"kid"` + Kty string `json:"kty"` + N string `json:"n"` + Use string `json:"use"` + } `json:"keys"` +} + // LocalCheckout defines model for LocalCheckout. type LocalCheckout struct { - AddressId *UUID `json:"address_id,omitempty"` - LocalReference *string `json:"local_reference,omitempty"` - PriceId UUID `json:"price_id"` - SubjectId *UUID `json:"subject_id,omitempty"` - SubjectType interface{} `json:"subject_type,omitempty"` + AddressId *UUID `json:"address_id,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + PriceId UUID `json:"price_id"` + SubjectId *UUID `json:"subject_id,omitempty"` + SubjectType interface{} `json:"subject_type,omitempty"` +} + +// LocalEntitlementApproval defines model for LocalEntitlementApproval. +type LocalEntitlementApproval struct { + EntitlementGrantId UUID `json:"entitlement_grant_id"` + Status LocalEntitlementApprovalStatus `json:"status"` +} + +// LocalEntitlementApprovalStatus defines model for LocalEntitlementApproval.Status. +type LocalEntitlementApprovalStatus string + +// LocalEntitlementRequest defines model for LocalEntitlementRequest. +type LocalEntitlementRequest struct { + AddressSnapshot *map[string]interface{} `json:"address_snapshot,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + EntitlementGrantId *openapi_types.UUID `json:"entitlement_grant_id,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + FeatureSnapshot map[string]interface{} `json:"feature_snapshot"` + Id UUID `json:"id"` + PriceSnapshot map[string]interface{} `json:"price_snapshot"` + ProductSnapshot map[string]interface{} `json:"product_snapshot"` + Reason *string `json:"reason,omitempty"` + Status interface{} `json:"status"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// LocalEntitlementRequestPage defines model for LocalEntitlementRequestPage. +type LocalEntitlementRequestPage struct { + Items []LocalEntitlementRequest `json:"items"` + NextCursor *string `json:"next_cursor"` } // Locale Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. type Locale = string +// MFAActivation defines model for MFAActivation. +type MFAActivation struct { + MethodId UUID `json:"method_id"` + RecoveryCodes []string `json:"recovery_codes"` +} + +// MFAEnrollment defines model for MFAEnrollment. +type MFAEnrollment struct { + MethodId UUID `json:"method_id"` + ProvisioningUri string `json:"provisioning_uri"` + Secret *string `json:"secret,omitempty"` +} + +// MFAMethod defines model for MFAMethod. +type MFAMethod struct { + CreatedAt time.Time `json:"created_at"` + Id UUID `json:"id"` + LastUsedAt *time.Time `json:"last_used_at,omitempty"` + Name *string `json:"name,omitempty"` + Status interface{} `json:"status"` + Type interface{} `json:"type"` +} + +// MFAMethodPage defines model for MFAMethodPage. +type MFAMethodPage struct { + Items []MFAMethod `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // ManagementAPIStatus defines model for ManagementAPIStatus. type ManagementAPIStatus struct { ActiveClients int `json:"active_clients"` @@ -570,16 +1878,206 @@ type ManagementAPIStatus struct { TokenEndpoint string `json:"token_endpoint"` } -// OperatorPasswordChange defines model for OperatorPasswordChange. -type OperatorPasswordChange struct { - CurrentPassword *string `json:"current_password,omitempty"` - NewPassword *string `json:"new_password,omitempty"` +// ManagementClient defines model for ManagementClient. +type ManagementClient struct { + AllowedScopes []string `json:"allowed_scopes"` + ClientId string `json:"client_id"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + Name string `json:"name"` + Status interface{} `json:"status"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` } -// OperatorPasswordLogin defines model for OperatorPasswordLogin. -type OperatorPasswordLogin struct { - Email openapi_types.Email `json:"email"` - Password *string `json:"password,omitempty"` +// ManagementClientPage defines model for ManagementClientPage. +type ManagementClientPage struct { + Items []ManagementClient `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// MembershipRole defines model for MembershipRole. +type MembershipRole struct { + Role interface{} `json:"role"` +} + +// Notification defines model for Notification. +type Notification struct { + AttemptCount *int `json:"attempt_count,omitempty"` + CreatedAt time.Time `json:"created_at"` + DeliveredAt *time.Time `json:"delivered_at,omitempty"` + Id UUID `json:"id"` + LastError *string `json:"last_error,omitempty"` + + // Locale Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Locale *Locale `json:"locale,omitempty"` + Recipient openapi_types.Email `json:"recipient"` + Status interface{} `json:"status"` + TemplateKey string `json:"template_key"` +} + +// NotificationPage defines model for NotificationPage. +type NotificationPage struct { + Items []Notification `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// NotificationPreference defines model for NotificationPreference. +type NotificationPreference struct { + Category string `json:"category"` + EmailEnabled bool `json:"email_enabled"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// NotificationPreferencePage defines model for NotificationPreferencePage. +type NotificationPreferencePage struct { + Items []NotificationPreference `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// NotificationProvider defines model for NotificationProvider. +type NotificationProvider struct { + ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + CredentialsConfigured *bool `json:"credentials_configured,omitempty"` + DisabledAt *time.Time `json:"disabled_at,omitempty"` + Effective *bool `json:"effective,omitempty"` + Id UUID `json:"id"` + Inheritable bool `json:"inheritable"` + Name string `json:"name"` + OrganizationId *openapi_types.UUID `json:"organization_id,omitempty"` + Provider NotificationProviderProvider `json:"provider"` + Scope interface{} `json:"scope"` + SenderEmail openapi_types.Email `json:"sender_email"` + SenderName string `json:"sender_name"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Verified *bool `json:"verified,omitempty"` + VerifiedAt *time.Time `json:"verified_at,omitempty"` +} + +// NotificationProviderProvider defines model for NotificationProvider.Provider. +type NotificationProviderProvider string + +// NotificationProviderPage defines model for NotificationProviderPage. +type NotificationProviderPage struct { + Items []NotificationProvider `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// NotificationQueued defines model for NotificationQueued. +type NotificationQueued struct { + NotificationId UUID `json:"notification_id"` + Status NotificationQueuedStatus `json:"status"` +} + +// NotificationQueuedStatus defines model for NotificationQueued.Status. +type NotificationQueuedStatus string + +// NotificationStatistics defines model for NotificationStatistics. +type NotificationStatistics struct { + AttemptsDelivered int `json:"attempts_delivered"` + AttemptsFailed int `json:"attempts_failed"` + NotificationStatusCounts map[string]int `json:"notification_status_counts"` +} + +// NotificationTemplate defines model for NotificationTemplate. +type NotificationTemplate struct { + ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` + Category string `json:"category"` + CreatedAt *time.Time `json:"created_at,omitempty"` + HtmlTemplate *string `json:"html_template,omitempty"` + Id UUID `json:"id"` + Key string `json:"key"` + + // Locale Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Locale Locale `json:"locale"` + Status interface{} `json:"status"` + SubjectTemplate *string `json:"subject_template,omitempty"` + TextTemplate *string `json:"text_template,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Version int `json:"version"` +} + +// NotificationTemplatePage defines model for NotificationTemplatePage. +type NotificationTemplatePage struct { + Items []NotificationTemplate `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// NotificationTemplatePreview defines model for NotificationTemplatePreview. +type NotificationTemplatePreview struct { + Html *string `json:"html"` + Subject string `json:"subject"` + TemplateId UUID `json:"template_id"` + Text string `json:"text"` + Version int `json:"version"` +} + +// OAuthClient defines model for OAuthClient. +type OAuthClient struct { + AllowedGrants *[]string `json:"allowed_grants,omitempty"` + AllowedScopes *[]string `json:"allowed_scopes,omitempty"` + ClientId string `json:"client_id"` + ClientSecret *string `json:"client_secret,omitempty"` + ClientType interface{} `json:"client_type"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + Name string `json:"name"` + PostLogoutRedirectUris *[]string `json:"post_logout_redirect_uris,omitempty"` + RedirectUris *[]string `json:"redirect_uris,omitempty"` + Secret *string `json:"secret,omitempty"` + SecretReturnedOnce *bool `json:"secret_returned_once,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// OAuthClientPage defines model for OAuthClientPage. +type OAuthClientPage struct { + Items []OAuthClient `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// OAuthConsent defines model for OAuthConsent. +type OAuthConsent struct { + ClientId string `json:"client_id"` + ClientName *string `json:"client_name,omitempty"` + CreatedAt time.Time `json:"created_at"` + Id UUID `json:"id"` + Scopes []string `json:"scopes"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// OAuthConsentPage defines model for OAuthConsentPage. +type OAuthConsentPage struct { + Items []OAuthConsent `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// OIDCDiscovery defines model for OIDCDiscovery. +type OIDCDiscovery struct { + AuthorizationEndpoint string `json:"authorization_endpoint"` + CodeChallengeMethodsSupported *[]string `json:"code_challenge_methods_supported,omitempty"` + GrantTypesSupported *[]string `json:"grant_types_supported,omitempty"` + IdTokenSigningAlgValuesSupported []string `json:"id_token_signing_alg_values_supported"` + IntrospectionEndpoint *string `json:"introspection_endpoint,omitempty"` + Issuer string `json:"issuer"` + JwksUri string `json:"jwks_uri"` + ResponseTypesSupported []string `json:"response_types_supported"` + RevocationEndpoint *string `json:"revocation_endpoint,omitempty"` + ScopesSupported *[]string `json:"scopes_supported,omitempty"` + SubjectTypesSupported []string `json:"subject_types_supported"` + TokenEndpoint string `json:"token_endpoint"` + UserinfoEndpoint *string `json:"userinfo_endpoint,omitempty"` +} + +// Organization defines model for Organization. +type Organization struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + Name string `json:"name"` + RetiredAt *time.Time `json:"retired_at,omitempty"` + Role *string `json:"role,omitempty"` + Slug string `json:"slug"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Version int64 `json:"version"` } // OrganizationEnabledSettings defines model for OrganizationEnabledSettings. @@ -595,15 +2093,31 @@ type OrganizationEnabledSettings struct { Webhooks bool `json:"webhooks"` } +// OrganizationMember defines model for OrganizationMember. +type OrganizationMember struct { + ControlUserId UUID `json:"control_user_id"` + DisplayName string `json:"display_name"` + Email openapi_types.Email `json:"email"` + JoinedAt *time.Time `json:"joined_at,omitempty"` + Role interface{} `json:"role"` + Status interface{} `json:"status"` +} + +// OrganizationMemberPage defines model for OrganizationMemberPage. +type OrganizationMemberPage struct { + Items []OrganizationMember `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // OrganizationPage defines model for OrganizationPage. type OrganizationPage struct { - // InstallationRole The current operator's installation-wide role, or null for organization-only access. - InstallationRole *OrganizationPageInstallationRole `json:"installation_role"` - Items []map[string]interface{} `json:"items"` + // InstallationRole The current Platform user's installation-wide role, or null for organization-only access. + InstallationRole *OrganizationPageInstallationRole `json:"installation_role,omitempty"` + Items []Organization `json:"items"` NextCursor *string `json:"next_cursor"` } -// OrganizationPageInstallationRole The current operator's installation-wide role, or null for organization-only access. +// OrganizationPageInstallationRole The current Platform user's installation-wide role, or null for organization-only access. type OrganizationPageInstallationRole string // OrganizationPolicy defines model for OrganizationPolicy. @@ -637,10 +2151,23 @@ type OwnershipTransferResult struct { WorkspaceId UUID `json:"workspace_id"` } -// Page defines model for Page. -type Page struct { - Items []interface{} `json:"items"` - NextCursor *string `json:"next_cursor"` +// PasswordChange defines model for PasswordChange. +type PasswordChange struct { + CurrentPassword *string `json:"current_password,omitempty"` + NewPassword *string `json:"new_password,omitempty"` +} + +// PasswordResetStart defines model for PasswordResetStart. +type PasswordResetStart struct { + Email openapi_types.Email `json:"email"` +} + +// PasswordResetVerify defines model for PasswordResetVerify. +type PasswordResetVerify struct { + ChallengeId UUID `json:"challenge_id"` + Code *string `json:"code,omitempty"` + LinkToken *string `json:"link_token,omitempty"` + Password *string `json:"password,omitempty"` } // PasswordSignIn defines model for PasswordSignIn. @@ -660,14 +2187,168 @@ type PasswordSignUp struct { Password *string `json:"password,omitempty"` } +// Payment defines model for Payment. +type Payment struct { + AmountMinor int64 `json:"amount_minor"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Currency string `json:"currency"` + ExternalReference *string `json:"external_reference,omitempty"` + Id UUID `json:"id"` + InvoiceId *openapi_types.UUID `json:"invoice_id,omitempty"` + ProviderPaymentId *string `json:"provider_payment_id,omitempty"` + Status string `json:"status"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` +} + +// PaymentPage defines model for PaymentPage. +type PaymentPage struct { + Items []Payment `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// PermissionCheck defines model for PermissionCheck. +type PermissionCheck struct { + Permissions []PermissionKey `json:"permissions"` + WorkspaceId *UUID `json:"workspace_id,omitempty"` +} + +// PermissionCheckResult defines model for PermissionCheckResult. +type PermissionCheckResult struct { + Results map[string]bool `json:"results"` + WorkspaceId *openapi_types.UUID `json:"workspace_id"` +} + +// PermissionGrant defines model for PermissionGrant. +type PermissionGrant struct { + ApplicationId UUID `json:"application_id"` + CanonicalScope string `json:"canonical_scope"` + CreatedAt time.Time `json:"created_at"` + Id UUID `json:"id"` + Permission PermissionKey `json:"permission"` + Reason *string `json:"reason,omitempty"` + RevokedAt *time.Time `json:"revoked_at,omitempty"` + Status PermissionGrantStatus `json:"status"` + SubjectId UUID `json:"subject_id"` + SubjectType PermissionGrantSubjectType `json:"subject_type"` + Version int64 `json:"version"` + WorkspaceId *UUID `json:"workspace_id,omitempty"` +} + +// PermissionGrantStatus defines model for PermissionGrant.Status. +type PermissionGrantStatus string + +// PermissionGrantSubjectType defines model for PermissionGrant.SubjectType. +type PermissionGrantSubjectType string + +// PermissionGrantPage defines model for PermissionGrantPage. +type PermissionGrantPage struct { + Items []PermissionGrant `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// PermissionKey defines model for PermissionKey. +type PermissionKey = string + +// PersonalAPIKey defines model for PersonalAPIKey. +type PersonalAPIKey struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + ExpiresAt time.Time `json:"expires_at"` + Id UUID `json:"id"` + Label string `json:"label"` + LastUsedAt *time.Time `json:"last_used_at,omitempty"` + Scopes []string `json:"scopes"` + Status interface{} `json:"status"` + TokenPrefix string `json:"token_prefix"` +} + +// PersonalAPIKeyCreated defines model for PersonalAPIKeyCreated. +type PersonalAPIKeyCreated struct { + ApiKey struct { + ExpiresAt time.Time `json:"expires_at"` + Id UUID `json:"id"` + Label string `json:"label"` + Scopes []string `json:"scopes"` + TokenPrefix string `json:"token_prefix"` + } `json:"api_key"` + Token *string `json:"token,omitempty"` +} + +// PersonalAPIKeyPage defines model for PersonalAPIKeyPage. +type PersonalAPIKeyPage struct { + Items []PersonalAPIKey `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// PortalSession defines model for PortalSession. +type PortalSession struct { + PortalUri string `json:"portal_uri"` + ProviderSessionId string `json:"provider_session_id"` +} + +// PreviewNotificationTemplate defines model for PreviewNotificationTemplate. +type PreviewNotificationTemplate struct { + Recipient *openapi_types.Email `json:"recipient,omitempty"` + UserId *UUID `json:"user_id,omitempty"` + Variables map[string]interface{} `json:"variables"` +} + +// Price defines model for Price. +type Price struct { + AmountMinor *int64 `json:"amount_minor,omitempty"` + CheckoutConfig map[string]interface{} `json:"checkout_config"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Currency string `json:"currency"` + CurrencyExponent int `json:"currency_exponent"` + EntitlementConfig map[string]interface{} `json:"entitlement_config"` + Features map[string]FeatureValue `json:"features"` + Id UUID `json:"id"` + Key string `json:"key"` + Mode interface{} `json:"mode"` + ProductId *UUID `json:"product_id,omitempty"` + Status interface{} `json:"status,omitempty"` + TaxBehavior interface{} `json:"tax_behavior"` + Version *int64 `json:"version,omitempty"` +} + +// PricePage defines model for PricePage. +type PricePage struct { + Items []Price `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // Problem defines model for Problem. type Problem struct { - Code string `json:"code"` - Detail *string `json:"detail,omitempty"` - RequestId *string `json:"request_id,omitempty"` - Status int `json:"status"` - Title string `json:"title"` - Type string `json:"type"` + AffectedUsers *int `json:"affected_users,omitempty"` + Code string `json:"code"` + Detail *string `json:"detail,omitempty"` + RequestId *string `json:"request_id,omitempty"` + Status int `json:"status"` + Title string `json:"title"` + Type string `json:"type"` +} + +// Product defines model for Product. +type Product struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Description *string `json:"description,omitempty"` + EntitlementConfig map[string]interface{} `json:"entitlement_config"` + Features map[string]FeatureValue `json:"features"` + Id UUID `json:"id"` + Key string `json:"key"` + Listable bool `json:"listable"` + Metadata map[string]interface{} `json:"metadata"` + Name string `json:"name"` + Prices *[]Price `json:"prices,omitempty"` + Status interface{} `json:"status"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Version int64 `json:"version"` +} + +// ProductPage defines model for ProductPage. +type ProductPage struct { + Items []Product `json:"items"` + NextCursor *string `json:"next_cursor"` } // PublishCustomEvent defines model for PublishCustomEvent. @@ -708,6 +2389,94 @@ type QueuedNotification struct { Status interface{} `json:"status"` } +// ReconciliationAccepted defines model for ReconciliationAccepted. +type ReconciliationAccepted struct { + Id UUID `json:"id"` + ProviderId UUID `json:"provider_id"` + Status ReconciliationAcceptedStatus `json:"status"` +} + +// ReconciliationAcceptedStatus defines model for ReconciliationAccepted.Status. +type ReconciliationAcceptedStatus string + +// ReconciliationRun defines model for ReconciliationRun. +type ReconciliationRun struct { + CompletedAt *time.Time `json:"completed_at,omitempty"` + CreatedAt time.Time `json:"created_at"` + Findings int `json:"findings"` + Id UUID `json:"id"` + LastError *string `json:"last_error,omitempty"` + ProviderId UUID `json:"provider_id"` + Repairs int `json:"repairs"` + StartedAt *time.Time `json:"started_at,omitempty"` + Status interface{} `json:"status"` +} + +// ReconciliationRunPage defines model for ReconciliationRunPage. +type ReconciliationRunPage struct { + Items []ReconciliationRun `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// RecoveryCodes defines model for RecoveryCodes. +type RecoveryCodes struct { + RecoveryCodes []string `json:"recovery_codes"` +} + +// RedeemInvitation defines model for RedeemInvitation. +type RedeemInvitation struct { + AuthorizationCode *string `json:"authorization_code,omitempty"` + CodeVerifier *string `json:"code_verifier,omitempty"` +} + +// RefreshToken defines model for RefreshToken. +type RefreshToken struct { + RefreshToken *string `json:"refresh_token,omitempty"` +} + +// Refund defines model for Refund. +type Refund struct { + AmountMinor int64 `json:"amount_minor"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Currency string `json:"currency"` + ExternalReference *string `json:"external_reference,omitempty"` + Id UUID `json:"id"` + PaymentId *UUID `json:"payment_id,omitempty"` + ProviderRefundId *string `json:"provider_refund_id,omitempty"` + Reason *string `json:"reason,omitempty"` + Status string `json:"status"` +} + +// RefundPage defines model for RefundPage. +type RefundPage struct { + Items []Refund `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// ReplaceWorkspaceMemberRoles defines model for ReplaceWorkspaceMemberRoles. +type ReplaceWorkspaceMemberRoles struct { + RoleKeys []RoleKey `json:"role_keys"` +} + +// RevokedSessionCount defines model for RevokedSessionCount. +type RevokedSessionCount struct { + RevokedSessions int `json:"revoked_sessions"` +} + +// Role defines model for Role. +type Role struct { + BuiltIn bool `json:"built_in"` + Id UUID `json:"id"` + Key RoleKey `json:"key"` + Name string `json:"name"` + Permissions []PermissionKey `json:"permissions"` + Scope RoleScope `json:"scope"` + Version int64 `json:"version"` +} + +// RoleScope defines model for Role.Scope. +type RoleScope string + // RoleAssignment defines model for RoleAssignment. type RoleAssignment struct { ClientId *UUID `json:"client_id,omitempty"` @@ -723,7 +2492,32 @@ type RoleAssignment0 = interface{} // RoleAssignment1 defines model for . type RoleAssignment1 = interface{} -// RuntimeAuthConfig defines model for RuntimeAuthConfig. +// RoleAssignmentPage defines model for RoleAssignmentPage. +type RoleAssignmentPage struct { + Items []RoleAssignmentRecord `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// RoleAssignmentRecord defines model for RoleAssignmentRecord. +type RoleAssignmentRecord struct { + ClientId *openapi_types.UUID `json:"client_id,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + RoleId UUID `json:"role_id"` + UserId *openapi_types.UUID `json:"user_id,omitempty"` + WorkspaceId *openapi_types.UUID `json:"workspace_id,omitempty"` +} + +// RoleKey defines model for RoleKey. +type RoleKey = string + +// RolePage defines model for RolePage. +type RolePage struct { + Items []Role `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// RuntimeAuthConfig defines model for RuntimeAuthConfig. type RuntimeAuthConfig struct { Flows *ApplicationFlowConfig `json:"flows,omitempty"` PasswordEnabled bool `json:"password_enabled"` @@ -757,6 +2551,110 @@ type RuntimeStorageConfig struct { PublicUploadsEnabled bool `json:"public_uploads_enabled"` } +// SecretCredential defines model for SecretCredential. +type SecretCredential struct { + ClientId *string `json:"client_id,omitempty"` + Id *UUID `json:"id,omitempty"` + PreviousSecretValidForSeconds *int `json:"previous_secret_valid_for_seconds,omitempty"` + Secret *string `json:"secret,omitempty"` + SecretReturnedOnce bool `json:"secret_returned_once"` +} + +// SenderIdentity defines model for SenderIdentity. +type SenderIdentity struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Email openapi_types.Email `json:"email"` + Id UUID `json:"id"` + IsDefault bool `json:"is_default"` + Name string `json:"name"` + ProviderId UUID `json:"provider_id"` + Verified bool `json:"verified"` +} + +// SenderIdentityPage defines model for SenderIdentityPage. +type SenderIdentityPage struct { + Items []SenderIdentity `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// Session defines model for Session. +type Session struct { + ActorType interface{} `json:"actor_type"` + Amr *[]string `json:"amr,omitempty"` + AuthenticatedAt *time.Time `json:"authenticated_at,omitempty"` + CreatedAt time.Time `json:"created_at"` + ExpiresAt time.Time `json:"expires_at"` + Id UUID `json:"id"` + IpAddress *string `json:"ip_address,omitempty"` + Revoked bool `json:"revoked"` + UserAgent *string `json:"user_agent,omitempty"` +} + +// SessionPage defines model for SessionPage. +type SessionPage struct { + Items []Session `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// SetupCompletion defines model for SetupCompletion. +type SetupCompletion struct { + AccessToken *string `json:"access_token,omitempty"` + Completed SetupCompletionCompleted `json:"completed"` + ExpiresIn int `json:"expires_in"` + RefreshToken *string `json:"refresh_token,omitempty"` + TokenType interface{} `json:"token_type"` +} + +// SetupCompletionCompleted defines model for SetupCompletion.Completed. +type SetupCompletionCompleted bool + +// SetupSession defines model for SetupSession. +type SetupSession struct { + AccessToken *string `json:"access_token,omitempty"` + ControlUserId UUID `json:"control_user_id"` + ExpiresIn int `json:"expires_in"` + RefreshToken *string `json:"refresh_token,omitempty"` + TokenType interface{} `json:"token_type"` +} + +// SetupStatus defines model for SetupStatus. +type SetupStatus struct { + Available bool `json:"available"` + ControlAuthMethods ControlAuthMethods `json:"control_auth_methods"` + ControlUserEmailLoginAvailable bool `json:"control_user_email_login_available"` +} + +// SigningKey defines model for SigningKey. +type SigningKey struct { + Algorithm SigningKeyAlgorithm `json:"algorithm"` + CreatedAt time.Time `json:"created_at"` + Id UUID `json:"id"` + Kid string `json:"kid"` + RetiresAt *time.Time `json:"retires_at,omitempty"` + Status interface{} `json:"status"` +} + +// SigningKeyAlgorithm defines model for SigningKey.Algorithm. +type SigningKeyAlgorithm string + +// SigningKeyPage defines model for SigningKeyPage. +type SigningKeyPage struct { + Items []SigningKey `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// StartTOTP defines model for StartTOTP. +type StartTOTP struct { + Label *string `json:"label,omitempty"` +} + +// StorageDownload defines model for StorageDownload. +type StorageDownload struct { + ExpiresAt time.Time `json:"expires_at"` + Url string `json:"url"` + Visibility interface{} `json:"visibility"` +} + // StorageObject defines model for StorageObject. type StorageObject struct { ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` @@ -780,6 +2678,57 @@ type StorageObject struct { Visibility interface{} `json:"visibility"` } +// StorageObjectPage defines model for StorageObjectPage. +type StorageObjectPage struct { + Items []StorageObject `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// StorageProvider defines model for StorageProvider. +type StorageProvider struct { + AllowPrivateEndpoint bool `json:"allow_private_endpoint"` + ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + CredentialsConfigured bool `json:"credentials_configured"` + DisabledAt *time.Time `json:"disabled_at,omitempty"` + Endpoint string `json:"endpoint"` + ForcePathStyle bool `json:"force_path_style"` + Id UUID `json:"id"` + Inheritable bool `json:"inheritable"` + LastError *string `json:"last_error,omitempty"` + MaxApplicationBytes int64 `json:"max_application_bytes"` + MaxApplicationObjects int64 `json:"max_application_objects"` + MaxEmailImageBytes int64 `json:"max_email_image_bytes"` + MaxObjectBytes int64 `json:"max_object_bytes"` + Name string `json:"name"` + OrganizationId *openapi_types.UUID `json:"organization_id,omitempty"` + PrivateBucket *string `json:"private_bucket,omitempty"` + Provider StorageProviderProvider `json:"provider"` + PublicBaseUrl *string `json:"public_base_url,omitempty"` + PublicBucket *string `json:"public_bucket,omitempty"` + Region string `json:"region"` + Scope interface{} `json:"scope"` + Status interface{} `json:"status"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + VerifiedAt *time.Time `json:"verified_at,omitempty"` + Version int64 `json:"version"` +} + +// StorageProviderProvider defines model for StorageProvider.Provider. +type StorageProviderProvider string + +// StorageProviderPage defines model for StorageProviderPage. +type StorageProviderPage struct { + Items []StorageProvider `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// StorageProviderStatus defines model for StorageProviderStatus. +type StorageProviderStatus struct { + Id UUID `json:"id"` + Status interface{} `json:"status"` +} + // StorageUploadAuthorization defines model for StorageUploadAuthorization. type StorageUploadAuthorization struct { Object StorageObject `json:"object"` @@ -788,6 +2737,73 @@ type StorageUploadAuthorization struct { UploadUrl *string `json:"upload_url,omitempty"` } +// StructuredRoles defines model for StructuredRoles. +type StructuredRoles struct { + Application []RoleKey `json:"application"` + Workspaces map[string][]RoleKey `json:"workspaces"` +} + +// Subscription defines model for Subscription. +type Subscription struct { + CancelAtPeriodEnd *bool `json:"cancel_at_period_end,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + CurrentPeriodEnd *time.Time `json:"current_period_end,omitempty"` + CurrentPeriodStart *time.Time `json:"current_period_start,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + Id UUID `json:"id"` + PriceId UUID `json:"price_id"` + ProviderId UUID `json:"provider_id"` + ProviderSubscriptionId *string `json:"provider_subscription_id,omitempty"` + Status string `json:"status"` + SubjectId UUID `json:"subject_id"` + SubjectType interface{} `json:"subject_type"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} + +// SubscriptionPage defines model for SubscriptionPage. +type SubscriptionPage struct { + Items []Subscription `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// TemplateVariables defines model for TemplateVariables. +type TemplateVariables struct { + Optional []string `json:"optional"` + Protected []string `json:"protected"` +} + +// TestNotificationProvider defines model for TestNotificationProvider. +type TestNotificationProvider struct { + Recipient openapi_types.Email `json:"recipient"` +} + +// TokenIntrospection defines model for TokenIntrospection. +type TokenIntrospection struct { + Active bool `json:"active"` + ActorType interface{} `json:"actor_type,omitempty"` + ApplicationId *openapi_types.UUID `json:"application_id,omitempty"` + Aud *TokenIntrospection_Aud `json:"aud,omitempty"` + ClientId *string `json:"client_id,omitempty"` + Exp *int64 `json:"exp,omitempty"` + Iat *int64 `json:"iat,omitempty"` + Iss *string `json:"iss,omitempty"` + Roles *StructuredRoles `json:"roles,omitempty"` + Scope *string `json:"scope,omitempty"` + Sub *string `json:"sub,omitempty"` + TokenType *string `json:"token_type,omitempty"` +} + +// TokenIntrospectionAud0 defines model for . +type TokenIntrospectionAud0 = string + +// TokenIntrospectionAud1 defines model for . +type TokenIntrospectionAud1 = []string + +// TokenIntrospection_Aud defines model for TokenIntrospection.Aud. +type TokenIntrospection_Aud struct { + union json.RawMessage +} + // TokenResponse defines model for TokenResponse. type TokenResponse struct { AccessToken *string `json:"access_token,omitempty"` @@ -799,6 +2815,61 @@ type TokenResponse struct { // UUID defines model for UUID. type UUID = openapi_types.UUID +// UpdateAddress defines model for UpdateAddress. +type UpdateAddress struct { + City *string `json:"city,omitempty"` + CountryCode *string `json:"country_code,omitempty"` + Line1 *string `json:"line1,omitempty"` + Line2 *string `json:"line2,omitempty"` + Name *string `json:"name,omitempty"` + PostalCode *string `json:"postal_code,omitempty"` + Region *string `json:"region,omitempty"` + TaxId *string `json:"tax_id,omitempty"` + Version int64 `json:"version"` +} + +// UpdateBillingProfile defines model for UpdateBillingProfile. +type UpdateBillingProfile struct { + Email *openapi_types.Email `json:"email,omitempty"` + Name *string `json:"name,omitempty"` + TaxId *string `json:"tax_id,omitempty"` + Version int64 `json:"version"` +} + +// UpdateBillingProvider defines model for UpdateBillingProvider. +type UpdateBillingProvider struct { + Inheritable *bool `json:"inheritable,omitempty"` + Metadata *map[string]interface{} `json:"metadata,omitempty"` + Secret *string `json:"secret,omitempty"` + WebhookSecret *string `json:"webhook_secret,omitempty"` +} + +// UpdateClient defines model for UpdateClient. +type UpdateClient struct { + AllowedGrants *[]interface{} `json:"allowed_grants,omitempty"` + AllowedScopes *[]string `json:"allowed_scopes,omitempty"` + Name *string `json:"name,omitempty"` + RedirectUris *[]string `json:"redirect_uris,omitempty"` +} + +// UpdateControlAuthPolicy defines model for UpdateControlAuthPolicy. +type UpdateControlAuthPolicy struct { + ConfirmAffectedUsers *bool `json:"confirm_affected_users,omitempty"` + EmailCodeEnabled bool `json:"email_code_enabled"` + MagicLinkEnabled bool `json:"magic_link_enabled"` + PasswordEnabled bool `json:"password_enabled"` +} + +// UpdateControlInvitationMethod defines model for UpdateControlInvitationMethod. +type UpdateControlInvitationMethod struct { + OnboardingMethod interface{} `json:"onboarding_method,omitempty"` +} + +// UpdateControlUserAccount defines model for UpdateControlUserAccount. +type UpdateControlUserAccount struct { + DisplayName string `json:"display_name"` +} + // UpdateEventType defines model for UpdateEventType. type UpdateEventType struct { DataSchema *map[string]interface{} `json:"data_schema,omitempty"` @@ -809,6 +2880,32 @@ type UpdateEventType struct { Status interface{} `json:"status,omitempty"` } +// UpdateInstallationAuthProvider defines model for UpdateInstallationAuthProvider. +type UpdateInstallationAuthProvider struct { + ConfirmAffectedUsers *bool `json:"confirm_affected_users,omitempty"` + ControlLoginEnabled *bool `json:"control_login_enabled,omitempty"` + Inheritable *bool `json:"inheritable,omitempty"` +} + +// UpdateManagementAPI defines model for UpdateManagementAPI. +type UpdateManagementAPI struct { + Enabled bool `json:"enabled"` +} + +// UpdateNotificationPreference defines model for UpdateNotificationPreference. +type UpdateNotificationPreference struct { + EmailEnabled bool `json:"email_enabled"` +} + +// UpdateNotificationTemplate defines model for UpdateNotificationTemplate. +type UpdateNotificationTemplate struct { + Category interface{} `json:"category,omitempty"` + HtmlTemplate *string `json:"html_template,omitempty"` + SubjectTemplate *string `json:"subject_template,omitempty"` + TextTemplate *string `json:"text_template,omitempty"` + VariableSchema *map[string]interface{} `json:"variable_schema,omitempty"` +} + // UpdateOrganizationPolicy defines model for UpdateOrganizationPolicy. type UpdateOrganizationPolicy struct { EnabledSettings OrganizationEnabledSettings `json:"enabled_settings"` @@ -831,6 +2928,59 @@ type UpdateProduct struct { Status interface{} `json:"status,omitempty"` } +// UpdateRole defines model for UpdateRole. +type UpdateRole struct { + Name *string `json:"name,omitempty"` + Permissions *[]PermissionKey `json:"permissions,omitempty"` +} + +// UpdateSMTPProvider defines model for UpdateSMTPProvider. +type UpdateSMTPProvider struct { + Host *string `json:"host,omitempty"` + Inheritable *bool `json:"inheritable,omitempty"` + Name *string `json:"name,omitempty"` + Password *string `json:"password,omitempty"` + Port *int `json:"port,omitempty"` + SenderEmail *openapi_types.Email `json:"sender_email,omitempty"` + SenderName *string `json:"sender_name,omitempty"` + TlsMode interface{} `json:"tls_mode,omitempty"` + Username *string `json:"username,omitempty"` +} + +// UpdateStorageProvider defines model for UpdateStorageProvider. +type UpdateStorageProvider struct { + AccessKeyId *string `json:"access_key_id,omitempty"` + AllowPrivateEndpoint *bool `json:"allow_private_endpoint,omitempty"` + Endpoint *string `json:"endpoint,omitempty"` + ForcePathStyle *bool `json:"force_path_style,omitempty"` + Inheritable *bool `json:"inheritable,omitempty"` + MaxApplicationBytes *int64 `json:"max_application_bytes,omitempty"` + MaxApplicationObjects *int64 `json:"max_application_objects,omitempty"` + MaxEmailImageBytes *int64 `json:"max_email_image_bytes,omitempty"` + MaxObjectBytes *int64 `json:"max_object_bytes,omitempty"` + Name *string `json:"name,omitempty"` + PrivateBucket *string `json:"private_bucket,omitempty"` + PublicBaseUrl *string `json:"public_base_url,omitempty"` + PublicBucket *string `json:"public_bucket,omitempty"` + Region *string `json:"region,omitempty"` + SecretAccessKey *string `json:"secret_access_key,omitempty"` +} + +// UpdateUser defines model for UpdateUser. +type UpdateUser struct { + CustomAttributes *map[string]interface{} `json:"custom_attributes,omitempty"` + EmailVerified *bool `json:"email_verified,omitempty"` + FirstName *string `json:"first_name,omitempty"` + IsOrgVerified *bool `json:"is_org_verified,omitempty"` + LastName *string `json:"last_name,omitempty"` + + // Locale Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Locale *Locale `json:"locale,omitempty"` + Reason *string `json:"reason,omitempty"` + Status interface{} `json:"status,omitempty"` + Username *string `json:"username,omitempty"` +} + // UpdateUserProfile defines model for UpdateUserProfile. type UpdateUserProfile struct { FirstName *string `json:"first_name,omitempty"` @@ -841,6 +2991,19 @@ type UpdateUserProfile struct { Username *string `json:"username,omitempty"` } +// UpdateWebhook defines model for UpdateWebhook. +type UpdateWebhook struct { + Enabled *bool `json:"enabled,omitempty"` + EventFilters *[]string `json:"event_filters,omitempty"` + Uri *string `json:"uri,omitempty"` +} + +// UpdateWorkspace defines model for UpdateWorkspace. +type UpdateWorkspace struct { + Metadata *map[string]interface{} `json:"metadata,omitempty"` + Name *string `json:"name,omitempty"` +} + // User defines model for User. type User struct { ApplicationId UUID `json:"application_id"` @@ -859,6 +3022,164 @@ type User struct { Version *int64 `json:"version,omitempty"` } +// UserInfo defines model for UserInfo. +type UserInfo struct { + ActorType interface{} `json:"actor_type"` + ApplicationId UUID `json:"application_id"` + CustomClaims *map[string]interface{} `json:"custom_claims,omitempty"` + Email *openapi_types.Email `json:"email,omitempty"` + EmailVerified *bool `json:"email_verified,omitempty"` + FamilyName *string `json:"family_name,omitempty"` + GivenName *string `json:"given_name,omitempty"` + + // Locale Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + Locale *Locale `json:"locale,omitempty"` + Roles *StructuredRoles `json:"roles,omitempty"` + Scope *string `json:"scope,omitempty"` + Sub string `json:"sub"` +} + +// UserPage defines model for UserPage. +type UserPage struct { + Items []User `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// VerifyMFA defines model for VerifyMFA. +type VerifyMFA struct { + ChallengeId UUID `json:"challenge_id"` + Code *string `json:"code,omitempty"` + RecoveryCode *string `json:"recovery_code,omitempty"` + union json.RawMessage +} + +// VerifyMFA0 defines model for . +type VerifyMFA0 = interface{} + +// VerifyMFA1 defines model for . +type VerifyMFA1 = interface{} + +// VersionInfo defines model for VersionInfo. +type VersionInfo struct { + BuiltAt string `json:"built_at"` + Commit string `json:"commit"` + Schema string `json:"schema"` + Version string `json:"version"` +} + +// WebAuthnChallenge defines model for WebAuthnChallenge. +type WebAuthnChallenge struct { + CeremonyId UUID `json:"ceremony_id"` + ExpiresAt time.Time `json:"expires_at"` + Options map[string]interface{} `json:"options"` +} + +// Webhook defines model for Webhook. +type Webhook struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + Disabled bool `json:"disabled"` + DisabledAt *time.Time `json:"disabled_at,omitempty"` + EventFilters []string `json:"event_filters"` + Id UUID `json:"id"` + Secret *string `json:"secret,omitempty"` + SecretReturnedOnce *bool `json:"secret_returned_once,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Uri string `json:"uri"` +} + +// WebhookAcknowledgement defines model for WebhookAcknowledgement. +type WebhookAcknowledgement struct { + Received bool `json:"received"` +} + +// WebhookDelivery defines model for WebhookDelivery. +type WebhookDelivery struct { + AttemptCount int `json:"attempt_count"` + CreatedAt time.Time `json:"created_at"` + DeliveredAt *time.Time `json:"delivered_at,omitempty"` + EventId UUID `json:"event_id"` + Id UUID `json:"id"` + LastError *string `json:"last_error,omitempty"` + NextAttemptAt *time.Time `json:"next_attempt_at,omitempty"` + ResponseStatus *int `json:"response_status,omitempty"` + Status interface{} `json:"status"` + WebhookId UUID `json:"webhook_id"` +} + +// WebhookDeliveryPage defines model for WebhookDeliveryPage. +type WebhookDeliveryPage struct { + Items []WebhookDelivery `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// WebhookPage defines model for WebhookPage. +type WebhookPage struct { + Items []Webhook `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// WebhookTestAccepted defines model for WebhookTestAccepted. +type WebhookTestAccepted struct { + DeliveryId UUID `json:"delivery_id"` + EventId UUID `json:"event_id"` + Status WebhookTestAcceptedStatus `json:"status"` +} + +// WebhookTestAcceptedStatus defines model for WebhookTestAccepted.Status. +type WebhookTestAcceptedStatus string + +// Workspace defines model for Workspace. +type Workspace struct { + ApplicationId *UUID `json:"application_id,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + Id UUID `json:"id"` + Key string `json:"key"` + Metadata map[string]interface{} `json:"metadata"` + Name string `json:"name"` + OwnerUserId UUID `json:"owner_user_id"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + Version int64 `json:"version"` +} + +// WorkspaceAccessEntry defines model for WorkspaceAccessEntry. +type WorkspaceAccessEntry struct { + Email *openapi_types.Email `json:"email,omitempty"` + ExpiresAt *time.Time `json:"expires_at,omitempty"` + InvitationId *openapi_types.UUID `json:"invitation_id,omitempty"` + RoleKeys *[]RoleKey `json:"role_keys,omitempty"` + Status *string `json:"status,omitempty"` + Type interface{} `json:"type"` + UserId *openapi_types.UUID `json:"user_id,omitempty"` + WorkspaceId UUID `json:"workspace_id"` +} + +// WorkspaceAccessPage defines model for WorkspaceAccessPage. +type WorkspaceAccessPage struct { + Items []WorkspaceAccessEntry `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// WorkspaceMember defines model for WorkspaceMember. +type WorkspaceMember struct { + CreatedAt *time.Time `json:"created_at,omitempty"` + RoleKeys []RoleKey `json:"role_keys"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + UserId UUID `json:"user_id"` + WorkspaceId UUID `json:"workspace_id"` +} + +// WorkspaceMemberPage defines model for WorkspaceMemberPage. +type WorkspaceMemberPage struct { + Items []WorkspaceMember `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +// WorkspacePage defines model for WorkspacePage. +type WorkspacePage struct { + Items []Workspace `json:"items"` + NextCursor *string `json:"next_cursor"` +} + // ApplicationID defines model for ApplicationID. type ApplicationID = UUID @@ -901,12 +3222,24 @@ type OAuthState = string // ObjectID defines model for ObjectID. type ObjectID = UUID +// OptionalPermissionSubjectID defines model for OptionalPermissionSubjectID. +type OptionalPermissionSubjectID = UUID + +// OptionalPermissionSubjectType defines model for OptionalPermissionSubjectType. +type OptionalPermissionSubjectType string + // OrganizationID defines model for OrganizationID. type OrganizationID = UUID // PaymentID defines model for PaymentID. type PaymentID = UUID +// PermissionSubjectID defines model for PermissionSubjectID. +type PermissionSubjectID = UUID + +// PermissionSubjectType defines model for PermissionSubjectType. +type PermissionSubjectType string + // ProviderID defines model for ProviderID. type ProviderID = UUID @@ -940,8 +3273,8 @@ type Named struct { Slug string `json:"slug"` } -// Object defines model for Object. -type Object = map[string]interface{} +// PermissionGrantBody defines model for PermissionGrantBody. +type PermissionGrantBody = CreatePermissionGrant // ProviderInheritance defines model for ProviderInheritance. type ProviderInheritance struct { @@ -970,8 +3303,8 @@ type SMTPProvider struct { Username *string `json:"username,omitempty"` } -// StorageProvider defines model for StorageProvider. -type StorageProvider = CreateStorageProvider +// StorageProviderBody defines model for StorageProviderBody. +type StorageProviderBody = CreateStorageProvider // StorageUpload defines model for StorageUpload. type StorageUpload = CreateStorageUpload @@ -979,14 +3312,14 @@ type StorageUpload = CreateStorageUpload // bearerAuthContextKey is the context key for bearerAuth security scheme type bearerAuthContextKey string -// managementBearerContextKey is the context key for managementBearer security scheme -type managementBearerContextKey string +// controlBearerContextKey is the context key for controlBearer security scheme +type controlBearerContextKey string -// operatorBearerContextKey is the context key for operatorBearer security scheme -type operatorBearerContextKey string +// controlCookieContextKey is the context key for controlCookie security scheme +type controlCookieContextKey string -// operatorCookieContextKey is the context key for operatorCookie security scheme -type operatorCookieContextKey string +// managementBearerContextKey is the context key for managementBearer security scheme +type managementBearerContextKey string // BeginOIDCAuthorizationParams defines parameters for BeginOIDCAuthorization. type BeginOIDCAuthorizationParams struct { @@ -1060,65 +3393,16 @@ type StripeWebhookParams struct { StripeSignature string `json:"Stripe-Signature"` } -// AuthMethodsJSONBody defines parameters for AuthMethods. -type AuthMethodsJSONBody = map[string]interface{} - -// VerifyMFAJSONBody defines parameters for VerifyMFA. -type VerifyMFAJSONBody = map[string]interface{} - -// BeginWebAuthnAuthenticationJSONBody defines parameters for BeginWebAuthnAuthentication. -type BeginWebAuthnAuthenticationJSONBody = map[string]interface{} - -// FinishWebAuthnAuthenticationJSONBody defines parameters for FinishWebAuthnAuthentication. -type FinishWebAuthnAuthenticationJSONBody = map[string]interface{} - -// PasswordResetStartJSONBody defines parameters for PasswordResetStart. -type PasswordResetStartJSONBody = map[string]interface{} - -// PasswordResetVerifyJSONBody defines parameters for PasswordResetVerify. -type PasswordResetVerifyJSONBody = map[string]interface{} - -// AppleAuthCallbackFormdataBody defines parameters for AppleAuthCallback. -type AppleAuthCallbackFormdataBody struct { - Code *string `form:"code,omitempty" json:"code,omitempty"` - Error *string `form:"error,omitempty" json:"error,omitempty"` - State *string `form:"state,omitempty" json:"state,omitempty"` - User *string `form:"user,omitempty" json:"user,omitempty"` -} - -// ExchangeAppleAuthJSONBody defines parameters for ExchangeAppleAuth. -type ExchangeAppleAuthJSONBody = map[string]interface{} - -// StartAppleAuthJSONBody defines parameters for StartAppleAuth. -type StartAppleAuthJSONBody = map[string]interface{} - -// ExchangeGoogleAuthJSONBody defines parameters for ExchangeGoogleAuth. -type ExchangeGoogleAuthJSONBody = map[string]interface{} - -// StartGoogleAuthJSONBody defines parameters for StartGoogleAuth. -type StartGoogleAuthJSONBody = map[string]interface{} - -// RefreshJSONBody defines parameters for Refresh. -type RefreshJSONBody struct { - RefreshToken *string `json:"refresh_token,omitempty"` -} - // CreateCheckoutSessionParams defines parameters for CreateCheckoutSession. type CreateCheckoutSessionParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// CreateBillingPortalSessionJSONBody defines parameters for CreateBillingPortalSession. -type CreateBillingPortalSessionJSONBody = map[string]interface{} - // CreateBillingPortalSessionParams defines parameters for CreateBillingPortalSession. type CreateBillingPortalSessionParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// ExchangeDelegationJSONBody defines parameters for ExchangeDelegation. -type ExchangeDelegationJSONBody = map[string]interface{} - // PublishCustomEventParams defines parameters for PublishCustomEvent. type PublishCustomEventParams struct { IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` @@ -1129,116 +3413,102 @@ type LocalEntitlementCheckoutParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// CreateMyAddressJSONBody defines parameters for CreateMyAddress. -type CreateMyAddressJSONBody = map[string]interface{} - -// UpdateMyAddressJSONBody defines parameters for UpdateMyAddress. -type UpdateMyAddressJSONBody = map[string]interface{} - -// StartAppleLinkJSONBody defines parameters for StartAppleLink. -type StartAppleLinkJSONBody = map[string]interface{} - -// StartGoogleLinkJSONBody defines parameters for StartGoogleLink. -type StartGoogleLinkJSONBody = map[string]interface{} - -// UpdateMyBillingProfileJSONBody defines parameters for UpdateMyBillingProfile. -type UpdateMyBillingProfileJSONBody = map[string]interface{} - -// EmailChangeStartJSONBody defines parameters for EmailChangeStart. -type EmailChangeStartJSONBody = map[string]interface{} - -// EmailChangeVerifyJSONBody defines parameters for EmailChangeVerify. -type EmailChangeVerifyJSONBody = map[string]interface{} - -// EmailVerificationVerifyJSONBody defines parameters for EmailVerificationVerify. -type EmailVerificationVerifyJSONBody = map[string]interface{} - // ListMyEntitlementsParams defines parameters for ListMyEntitlements. type ListMyEntitlementsParams struct { // WorkspaceId Explicit accessible workspace whose grants are merged with the current user's grants. WorkspaceId *WorkspaceIDQuery `form:"workspace_id,omitempty" json:"workspace_id,omitempty"` } -// StartTOTPEnrollmentJSONBody defines parameters for StartTOTPEnrollment. -type StartTOTPEnrollmentJSONBody = map[string]interface{} - -// ActivateTOTPEnrollmentJSONBody defines parameters for ActivateTOTPEnrollment. -type ActivateTOTPEnrollmentJSONBody = map[string]interface{} - -// BeginWebAuthnRegistrationJSONBody defines parameters for BeginWebAuthnRegistration. -type BeginWebAuthnRegistrationJSONBody = map[string]interface{} +// CreateMyStorageUploadParams defines parameters for CreateMyStorageUpload. +type CreateMyStorageUploadParams struct { + IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` +} -// FinishWebAuthnRegistrationJSONBody defines parameters for FinishWebAuthnRegistration. -type FinishWebAuthnRegistrationJSONBody = map[string]interface{} +// SendMachineNotificationParams defines parameters for SendMachineNotification. +type SendMachineNotificationParams struct { + IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` +} -// UpdateMyNotificationPreferenceJSONBody defines parameters for UpdateMyNotificationPreference. -type UpdateMyNotificationPreferenceJSONBody = map[string]interface{} +// ListPermissionGrantsParams defines parameters for ListPermissionGrants. +type ListPermissionGrantsParams struct { + SubjectType *OptionalPermissionSubjectType `form:"subject_type,omitempty" json:"subject_type,omitempty"` + SubjectId *OptionalPermissionSubjectID `form:"subject_id,omitempty" json:"subject_id,omitempty"` -// PasswordChangeJSONBody defines parameters for PasswordChange. -type PasswordChangeJSONBody = map[string]interface{} + // WorkspaceId Explicit accessible workspace whose grants are merged with the current user's grants. + WorkspaceId *WorkspaceIDQuery `form:"workspace_id,omitempty" json:"workspace_id,omitempty"` + Status *PermissionGrantStatus `form:"status,omitempty" json:"status,omitempty"` +} -// CheckMyPermissionsJSONBody defines parameters for CheckMyPermissions. -type CheckMyPermissionsJSONBody = map[string]interface{} +// CreatePermissionGrantParams defines parameters for CreatePermissionGrant. +type CreatePermissionGrantParams struct { + SubjectType *OptionalPermissionSubjectType `form:"subject_type,omitempty" json:"subject_type,omitempty"` + SubjectId *OptionalPermissionSubjectID `form:"subject_id,omitempty" json:"subject_id,omitempty"` -// CreateMyStorageUploadParams defines parameters for CreateMyStorageUpload. -type CreateMyStorageUploadParams struct { + // WorkspaceId Explicit accessible workspace whose grants are merged with the current user's grants. + WorkspaceId *WorkspaceIDQuery `form:"workspace_id,omitempty" json:"workspace_id,omitempty"` + Status *PermissionGrantStatus `form:"status,omitempty" json:"status,omitempty"` IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` } -// AcceptMyWorkspaceInvitationJSONBody defines parameters for AcceptMyWorkspaceInvitation. -type AcceptMyWorkspaceInvitationJSONBody = map[string]interface{} +// GetEffectiveAccessParams defines parameters for GetEffectiveAccess. +type GetEffectiveAccessParams struct { + SubjectType PermissionSubjectType `form:"subject_type" json:"subject_type"` + SubjectId PermissionSubjectID `form:"subject_id" json:"subject_id"` + + // WorkspaceId Explicit accessible workspace whose grants are merged with the current user's grants. + WorkspaceId *WorkspaceIDQuery `form:"workspace_id,omitempty" json:"workspace_id,omitempty"` +} -// CreateMyWorkspaceJSONBody defines parameters for CreateMyWorkspace. -type CreateMyWorkspaceJSONBody = map[string]interface{} +// RevokePermissionGrantParams defines parameters for RevokePermissionGrant. +type RevokePermissionGrantParams struct { + // IfMatch Current resource ETag. + IfMatch IfMatch `json:"If-Match"` +} // CreateApplicationStorageUploadParams defines parameters for CreateApplicationStorageUpload. type CreateApplicationStorageUploadParams struct { IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` } -// UpdateMyWorkspaceJSONBody defines parameters for UpdateMyWorkspace. -type UpdateMyWorkspaceJSONBody = map[string]interface{} - -// CreateWorkspaceAddressJSONBody defines parameters for CreateWorkspaceAddress. -type CreateWorkspaceAddressJSONBody = map[string]interface{} - -// UpdateWorkspaceAddressJSONBody defines parameters for UpdateWorkspaceAddress. -type UpdateWorkspaceAddressJSONBody = map[string]interface{} - -// UpdateWorkspaceBillingProfileJSONBody defines parameters for UpdateWorkspaceBillingProfile. -type UpdateWorkspaceBillingProfileJSONBody = map[string]interface{} +// ListWorkspacePermissionGrantsParams defines parameters for ListWorkspacePermissionGrants. +type ListWorkspacePermissionGrantsParams struct { + SubjectType *OptionalPermissionSubjectType `form:"subject_type,omitempty" json:"subject_type,omitempty"` + SubjectId *OptionalPermissionSubjectID `form:"subject_id,omitempty" json:"subject_id,omitempty"` + Status *PermissionGrantStatus `form:"status,omitempty" json:"status,omitempty"` +} -// CreateMyWorkspaceInvitationJSONBody defines parameters for CreateMyWorkspaceInvitation. -type CreateMyWorkspaceInvitationJSONBody = map[string]interface{} +// CreateWorkspacePermissionGrantParams defines parameters for CreateWorkspacePermissionGrant. +type CreateWorkspacePermissionGrantParams struct { + SubjectType *OptionalPermissionSubjectType `form:"subject_type,omitempty" json:"subject_type,omitempty"` + SubjectId *OptionalPermissionSubjectID `form:"subject_id,omitempty" json:"subject_id,omitempty"` + Status *PermissionGrantStatus `form:"status,omitempty" json:"status,omitempty"` + IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` +} -// ReplaceMyWorkspaceMemberRolesJSONBody defines parameters for ReplaceMyWorkspaceMemberRoles. -type ReplaceMyWorkspaceMemberRolesJSONBody = map[string]interface{} +// RevokeWorkspacePermissionGrantParams defines parameters for RevokeWorkspacePermissionGrant. +type RevokeWorkspacePermissionGrantParams struct { + // IfMatch Current resource ETag. + IfMatch IfMatch `json:"If-Match"` +} // CreateWorkspaceStorageUploadParams defines parameters for CreateWorkspaceStorageUpload. type CreateWorkspaceStorageUploadParams struct { IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` } -// CreateAuditExportJSONBody defines parameters for CreateAuditExport. -type CreateAuditExportJSONBody = map[string]interface{} - -// ConfigureAppleProviderJSONBody defines parameters for ConfigureAppleProvider. -type ConfigureAppleProviderJSONBody = map[string]interface{} - -// ConfigureGoogleProviderJSONBody defines parameters for ConfigureGoogleProvider. -type ConfigureGoogleProviderJSONBody = map[string]interface{} - -// CreateRefundJSONBody defines parameters for CreateRefund. -type CreateRefundJSONBody = map[string]interface{} +// AppleAuthCallbackFormdataBody defines parameters for AppleAuthCallback. +type AppleAuthCallbackFormdataBody struct { + Code *string `form:"code,omitempty" json:"code,omitempty"` + Error *string `form:"error,omitempty" json:"error,omitempty"` + State *string `form:"state,omitempty" json:"state,omitempty"` + User *string `form:"user,omitempty" json:"user,omitempty"` +} // CreateRefundParams defines parameters for CreateRefund. type CreateRefundParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// UpdateBillingProviderJSONBody defines parameters for UpdateBillingProvider. -type UpdateBillingProviderJSONBody = map[string]interface{} - // CreateBillingReconciliationRunParams defines parameters for CreateBillingReconciliationRun. type CreateBillingReconciliationRunParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` @@ -1250,20 +3520,11 @@ type GetBillingStatisticsParams struct { To *time.Time `form:"to,omitempty" json:"to,omitempty"` } -// CancelSubscriptionJSONBody defines parameters for CancelSubscription. -type CancelSubscriptionJSONBody = map[string]interface{} - // CancelSubscriptionParams defines parameters for CancelSubscription. type CancelSubscriptionParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// ChangeSubscriptionPriceJSONBody defines parameters for ChangeSubscriptionPrice. -type ChangeSubscriptionPriceJSONBody struct { - PriceId UUID `json:"price_id"` - ProrationBehavior interface{} `json:"proration_behavior,omitempty"` -} - // ChangeSubscriptionPriceParams defines parameters for ChangeSubscriptionPrice. type ChangeSubscriptionPriceParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` @@ -1274,36 +3535,6 @@ type ResumeSubscriptionParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// CreateClientJSONBody defines parameters for CreateClient. -type CreateClientJSONBody = map[string]interface{} - -// UpdateClientJSONBody defines parameters for UpdateClient. -type UpdateClientJSONBody = map[string]interface{} - -// CreateDelegationJSONBody defines parameters for CreateDelegation. -type CreateDelegationJSONBody = map[string]interface{} - -// CreateApplicationDomainJSONBody defines parameters for CreateApplicationDomain. -type CreateApplicationDomainJSONBody = map[string]interface{} - -// CreateEntitlementJSONBody defines parameters for CreateEntitlement. -type CreateEntitlementJSONBody = map[string]interface{} - -// RestoreEntitlementJSONBody defines parameters for RestoreEntitlement. -type RestoreEntitlementJSONBody = map[string]interface{} - -// RevokeEntitlementJSONBody defines parameters for RevokeEntitlement. -type RevokeEntitlementJSONBody = map[string]interface{} - -// ApproveLocalEntitlementRequestJSONBody defines parameters for ApproveLocalEntitlementRequest. -type ApproveLocalEntitlementRequestJSONBody = map[string]interface{} - -// RejectLocalEntitlementRequestJSONBody defines parameters for RejectLocalEntitlementRequest. -type RejectLocalEntitlementRequestJSONBody = map[string]interface{} - -// ReopenLocalEntitlementRequestJSONBody defines parameters for ReopenLocalEntitlementRequest. -type ReopenLocalEntitlementRequestJSONBody = map[string]interface{} - // CreateNotificationProviderJSONBody defines parameters for CreateNotificationProvider. type CreateNotificationProviderJSONBody struct { Host string `json:"host"` @@ -1317,42 +3548,55 @@ type CreateNotificationProviderJSONBody struct { Username *string `json:"username,omitempty"` } -// UpdateNotificationProviderJSONBody defines parameters for UpdateNotificationProvider. -type UpdateNotificationProviderJSONBody = map[string]interface{} - -// TestNotificationProviderJSONBody defines parameters for TestNotificationProvider. -type TestNotificationProviderJSONBody = map[string]interface{} - // TestNotificationProviderParams defines parameters for TestNotificationProvider. type TestNotificationProviderParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// CreateNotificationTemplateJSONBody defines parameters for CreateNotificationTemplate. -type CreateNotificationTemplateJSONBody = map[string]interface{} +// ListControlPermissionGrantsParams defines parameters for ListControlPermissionGrants. +type ListControlPermissionGrantsParams struct { + SubjectType *OptionalPermissionSubjectType `form:"subject_type,omitempty" json:"subject_type,omitempty"` + SubjectId *OptionalPermissionSubjectID `form:"subject_id,omitempty" json:"subject_id,omitempty"` -// UpdateNotificationTemplateJSONBody defines parameters for UpdateNotificationTemplate. -type UpdateNotificationTemplateJSONBody = map[string]interface{} + // WorkspaceId Explicit accessible workspace whose grants are merged with the current user's grants. + WorkspaceId *WorkspaceIDQuery `form:"workspace_id,omitempty" json:"workspace_id,omitempty"` + Status *PermissionGrantStatus `form:"status,omitempty" json:"status,omitempty"` +} -// PreviewNotificationTemplateJSONBody defines parameters for PreviewNotificationTemplate. -type PreviewNotificationTemplateJSONBody = map[string]interface{} +// CreateControlPermissionGrantParams defines parameters for CreateControlPermissionGrant. +type CreateControlPermissionGrantParams struct { + SubjectType *OptionalPermissionSubjectType `form:"subject_type,omitempty" json:"subject_type,omitempty"` + SubjectId *OptionalPermissionSubjectID `form:"subject_id,omitempty" json:"subject_id,omitempty"` -// QueueNotificationParams defines parameters for QueueNotification. -type QueueNotificationParams struct { - IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` + // WorkspaceId Explicit accessible workspace whose grants are merged with the current user's grants. + WorkspaceId *WorkspaceIDQuery `form:"workspace_id,omitempty" json:"workspace_id,omitempty"` + Status *PermissionGrantStatus `form:"status,omitempty" json:"status,omitempty"` + IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` } -// UpdatePublicApplicationConfigJSONBody defines parameters for UpdatePublicApplicationConfig. -type UpdatePublicApplicationConfigJSONBody map[string]interface{} +// GetControlEffectiveAccessParams defines parameters for GetControlEffectiveAccess. +type GetControlEffectiveAccessParams struct { + SubjectType PermissionSubjectType `form:"subject_type" json:"subject_type"` + SubjectId PermissionSubjectID `form:"subject_id" json:"subject_id"` -// CreateRoleJSONBody defines parameters for CreateRole. -type CreateRoleJSONBody = map[string]interface{} + // WorkspaceId Explicit accessible workspace whose grants are merged with the current user's grants. + WorkspaceId *WorkspaceIDQuery `form:"workspace_id,omitempty" json:"workspace_id,omitempty"` +} + +// RevokeControlPermissionGrantParams defines parameters for RevokeControlPermissionGrant. +type RevokeControlPermissionGrantParams struct { + // IfMatch Current resource ETag. + IfMatch IfMatch `json:"If-Match"` +} -// UpdateRoleJSONBody defines parameters for UpdateRole. -type UpdateRoleJSONBody = map[string]interface{} +// UpdatePublicApplicationConfigJSONBody defines parameters for UpdatePublicApplicationConfig. +type UpdatePublicApplicationConfigJSONBody map[string]interface{} -// CreateSenderIdentityJSONBody defines parameters for CreateSenderIdentity. -type CreateSenderIdentityJSONBody = map[string]interface{} +// UpdateRoleParams defines parameters for UpdateRole. +type UpdateRoleParams struct { + // IfMatch Current resource ETag. + IfMatch IfMatch `json:"If-Match"` +} // DeleteControlApplicationStorageObjectParams defines parameters for DeleteControlApplicationStorageObject. type DeleteControlApplicationStorageObjectParams struct { @@ -1366,89 +3610,16 @@ type DisableApplicationStorageProviderParams struct { ConfirmAffectedObjects *ConfirmAffectedObjects `form:"confirm_affected_objects,omitempty" json:"confirm_affected_objects,omitempty"` } -// UpdateApplicationStorageProviderJSONBody defines parameters for UpdateApplicationStorageProvider. -type UpdateApplicationStorageProviderJSONBody = map[string]interface{} - // CreateControlApplicationStorageUploadParams defines parameters for CreateControlApplicationStorageUpload. type CreateControlApplicationStorageUploadParams struct { IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` } -// CreateUserJSONBody defines parameters for CreateUser. -type CreateUserJSONBody = map[string]interface{} - -// UpdateUserJSONBody defines parameters for UpdateUser. -type UpdateUserJSONBody = map[string]interface{} - -// RestoreUserJSONBody defines parameters for RestoreUser. -type RestoreUserJSONBody = map[string]interface{} - -// SuspendUserJSONBody defines parameters for SuspendUser. -type SuspendUserJSONBody = map[string]interface{} - -// UnverifyUserEmailJSONBody defines parameters for UnverifyUserEmail. -type UnverifyUserEmailJSONBody = map[string]interface{} - -// UnverifyUserOrganizationJSONBody defines parameters for UnverifyUserOrganization. -type UnverifyUserOrganizationJSONBody = map[string]interface{} - -// VerifyUserEmailJSONBody defines parameters for VerifyUserEmail. -type VerifyUserEmailJSONBody = map[string]interface{} - -// VerifyUserOrganizationJSONBody defines parameters for VerifyUserOrganization. -type VerifyUserOrganizationJSONBody = map[string]interface{} - -// CreateWebhookJSONBody defines parameters for CreateWebhook. -type CreateWebhookJSONBody = map[string]interface{} - -// UpdateWebhookJSONBody defines parameters for UpdateWebhook. -type UpdateWebhookJSONBody = map[string]interface{} - // TestWebhookParams defines parameters for TestWebhook. type TestWebhookParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// CreateWorkspaceInvitationJSONBody defines parameters for CreateWorkspaceInvitation. -type CreateWorkspaceInvitationJSONBody = map[string]interface{} - -// CreateWorkspaceJSONBody defines parameters for CreateWorkspace. -type CreateWorkspaceJSONBody = map[string]interface{} - -// UpdateWorkspaceJSONBody defines parameters for UpdateWorkspace. -type UpdateWorkspaceJSONBody = map[string]interface{} - -// ReplaceWorkspaceMemberRolesJSONBody defines parameters for ReplaceWorkspaceMemberRoles. -type ReplaceWorkspaceMemberRolesJSONBody = map[string]interface{} - -// StartOperatorEmailLoginJSONBody defines parameters for StartOperatorEmailLogin. -type StartOperatorEmailLoginJSONBody struct { - Delivery interface{} `json:"delivery,omitempty"` - Email openapi_types.Email `json:"email"` -} - -// UpdateOperatorAccountJSONBody defines parameters for UpdateOperatorAccount. -type UpdateOperatorAccountJSONBody struct { - DisplayName string `json:"display_name"` -} - -// UpdateInstallationAuthProviderJSONBody defines parameters for UpdateInstallationAuthProvider. -type UpdateInstallationAuthProviderJSONBody struct { - // Inheritable Allow child scopes to resolve this provider. - Inheritable bool `json:"inheritable"` -} - -// ConfigureInstallationAuthProviderJSONBody defines parameters for ConfigureInstallationAuthProvider. -type ConfigureInstallationAuthProviderJSONBody = map[string]interface{} - -// UpdateInstallationBillingProviderJSONBody defines parameters for UpdateInstallationBillingProvider. -type UpdateInstallationBillingProviderJSONBody = map[string]interface{} - -// UpdateManagementAPIStatusJSONBody defines parameters for UpdateManagementAPIStatus. -type UpdateManagementAPIStatusJSONBody struct { - Enabled bool `json:"enabled"` -} - // CreateInstallationNotificationProviderJSONBody defines parameters for CreateInstallationNotificationProvider. type CreateInstallationNotificationProviderJSONBody struct { Host string `json:"host"` @@ -1462,32 +3633,11 @@ type CreateInstallationNotificationProviderJSONBody struct { Username *string `json:"username,omitempty"` } -// UpdateInstallationNotificationProviderJSONBody defines parameters for UpdateInstallationNotificationProvider. -type UpdateInstallationNotificationProviderJSONBody = map[string]interface{} - -// TestInstallationNotificationProviderJSONBody defines parameters for TestInstallationNotificationProvider. -type TestInstallationNotificationProviderJSONBody = map[string]interface{} - // TestInstallationNotificationProviderParams defines parameters for TestInstallationNotificationProvider. type TestInstallationNotificationProviderParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` } -// CreateInstallationNotificationTemplateJSONBody defines parameters for CreateInstallationNotificationTemplate. -type CreateInstallationNotificationTemplateJSONBody = map[string]interface{} - -// UpdateInstallationNotificationTemplateJSONBody defines parameters for UpdateInstallationNotificationTemplate. -type UpdateInstallationNotificationTemplateJSONBody = map[string]interface{} - -// PreviewInstallationNotificationTemplateJSONBody defines parameters for PreviewInstallationNotificationTemplate. -type PreviewInstallationNotificationTemplateJSONBody = map[string]interface{} - -// CreateInstallationOperatorJSONBody defines parameters for CreateInstallationOperator. -type CreateInstallationOperatorJSONBody = map[string]interface{} - -// UpdateInstallationOperatorJSONBody defines parameters for UpdateInstallationOperator. -type UpdateInstallationOperatorJSONBody = map[string]interface{} - // UpdateOrganizationPolicyParams defines parameters for UpdateOrganizationPolicy. type UpdateOrganizationPolicyParams struct { // IfMatch Current resource ETag. @@ -1506,9 +3656,6 @@ type DisableInstallationStorageProviderParams struct { ConfirmAffectedObjects *ConfirmAffectedObjects `form:"confirm_affected_objects,omitempty" json:"confirm_affected_objects,omitempty"` } -// UpdateInstallationStorageProviderJSONBody defines parameters for UpdateInstallationStorageProvider. -type UpdateInstallationStorageProviderJSONBody = map[string]interface{} - // CreateInstallationStorageUploadParams defines parameters for CreateInstallationStorageUpload. type CreateInstallationStorageUploadParams struct { IdempotencyKey RequiredIdempotencyKey `json:"Idempotency-Key"` @@ -1552,18 +3699,6 @@ type UpdateOrganizationAuthProviderJSONBody struct { Inheritable bool `json:"inheritable"` } -// ConfigureOrganizationAuthProviderJSONBody defines parameters for ConfigureOrganizationAuthProvider. -type ConfigureOrganizationAuthProviderJSONBody = map[string]interface{} - -// UpdateOrganizationBillingProviderJSONBody defines parameters for UpdateOrganizationBillingProvider. -type UpdateOrganizationBillingProviderJSONBody = map[string]interface{} - -// CreateOrganizationInvitationJSONBody defines parameters for CreateOrganizationInvitation. -type CreateOrganizationInvitationJSONBody = map[string]interface{} - -// UpdateOrganizationMemberJSONBody defines parameters for UpdateOrganizationMember. -type UpdateOrganizationMemberJSONBody = map[string]interface{} - // CreateOrganizationNotificationProviderJSONBody defines parameters for CreateOrganizationNotificationProvider. type CreateOrganizationNotificationProviderJSONBody struct { Host string `json:"host"` @@ -1577,12 +3712,6 @@ type CreateOrganizationNotificationProviderJSONBody struct { Username *string `json:"username,omitempty"` } -// UpdateOrganizationNotificationProviderJSONBody defines parameters for UpdateOrganizationNotificationProvider. -type UpdateOrganizationNotificationProviderJSONBody = map[string]interface{} - -// TestOrganizationNotificationProviderJSONBody defines parameters for TestOrganizationNotificationProvider. -type TestOrganizationNotificationProviderJSONBody = map[string]interface{} - // TestOrganizationNotificationProviderParams defines parameters for TestOrganizationNotificationProvider. type TestOrganizationNotificationProviderParams struct { IdempotencyKey *IdempotencyKey `json:"Idempotency-Key,omitempty"` @@ -1600,9 +3729,6 @@ type DisableOrganizationStorageProviderParams struct { ConfirmAffectedObjects *ConfirmAffectedObjects `form:"confirm_affected_objects,omitempty" json:"confirm_affected_objects,omitempty"` } -// UpdateOrganizationStorageProviderJSONBody defines parameters for UpdateOrganizationStorageProvider. -type UpdateOrganizationStorageProviderJSONBody = map[string]interface{} - // ManagementListOrganizationsParams defines parameters for ManagementListOrganizations. type ManagementListOrganizationsParams struct { IncludeRetired *IncludeRetired `form:"include_retired,omitempty" json:"include_retired,omitempty"` @@ -1687,23 +3813,26 @@ type EmailStartJSONRequestBody = EmailStart // EmailVerifyJSONRequestBody defines body for EmailVerify for application/json ContentType. type EmailVerifyJSONRequestBody = EmailVerify -// AuthMethodsJSONRequestBody defines body for AuthMethods for application/json ContentType. -type AuthMethodsJSONRequestBody = AuthMethodsJSONBody +// ExchangeApplicationInvitationJSONRequestBody defines body for ExchangeApplicationInvitation for application/json ContentType. +type ExchangeApplicationInvitationJSONRequestBody = ExchangeInvitation + +// RedeemApplicationInvitationJSONRequestBody defines body for RedeemApplicationInvitation for application/json ContentType. +type RedeemApplicationInvitationJSONRequestBody = RedeemInvitation // VerifyMFAJSONRequestBody defines body for VerifyMFA for application/json ContentType. -type VerifyMFAJSONRequestBody = VerifyMFAJSONBody +type VerifyMFAJSONRequestBody = VerifyMFA // BeginWebAuthnAuthenticationJSONRequestBody defines body for BeginWebAuthnAuthentication for application/json ContentType. -type BeginWebAuthnAuthenticationJSONRequestBody = BeginWebAuthnAuthenticationJSONBody +type BeginWebAuthnAuthenticationJSONRequestBody = BeginWebAuthnAuthentication // FinishWebAuthnAuthenticationJSONRequestBody defines body for FinishWebAuthnAuthentication for application/json ContentType. -type FinishWebAuthnAuthenticationJSONRequestBody = FinishWebAuthnAuthenticationJSONBody +type FinishWebAuthnAuthenticationJSONRequestBody = FinishWebAuthnCeremony // PasswordResetStartJSONRequestBody defines body for PasswordResetStart for application/json ContentType. -type PasswordResetStartJSONRequestBody = PasswordResetStartJSONBody +type PasswordResetStartJSONRequestBody = PasswordResetStart // PasswordResetVerifyJSONRequestBody defines body for PasswordResetVerify for application/json ContentType. -type PasswordResetVerifyJSONRequestBody = PasswordResetVerifyJSONBody +type PasswordResetVerifyJSONRequestBody = PasswordResetVerify // PasswordSignInJSONRequestBody defines body for PasswordSignIn for application/json ContentType. type PasswordSignInJSONRequestBody = PasswordSignIn @@ -1711,36 +3840,36 @@ type PasswordSignInJSONRequestBody = PasswordSignIn // PasswordSignUpJSONRequestBody defines body for PasswordSignUp for application/json ContentType. type PasswordSignUpJSONRequestBody = PasswordSignUp -// AppleAuthCallbackFormdataRequestBody defines body for AppleAuthCallback for application/x-www-form-urlencoded ContentType. -type AppleAuthCallbackFormdataRequestBody AppleAuthCallbackFormdataBody - // ExchangeAppleAuthJSONRequestBody defines body for ExchangeAppleAuth for application/json ContentType. -type ExchangeAppleAuthJSONRequestBody = ExchangeAppleAuthJSONBody +type ExchangeAppleAuthJSONRequestBody = ExternalAuthExchange // StartAppleAuthJSONRequestBody defines body for StartAppleAuth for application/json ContentType. -type StartAppleAuthJSONRequestBody = StartAppleAuthJSONBody +type StartAppleAuthJSONRequestBody = ExternalAuthStartRequest // ExchangeGoogleAuthJSONRequestBody defines body for ExchangeGoogleAuth for application/json ContentType. -type ExchangeGoogleAuthJSONRequestBody = ExchangeGoogleAuthJSONBody +type ExchangeGoogleAuthJSONRequestBody = ExternalAuthExchange // StartGoogleAuthJSONRequestBody defines body for StartGoogleAuth for application/json ContentType. -type StartGoogleAuthJSONRequestBody = StartGoogleAuthJSONBody +type StartGoogleAuthJSONRequestBody = ExternalAuthStartRequest // RefreshJSONRequestBody defines body for Refresh for application/json ContentType. -type RefreshJSONRequestBody RefreshJSONBody +type RefreshJSONRequestBody = RefreshToken // CreateCheckoutSessionJSONRequestBody defines body for CreateCheckoutSession for application/json ContentType. type CreateCheckoutSessionJSONRequestBody = CreateCheckout // CreateBillingPortalSessionJSONRequestBody defines body for CreateBillingPortalSession for application/json ContentType. -type CreateBillingPortalSessionJSONRequestBody = CreateBillingPortalSessionJSONBody +type CreateBillingPortalSessionJSONRequestBody = CreatePortalSession // ExchangeDelegationJSONRequestBody defines body for ExchangeDelegation for application/json ContentType. -type ExchangeDelegationJSONRequestBody = ExchangeDelegationJSONBody +type ExchangeDelegationJSONRequestBody = ExchangeDelegation // PublishCustomEventJSONRequestBody defines body for PublishCustomEvent for application/json ContentType. type PublishCustomEventJSONRequestBody = PublishCustomEvent +// CreateApplicationInvitationMachineJSONRequestBody defines body for CreateApplicationInvitationMachine for application/json ContentType. +type CreateApplicationInvitationMachineJSONRequestBody = CreateInvitation + // LocalEntitlementCheckoutJSONRequestBody defines body for LocalEntitlementCheckout for application/json ContentType. type LocalEntitlementCheckoutJSONRequestBody = LocalCheckout @@ -1748,136 +3877,148 @@ type LocalEntitlementCheckoutJSONRequestBody = LocalCheckout type UpdateCurrentUserJSONRequestBody = UpdateUserProfile // CreateMyAddressJSONRequestBody defines body for CreateMyAddress for application/json ContentType. -type CreateMyAddressJSONRequestBody = CreateMyAddressJSONBody +type CreateMyAddressJSONRequestBody = CreateAddress // UpdateMyAddressJSONRequestBody defines body for UpdateMyAddress for application/json ContentType. -type UpdateMyAddressJSONRequestBody = UpdateMyAddressJSONBody +type UpdateMyAddressJSONRequestBody = UpdateAddress // CreatePersonalAPIKeyJSONRequestBody defines body for CreatePersonalAPIKey for application/json ContentType. type CreatePersonalAPIKeyJSONRequestBody = CreatePersonalAPIKey // StartAppleLinkJSONRequestBody defines body for StartAppleLink for application/json ContentType. -type StartAppleLinkJSONRequestBody = StartAppleLinkJSONBody +type StartAppleLinkJSONRequestBody = ExternalAuthStartRequest // StartGoogleLinkJSONRequestBody defines body for StartGoogleLink for application/json ContentType. -type StartGoogleLinkJSONRequestBody = StartGoogleLinkJSONBody +type StartGoogleLinkJSONRequestBody = ExternalAuthStartRequest // UpdateMyBillingProfileJSONRequestBody defines body for UpdateMyBillingProfile for application/json ContentType. -type UpdateMyBillingProfileJSONRequestBody = UpdateMyBillingProfileJSONBody +type UpdateMyBillingProfileJSONRequestBody = UpdateBillingProfile // EmailChangeStartJSONRequestBody defines body for EmailChangeStart for application/json ContentType. -type EmailChangeStartJSONRequestBody = EmailChangeStartJSONBody +type EmailChangeStartJSONRequestBody = EmailAddress // EmailChangeVerifyJSONRequestBody defines body for EmailChangeVerify for application/json ContentType. -type EmailChangeVerifyJSONRequestBody = EmailChangeVerifyJSONBody +type EmailChangeVerifyJSONRequestBody = AccountChallenge // EmailVerificationVerifyJSONRequestBody defines body for EmailVerificationVerify for application/json ContentType. -type EmailVerificationVerifyJSONRequestBody = EmailVerificationVerifyJSONBody +type EmailVerificationVerifyJSONRequestBody = AccountChallenge // StartTOTPEnrollmentJSONRequestBody defines body for StartTOTPEnrollment for application/json ContentType. -type StartTOTPEnrollmentJSONRequestBody = StartTOTPEnrollmentJSONBody +type StartTOTPEnrollmentJSONRequestBody = StartTOTP // ActivateTOTPEnrollmentJSONRequestBody defines body for ActivateTOTPEnrollment for application/json ContentType. -type ActivateTOTPEnrollmentJSONRequestBody = ActivateTOTPEnrollmentJSONBody +type ActivateTOTPEnrollmentJSONRequestBody = ActivateTOTP // BeginWebAuthnRegistrationJSONRequestBody defines body for BeginWebAuthnRegistration for application/json ContentType. -type BeginWebAuthnRegistrationJSONRequestBody = BeginWebAuthnRegistrationJSONBody +type BeginWebAuthnRegistrationJSONRequestBody = BeginWebAuthnRegistration // FinishWebAuthnRegistrationJSONRequestBody defines body for FinishWebAuthnRegistration for application/json ContentType. -type FinishWebAuthnRegistrationJSONRequestBody = FinishWebAuthnRegistrationJSONBody +type FinishWebAuthnRegistrationJSONRequestBody = FinishWebAuthnCeremony // UpdateMyNotificationPreferenceJSONRequestBody defines body for UpdateMyNotificationPreference for application/json ContentType. -type UpdateMyNotificationPreferenceJSONRequestBody = UpdateMyNotificationPreferenceJSONBody +type UpdateMyNotificationPreferenceJSONRequestBody = UpdateNotificationPreference // PasswordChangeJSONRequestBody defines body for PasswordChange for application/json ContentType. -type PasswordChangeJSONRequestBody = PasswordChangeJSONBody +type PasswordChangeJSONRequestBody = PasswordChange // CheckMyPermissionsJSONRequestBody defines body for CheckMyPermissions for application/json ContentType. -type CheckMyPermissionsJSONRequestBody = CheckMyPermissionsJSONBody +type CheckMyPermissionsJSONRequestBody = PermissionCheck // CreateMyStorageUploadJSONRequestBody defines body for CreateMyStorageUpload for application/json ContentType. type CreateMyStorageUploadJSONRequestBody = CreateStorageUpload -// AcceptMyWorkspaceInvitationJSONRequestBody defines body for AcceptMyWorkspaceInvitation for application/json ContentType. -type AcceptMyWorkspaceInvitationJSONRequestBody = AcceptMyWorkspaceInvitationJSONBody - // CreateMyWorkspaceJSONRequestBody defines body for CreateMyWorkspace for application/json ContentType. -type CreateMyWorkspaceJSONRequestBody = CreateMyWorkspaceJSONBody +type CreateMyWorkspaceJSONRequestBody = CreateWorkspace + +// SendMachineNotificationJSONRequestBody defines body for SendMachineNotification for application/json ContentType. +type SendMachineNotificationJSONRequestBody = QueueNotification + +// CreatePermissionGrantJSONRequestBody defines body for CreatePermissionGrant for application/json ContentType. +type CreatePermissionGrantJSONRequestBody = CreatePermissionGrant // CreateApplicationStorageUploadJSONRequestBody defines body for CreateApplicationStorageUpload for application/json ContentType. type CreateApplicationStorageUploadJSONRequestBody = CreateStorageUpload // UpdateMyWorkspaceJSONRequestBody defines body for UpdateMyWorkspace for application/json ContentType. -type UpdateMyWorkspaceJSONRequestBody = UpdateMyWorkspaceJSONBody +type UpdateMyWorkspaceJSONRequestBody = UpdateWorkspace // CreateWorkspaceAddressJSONRequestBody defines body for CreateWorkspaceAddress for application/json ContentType. -type CreateWorkspaceAddressJSONRequestBody = CreateWorkspaceAddressJSONBody +type CreateWorkspaceAddressJSONRequestBody = CreateAddress // UpdateWorkspaceAddressJSONRequestBody defines body for UpdateWorkspaceAddress for application/json ContentType. -type UpdateWorkspaceAddressJSONRequestBody = UpdateWorkspaceAddressJSONBody +type UpdateWorkspaceAddressJSONRequestBody = UpdateAddress // UpdateWorkspaceBillingProfileJSONRequestBody defines body for UpdateWorkspaceBillingProfile for application/json ContentType. -type UpdateWorkspaceBillingProfileJSONRequestBody = UpdateWorkspaceBillingProfileJSONBody +type UpdateWorkspaceBillingProfileJSONRequestBody = UpdateBillingProfile // CreateMyWorkspaceInvitationJSONRequestBody defines body for CreateMyWorkspaceInvitation for application/json ContentType. -type CreateMyWorkspaceInvitationJSONRequestBody = CreateMyWorkspaceInvitationJSONBody +type CreateMyWorkspaceInvitationJSONRequestBody = CreateInvitation // ReplaceMyWorkspaceMemberRolesJSONRequestBody defines body for ReplaceMyWorkspaceMemberRoles for application/json ContentType. -type ReplaceMyWorkspaceMemberRolesJSONRequestBody = ReplaceMyWorkspaceMemberRolesJSONBody +type ReplaceMyWorkspaceMemberRolesJSONRequestBody = ReplaceWorkspaceMemberRoles // TransferMyWorkspaceOwnershipJSONRequestBody defines body for TransferMyWorkspaceOwnership for application/json ContentType. type TransferMyWorkspaceOwnershipJSONRequestBody = OwnershipTransfer +// CreateWorkspacePermissionGrantJSONRequestBody defines body for CreateWorkspacePermissionGrant for application/json ContentType. +type CreateWorkspacePermissionGrantJSONRequestBody = CreatePermissionGrant + // CreateWorkspaceStorageUploadJSONRequestBody defines body for CreateWorkspaceStorageUpload for application/json ContentType. type CreateWorkspaceStorageUploadJSONRequestBody = CreateStorageUpload +// AppleAuthCallbackFormdataRequestBody defines body for AppleAuthCallback for application/x-www-form-urlencoded ContentType. +type AppleAuthCallbackFormdataRequestBody AppleAuthCallbackFormdataBody + // CreateAuditExportJSONRequestBody defines body for CreateAuditExport for application/json ContentType. -type CreateAuditExportJSONRequestBody = CreateAuditExportJSONBody +type CreateAuditExportJSONRequestBody = AuditExport // UpdateAuthConfigJSONRequestBody defines body for UpdateAuthConfig for application/json ContentType. type UpdateAuthConfigJSONRequestBody = ApplicationAuthConfig // ConfigureAppleProviderJSONRequestBody defines body for ConfigureAppleProvider for application/json ContentType. -type ConfigureAppleProviderJSONRequestBody = ConfigureAppleProviderJSONBody +type ConfigureAppleProviderJSONRequestBody = ConfigureAuthProvider // ConfigureGoogleProviderJSONRequestBody defines body for ConfigureGoogleProvider for application/json ContentType. -type ConfigureGoogleProviderJSONRequestBody = ConfigureGoogleProviderJSONBody +type ConfigureGoogleProviderJSONRequestBody = ConfigureAuthProvider // CreateRefundJSONRequestBody defines body for CreateRefund for application/json ContentType. -type CreateRefundJSONRequestBody = CreateRefundJSONBody +type CreateRefundJSONRequestBody = CreateRefund // CreateBillingProviderJSONRequestBody defines body for CreateBillingProvider for application/json ContentType. type CreateBillingProviderJSONRequestBody = CreateBillingProvider // UpdateBillingProviderJSONRequestBody defines body for UpdateBillingProvider for application/json ContentType. -type UpdateBillingProviderJSONRequestBody = UpdateBillingProviderJSONBody +type UpdateBillingProviderJSONRequestBody = UpdateBillingProvider // CancelSubscriptionJSONRequestBody defines body for CancelSubscription for application/json ContentType. -type CancelSubscriptionJSONRequestBody = CancelSubscriptionJSONBody +type CancelSubscriptionJSONRequestBody = CancelSubscription // ChangeSubscriptionPriceJSONRequestBody defines body for ChangeSubscriptionPrice for application/json ContentType. -type ChangeSubscriptionPriceJSONRequestBody ChangeSubscriptionPriceJSONBody +type ChangeSubscriptionPriceJSONRequestBody = ChangeSubscriptionPrice // CreateClientJSONRequestBody defines body for CreateClient for application/json ContentType. -type CreateClientJSONRequestBody = CreateClientJSONBody +type CreateClientJSONRequestBody = CreateClient // UpdateClientJSONRequestBody defines body for UpdateClient for application/json ContentType. -type UpdateClientJSONRequestBody = UpdateClientJSONBody +type UpdateClientJSONRequestBody = UpdateClient // CreateDelegationJSONRequestBody defines body for CreateDelegation for application/json ContentType. -type CreateDelegationJSONRequestBody = CreateDelegationJSONBody +type CreateDelegationJSONRequestBody = CreateDelegation // CreateApplicationDomainJSONRequestBody defines body for CreateApplicationDomain for application/json ContentType. -type CreateApplicationDomainJSONRequestBody = CreateApplicationDomainJSONBody +type CreateApplicationDomainJSONRequestBody = CreateApplicationDomain // CreateEntitlementJSONRequestBody defines body for CreateEntitlement for application/json ContentType. -type CreateEntitlementJSONRequestBody = CreateEntitlementJSONBody +type CreateEntitlementJSONRequestBody = CreateEntitlement + +// AdjustEntitlementJSONRequestBody defines body for AdjustEntitlement for application/json ContentType. +type AdjustEntitlementJSONRequestBody = AdjustEntitlement // RestoreEntitlementJSONRequestBody defines body for RestoreEntitlement for application/json ContentType. -type RestoreEntitlementJSONRequestBody = RestoreEntitlementJSONBody +type RestoreEntitlementJSONRequestBody = AuditReason // RevokeEntitlementJSONRequestBody defines body for RevokeEntitlement for application/json ContentType. -type RevokeEntitlementJSONRequestBody = RevokeEntitlementJSONBody +type RevokeEntitlementJSONRequestBody = AuditReason // CreateEventTypeJSONRequestBody defines body for CreateEventType for application/json ContentType. type CreateEventTypeJSONRequestBody = CreateEventType @@ -1891,35 +4032,38 @@ type CreateFeatureJSONRequestBody = CreateFeature // UpdateInternalApplicationConfigJSONRequestBody defines body for UpdateInternalApplicationConfig for application/json ContentType. type UpdateInternalApplicationConfigJSONRequestBody = ApplicationInternalConfig +// CreateApplicationInvitationControlJSONRequestBody defines body for CreateApplicationInvitationControl for application/json ContentType. +type CreateApplicationInvitationControlJSONRequestBody = CreateInvitation + // ApproveLocalEntitlementRequestJSONRequestBody defines body for ApproveLocalEntitlementRequest for application/json ContentType. -type ApproveLocalEntitlementRequestJSONRequestBody = ApproveLocalEntitlementRequestJSONBody +type ApproveLocalEntitlementRequestJSONRequestBody = AuditReason // RejectLocalEntitlementRequestJSONRequestBody defines body for RejectLocalEntitlementRequest for application/json ContentType. -type RejectLocalEntitlementRequestJSONRequestBody = RejectLocalEntitlementRequestJSONBody +type RejectLocalEntitlementRequestJSONRequestBody = AuditReason // ReopenLocalEntitlementRequestJSONRequestBody defines body for ReopenLocalEntitlementRequest for application/json ContentType. -type ReopenLocalEntitlementRequestJSONRequestBody = ReopenLocalEntitlementRequestJSONBody +type ReopenLocalEntitlementRequestJSONRequestBody = AuditReason // CreateNotificationProviderJSONRequestBody defines body for CreateNotificationProvider for application/json ContentType. type CreateNotificationProviderJSONRequestBody CreateNotificationProviderJSONBody // UpdateNotificationProviderJSONRequestBody defines body for UpdateNotificationProvider for application/json ContentType. -type UpdateNotificationProviderJSONRequestBody = UpdateNotificationProviderJSONBody +type UpdateNotificationProviderJSONRequestBody = UpdateSMTPProvider // TestNotificationProviderJSONRequestBody defines body for TestNotificationProvider for application/json ContentType. -type TestNotificationProviderJSONRequestBody = TestNotificationProviderJSONBody +type TestNotificationProviderJSONRequestBody = TestNotificationProvider // CreateNotificationTemplateJSONRequestBody defines body for CreateNotificationTemplate for application/json ContentType. -type CreateNotificationTemplateJSONRequestBody = CreateNotificationTemplateJSONBody +type CreateNotificationTemplateJSONRequestBody = CreateNotificationTemplate // UpdateNotificationTemplateJSONRequestBody defines body for UpdateNotificationTemplate for application/json ContentType. -type UpdateNotificationTemplateJSONRequestBody = UpdateNotificationTemplateJSONBody +type UpdateNotificationTemplateJSONRequestBody = UpdateNotificationTemplate // PreviewNotificationTemplateJSONRequestBody defines body for PreviewNotificationTemplate for application/json ContentType. -type PreviewNotificationTemplateJSONRequestBody = PreviewNotificationTemplateJSONBody +type PreviewNotificationTemplateJSONRequestBody = PreviewNotificationTemplate -// QueueNotificationJSONRequestBody defines body for QueueNotification for application/json ContentType. -type QueueNotificationJSONRequestBody = QueueNotification +// CreateControlPermissionGrantJSONRequestBody defines body for CreateControlPermissionGrant for application/json ContentType. +type CreateControlPermissionGrantJSONRequestBody = CreatePermissionGrant // CreateProductJSONRequestBody defines body for CreateProduct for application/json ContentType. type CreateProductJSONRequestBody = CreateProduct @@ -1937,97 +4081,103 @@ type UpdatePublicApplicationConfigJSONRequestBody UpdatePublicApplicationConfigJ type CreateRoleAssignmentJSONRequestBody = RoleAssignment // CreateRoleJSONRequestBody defines body for CreateRole for application/json ContentType. -type CreateRoleJSONRequestBody = CreateRoleJSONBody +type CreateRoleJSONRequestBody = CreateRole // UpdateRoleJSONRequestBody defines body for UpdateRole for application/json ContentType. -type UpdateRoleJSONRequestBody = UpdateRoleJSONBody +type UpdateRoleJSONRequestBody = UpdateRole // CreateSenderIdentityJSONRequestBody defines body for CreateSenderIdentity for application/json ContentType. -type CreateSenderIdentityJSONRequestBody = CreateSenderIdentityJSONBody +type CreateSenderIdentityJSONRequestBody = CreateSenderIdentity // CreateApplicationStorageProviderJSONRequestBody defines body for CreateApplicationStorageProvider for application/json ContentType. type CreateApplicationStorageProviderJSONRequestBody = CreateStorageProvider // UpdateApplicationStorageProviderJSONRequestBody defines body for UpdateApplicationStorageProvider for application/json ContentType. -type UpdateApplicationStorageProviderJSONRequestBody = UpdateApplicationStorageProviderJSONBody +type UpdateApplicationStorageProviderJSONRequestBody = UpdateStorageProvider // CreateControlApplicationStorageUploadJSONRequestBody defines body for CreateControlApplicationStorageUpload for application/json ContentType. type CreateControlApplicationStorageUploadJSONRequestBody = CreateStorageUpload // CreateUserJSONRequestBody defines body for CreateUser for application/json ContentType. -type CreateUserJSONRequestBody = CreateUserJSONBody +type CreateUserJSONRequestBody = CreateUser // UpdateUserJSONRequestBody defines body for UpdateUser for application/json ContentType. -type UpdateUserJSONRequestBody = UpdateUserJSONBody +type UpdateUserJSONRequestBody = UpdateUser // RestoreUserJSONRequestBody defines body for RestoreUser for application/json ContentType. -type RestoreUserJSONRequestBody = RestoreUserJSONBody +type RestoreUserJSONRequestBody = AuditReason // SuspendUserJSONRequestBody defines body for SuspendUser for application/json ContentType. -type SuspendUserJSONRequestBody = SuspendUserJSONBody +type SuspendUserJSONRequestBody = AuditReason // UnverifyUserEmailJSONRequestBody defines body for UnverifyUserEmail for application/json ContentType. -type UnverifyUserEmailJSONRequestBody = UnverifyUserEmailJSONBody +type UnverifyUserEmailJSONRequestBody = AuditReason // UnverifyUserOrganizationJSONRequestBody defines body for UnverifyUserOrganization for application/json ContentType. -type UnverifyUserOrganizationJSONRequestBody = UnverifyUserOrganizationJSONBody +type UnverifyUserOrganizationJSONRequestBody = AuditReason // VerifyUserEmailJSONRequestBody defines body for VerifyUserEmail for application/json ContentType. -type VerifyUserEmailJSONRequestBody = VerifyUserEmailJSONBody +type VerifyUserEmailJSONRequestBody = AuditReason // VerifyUserOrganizationJSONRequestBody defines body for VerifyUserOrganization for application/json ContentType. -type VerifyUserOrganizationJSONRequestBody = VerifyUserOrganizationJSONBody +type VerifyUserOrganizationJSONRequestBody = AuditReason // CreateWebhookJSONRequestBody defines body for CreateWebhook for application/json ContentType. -type CreateWebhookJSONRequestBody = CreateWebhookJSONBody +type CreateWebhookJSONRequestBody = CreateWebhook // UpdateWebhookJSONRequestBody defines body for UpdateWebhook for application/json ContentType. -type UpdateWebhookJSONRequestBody = UpdateWebhookJSONBody - -// CreateWorkspaceInvitationJSONRequestBody defines body for CreateWorkspaceInvitation for application/json ContentType. -type CreateWorkspaceInvitationJSONRequestBody = CreateWorkspaceInvitationJSONBody +type UpdateWebhookJSONRequestBody = UpdateWebhook // CreateWorkspaceJSONRequestBody defines body for CreateWorkspace for application/json ContentType. -type CreateWorkspaceJSONRequestBody = CreateWorkspaceJSONBody +type CreateWorkspaceJSONRequestBody = CreateWorkspace // UpdateWorkspaceJSONRequestBody defines body for UpdateWorkspace for application/json ContentType. -type UpdateWorkspaceJSONRequestBody = UpdateWorkspaceJSONBody +type UpdateWorkspaceJSONRequestBody = UpdateWorkspace // ReplaceWorkspaceMemberRolesJSONRequestBody defines body for ReplaceWorkspaceMemberRoles for application/json ContentType. -type ReplaceWorkspaceMemberRolesJSONRequestBody = ReplaceWorkspaceMemberRolesJSONBody +type ReplaceWorkspaceMemberRolesJSONRequestBody = ReplaceWorkspaceMemberRoles // RecoverWorkspaceOwnershipJSONRequestBody defines body for RecoverWorkspaceOwnership for application/json ContentType. type RecoverWorkspaceOwnershipJSONRequestBody = OwnershipTransfer -// StartOperatorEmailLoginJSONRequestBody defines body for StartOperatorEmailLogin for application/json ContentType. -type StartOperatorEmailLoginJSONRequestBody StartOperatorEmailLoginJSONBody +// StartControlUserEmailLoginJSONRequestBody defines body for StartControlUserEmailLogin for application/json ContentType. +type StartControlUserEmailLoginJSONRequestBody = ControlEmailStart -// VerifyOperatorEmailLoginJSONRequestBody defines body for VerifyOperatorEmailLogin for application/json ContentType. -type VerifyOperatorEmailLoginJSONRequestBody = EmailVerify +// VerifyControlUserEmailLoginJSONRequestBody defines body for VerifyControlUserEmailLogin for application/json ContentType. +type VerifyControlUserEmailLoginJSONRequestBody = EmailVerify -// UpdateOperatorAccountJSONRequestBody defines body for UpdateOperatorAccount for application/json ContentType. -type UpdateOperatorAccountJSONRequestBody UpdateOperatorAccountJSONBody +// UpdateControlUserAccountJSONRequestBody defines body for UpdateControlUserAccount for application/json ContentType. +type UpdateControlUserAccountJSONRequestBody = UpdateControlUserAccount -// LoginOperatorWithPasswordJSONRequestBody defines body for LoginOperatorWithPassword for application/json ContentType. -type LoginOperatorWithPasswordJSONRequestBody = OperatorPasswordLogin +// LoginControlUserWithPasswordJSONRequestBody defines body for LoginControlUserWithPassword for application/json ContentType. +type LoginControlUserWithPasswordJSONRequestBody = ControlUserPasswordLogin -// ChangeOperatorPasswordJSONRequestBody defines body for ChangeOperatorPassword for application/json ContentType. -type ChangeOperatorPasswordJSONRequestBody = OperatorPasswordChange +// ChangeControlUserPasswordJSONRequestBody defines body for ChangeControlUserPassword for application/json ContentType. +type ChangeControlUserPasswordJSONRequestBody = ControlUserPasswordChange + +// UpdateControlAuthPolicyJSONRequestBody defines body for UpdateControlAuthPolicy for application/json ContentType. +type UpdateControlAuthPolicyJSONRequestBody = UpdateControlAuthPolicy // UpdateInstallationAuthProviderJSONRequestBody defines body for UpdateInstallationAuthProvider for application/json ContentType. -type UpdateInstallationAuthProviderJSONRequestBody UpdateInstallationAuthProviderJSONBody +type UpdateInstallationAuthProviderJSONRequestBody = UpdateInstallationAuthProvider // ConfigureInstallationAuthProviderJSONRequestBody defines body for ConfigureInstallationAuthProvider for application/json ContentType. -type ConfigureInstallationAuthProviderJSONRequestBody = ConfigureInstallationAuthProviderJSONBody +type ConfigureInstallationAuthProviderJSONRequestBody = ConfigureAuthProvider // CreateInstallationBillingProviderJSONRequestBody defines body for CreateInstallationBillingProvider for application/json ContentType. type CreateInstallationBillingProviderJSONRequestBody = CreateBillingProvider // UpdateInstallationBillingProviderJSONRequestBody defines body for UpdateInstallationBillingProvider for application/json ContentType. -type UpdateInstallationBillingProviderJSONRequestBody = UpdateInstallationBillingProviderJSONBody +type UpdateInstallationBillingProviderJSONRequestBody = UpdateBillingProvider + +// CreateInstallationControlUserInvitationJSONRequestBody defines body for CreateInstallationControlUserInvitation for application/json ContentType. +type CreateInstallationControlUserInvitationJSONRequestBody = CreateControlUserInvitation + +// ResendInstallationControlUserInvitationJSONRequestBody defines body for ResendInstallationControlUserInvitation for application/json ContentType. +type ResendInstallationControlUserInvitationJSONRequestBody = UpdateControlInvitationMethod // UpdateManagementAPIStatusJSONRequestBody defines body for UpdateManagementAPIStatus for application/json ContentType. -type UpdateManagementAPIStatusJSONRequestBody UpdateManagementAPIStatusJSONBody +type UpdateManagementAPIStatusJSONRequestBody = UpdateManagementAPI // CreateManagementClientJSONRequestBody defines body for CreateManagementClient for application/json ContentType. type CreateManagementClientJSONRequestBody = CreateManagementClient @@ -2036,25 +4186,19 @@ type CreateManagementClientJSONRequestBody = CreateManagementClient type CreateInstallationNotificationProviderJSONRequestBody CreateInstallationNotificationProviderJSONBody // UpdateInstallationNotificationProviderJSONRequestBody defines body for UpdateInstallationNotificationProvider for application/json ContentType. -type UpdateInstallationNotificationProviderJSONRequestBody = UpdateInstallationNotificationProviderJSONBody +type UpdateInstallationNotificationProviderJSONRequestBody = UpdateSMTPProvider // TestInstallationNotificationProviderJSONRequestBody defines body for TestInstallationNotificationProvider for application/json ContentType. -type TestInstallationNotificationProviderJSONRequestBody = TestInstallationNotificationProviderJSONBody +type TestInstallationNotificationProviderJSONRequestBody = TestNotificationProvider // CreateInstallationNotificationTemplateJSONRequestBody defines body for CreateInstallationNotificationTemplate for application/json ContentType. -type CreateInstallationNotificationTemplateJSONRequestBody = CreateInstallationNotificationTemplateJSONBody +type CreateInstallationNotificationTemplateJSONRequestBody = CreateNotificationTemplate // UpdateInstallationNotificationTemplateJSONRequestBody defines body for UpdateInstallationNotificationTemplate for application/json ContentType. -type UpdateInstallationNotificationTemplateJSONRequestBody = UpdateInstallationNotificationTemplateJSONBody +type UpdateInstallationNotificationTemplateJSONRequestBody = UpdateNotificationTemplate // PreviewInstallationNotificationTemplateJSONRequestBody defines body for PreviewInstallationNotificationTemplate for application/json ContentType. -type PreviewInstallationNotificationTemplateJSONRequestBody = PreviewInstallationNotificationTemplateJSONBody - -// CreateInstallationOperatorJSONRequestBody defines body for CreateInstallationOperator for application/json ContentType. -type CreateInstallationOperatorJSONRequestBody = CreateInstallationOperatorJSONBody - -// UpdateInstallationOperatorJSONRequestBody defines body for UpdateInstallationOperator for application/json ContentType. -type UpdateInstallationOperatorJSONRequestBody = UpdateInstallationOperatorJSONBody +type PreviewInstallationNotificationTemplateJSONRequestBody = PreviewNotificationTemplate // UpdateOrganizationPolicyJSONRequestBody defines body for UpdateOrganizationPolicy for application/json ContentType. type UpdateOrganizationPolicyJSONRequestBody = UpdateOrganizationPolicy @@ -2063,13 +4207,19 @@ type UpdateOrganizationPolicyJSONRequestBody = UpdateOrganizationPolicy type CreateInstallationStorageProviderJSONRequestBody = CreateStorageProvider // UpdateInstallationStorageProviderJSONRequestBody defines body for UpdateInstallationStorageProvider for application/json ContentType. -type UpdateInstallationStorageProviderJSONRequestBody = UpdateInstallationStorageProviderJSONBody +type UpdateInstallationStorageProviderJSONRequestBody = UpdateStorageProvider // CreateInstallationStorageUploadJSONRequestBody defines body for CreateInstallationStorageUpload for application/json ContentType. type CreateInstallationStorageUploadJSONRequestBody = CreateStorageUpload -// AcceptOrganizationInvitationJSONRequestBody defines body for AcceptOrganizationInvitation for application/json ContentType. -type AcceptOrganizationInvitationJSONRequestBody = AcceptOrganizationInvitation +// UpdateInstallationControlUserJSONRequestBody defines body for UpdateInstallationControlUser for application/json ContentType. +type UpdateInstallationControlUserJSONRequestBody = MembershipRole + +// AcceptControlUserInvitationJSONRequestBody defines body for AcceptControlUserInvitation for application/json ContentType. +type AcceptControlUserInvitationJSONRequestBody = AcceptControlUserInvitation + +// StartControlInvitationExternalLoginJSONRequestBody defines body for StartControlInvitationExternalLogin for application/json ContentType. +type StartControlInvitationExternalLoginJSONRequestBody = ControlInvitationProviderStart // CreateOrganizationJSONRequestBody defines body for CreateOrganization for application/json ContentType. type CreateOrganizationJSONRequestBody CreateOrganizationJSONBody @@ -2087,34 +4237,34 @@ type UpdateApplicationJSONRequestBody UpdateApplicationJSONBody type UpdateOrganizationAuthProviderJSONRequestBody UpdateOrganizationAuthProviderJSONBody // ConfigureOrganizationAuthProviderJSONRequestBody defines body for ConfigureOrganizationAuthProvider for application/json ContentType. -type ConfigureOrganizationAuthProviderJSONRequestBody = ConfigureOrganizationAuthProviderJSONBody +type ConfigureOrganizationAuthProviderJSONRequestBody = ConfigureAuthProvider // CreateOrganizationBillingProviderJSONRequestBody defines body for CreateOrganizationBillingProvider for application/json ContentType. type CreateOrganizationBillingProviderJSONRequestBody = CreateBillingProvider // UpdateOrganizationBillingProviderJSONRequestBody defines body for UpdateOrganizationBillingProvider for application/json ContentType. -type UpdateOrganizationBillingProviderJSONRequestBody = UpdateOrganizationBillingProviderJSONBody +type UpdateOrganizationBillingProviderJSONRequestBody = UpdateBillingProvider // CreateOrganizationInvitationJSONRequestBody defines body for CreateOrganizationInvitation for application/json ContentType. -type CreateOrganizationInvitationJSONRequestBody = CreateOrganizationInvitationJSONBody +type CreateOrganizationInvitationJSONRequestBody = CreateControlUserInvitation // UpdateOrganizationMemberJSONRequestBody defines body for UpdateOrganizationMember for application/json ContentType. -type UpdateOrganizationMemberJSONRequestBody = UpdateOrganizationMemberJSONBody +type UpdateOrganizationMemberJSONRequestBody = MembershipRole // CreateOrganizationNotificationProviderJSONRequestBody defines body for CreateOrganizationNotificationProvider for application/json ContentType. type CreateOrganizationNotificationProviderJSONRequestBody CreateOrganizationNotificationProviderJSONBody // UpdateOrganizationNotificationProviderJSONRequestBody defines body for UpdateOrganizationNotificationProvider for application/json ContentType. -type UpdateOrganizationNotificationProviderJSONRequestBody = UpdateOrganizationNotificationProviderJSONBody +type UpdateOrganizationNotificationProviderJSONRequestBody = UpdateSMTPProvider // TestOrganizationNotificationProviderJSONRequestBody defines body for TestOrganizationNotificationProvider for application/json ContentType. -type TestOrganizationNotificationProviderJSONRequestBody = TestOrganizationNotificationProviderJSONBody +type TestOrganizationNotificationProviderJSONRequestBody = TestNotificationProvider // CreateOrganizationStorageProviderJSONRequestBody defines body for CreateOrganizationStorageProvider for application/json ContentType. type CreateOrganizationStorageProviderJSONRequestBody = CreateStorageProvider // UpdateOrganizationStorageProviderJSONRequestBody defines body for UpdateOrganizationStorageProvider for application/json ContentType. -type UpdateOrganizationStorageProviderJSONRequestBody = UpdateOrganizationStorageProviderJSONBody +type UpdateOrganizationStorageProviderJSONRequestBody = UpdateStorageProvider // ManagementCreateOrganizationJSONRequestBody defines body for ManagementCreateOrganization for application/json ContentType. type ManagementCreateOrganizationJSONRequestBody ManagementCreateOrganizationJSONBody @@ -2134,6 +4284,9 @@ type ManagementUpdateOrganizationPolicyJSONRequestBody = UpdateOrganizationPolic // BootstrapJSONRequestBody defines body for Bootstrap for application/json ContentType. type BootstrapJSONRequestBody = BootstrapRequest +// CompleteSetupJSONRequestBody defines body for CompleteSetup for application/json ContentType. +type CompleteSetupJSONRequestBody = CompleteSetup + // CreateSetupNotificationProviderJSONRequestBody defines body for CreateSetupNotificationProvider for application/json ContentType. type CreateSetupNotificationProviderJSONRequestBody CreateSetupNotificationProviderJSONBody @@ -2420,6 +4573,156 @@ func (t *CreateStorageProvider) UnmarshalJSON(b []byte) error { return err } +// AsExchangeInvitation0 returns the union data inside the ExchangeInvitation as a ExchangeInvitation0 +func (t ExchangeInvitation) AsExchangeInvitation0() (ExchangeInvitation0, error) { + var body ExchangeInvitation0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExchangeInvitation0 overwrites any union data inside the ExchangeInvitation as the provided ExchangeInvitation0 +func (t *ExchangeInvitation) FromExchangeInvitation0(v ExchangeInvitation0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExchangeInvitation0 performs a merge with any union data inside the ExchangeInvitation, using the provided ExchangeInvitation0 +func (t *ExchangeInvitation) MergeExchangeInvitation0(v ExchangeInvitation0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsExchangeInvitation1 returns the union data inside the ExchangeInvitation as a ExchangeInvitation1 +func (t ExchangeInvitation) AsExchangeInvitation1() (ExchangeInvitation1, error) { + var body ExchangeInvitation1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromExchangeInvitation1 overwrites any union data inside the ExchangeInvitation as the provided ExchangeInvitation1 +func (t *ExchangeInvitation) FromExchangeInvitation1(v ExchangeInvitation1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeExchangeInvitation1 performs a merge with any union data inside the ExchangeInvitation, using the provided ExchangeInvitation1 +func (t *ExchangeInvitation) MergeExchangeInvitation1(v ExchangeInvitation1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t ExchangeInvitation) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + if err != nil { + return nil, err + } + object := make(map[string]json.RawMessage) + if t.union != nil { + err = json.Unmarshal(b, &object) + if err != nil { + return nil, err + } + } + + if t.Code != nil { + object["code"], err = json.Marshal(t.Code) + if err != nil { + return nil, fmt.Errorf("error marshaling 'code': %w", err) + } + } + + object["code_challenge"], err = json.Marshal(t.CodeChallenge) + if err != nil { + return nil, fmt.Errorf("error marshaling 'code_challenge': %w", err) + } + + if t.Email != nil { + object["email"], err = json.Marshal(t.Email) + if err != nil { + return nil, fmt.Errorf("error marshaling 'email': %w", err) + } + } + + if t.InvitationId != nil { + object["invitation_id"], err = json.Marshal(t.InvitationId) + if err != nil { + return nil, fmt.Errorf("error marshaling 'invitation_id': %w", err) + } + } + + if t.LinkToken != nil { + object["link_token"], err = json.Marshal(t.LinkToken) + if err != nil { + return nil, fmt.Errorf("error marshaling 'link_token': %w", err) + } + } + b, err = json.Marshal(object) + return b, err +} + +func (t *ExchangeInvitation) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + if err != nil { + return err + } + object := make(map[string]json.RawMessage) + err = json.Unmarshal(b, &object) + if err != nil { + return err + } + + if raw, found := object["code"]; found { + err = json.Unmarshal(raw, &t.Code) + if err != nil { + return fmt.Errorf("error reading 'code': %w", err) + } + } + + if raw, found := object["code_challenge"]; found { + err = json.Unmarshal(raw, &t.CodeChallenge) + if err != nil { + return fmt.Errorf("error reading 'code_challenge': %w", err) + } + } + + if raw, found := object["email"]; found { + err = json.Unmarshal(raw, &t.Email) + if err != nil { + return fmt.Errorf("error reading 'email': %w", err) + } + } + + if raw, found := object["invitation_id"]; found { + err = json.Unmarshal(raw, &t.InvitationId) + if err != nil { + return fmt.Errorf("error reading 'invitation_id': %w", err) + } + } + + if raw, found := object["link_token"]; found { + err = json.Unmarshal(raw, &t.LinkToken) + if err != nil { + return fmt.Errorf("error reading 'link_token': %w", err) + } + } + + return err +} + // AsRoleAssignment0 returns the union data inside the RoleAssignment as a RoleAssignment0 func (t RoleAssignment) AsRoleAssignment0() (RoleAssignment0, error) { var body RoleAssignment0 @@ -2556,6 +4859,190 @@ func (t *RoleAssignment) UnmarshalJSON(b []byte) error { return err } +// AsTokenIntrospectionAud0 returns the union data inside the TokenIntrospection_Aud as a TokenIntrospectionAud0 +func (t TokenIntrospection_Aud) AsTokenIntrospectionAud0() (TokenIntrospectionAud0, error) { + var body TokenIntrospectionAud0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromTokenIntrospectionAud0 overwrites any union data inside the TokenIntrospection_Aud as the provided TokenIntrospectionAud0 +func (t *TokenIntrospection_Aud) FromTokenIntrospectionAud0(v TokenIntrospectionAud0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeTokenIntrospectionAud0 performs a merge with any union data inside the TokenIntrospection_Aud, using the provided TokenIntrospectionAud0 +func (t *TokenIntrospection_Aud) MergeTokenIntrospectionAud0(v TokenIntrospectionAud0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsTokenIntrospectionAud1 returns the union data inside the TokenIntrospection_Aud as a TokenIntrospectionAud1 +func (t TokenIntrospection_Aud) AsTokenIntrospectionAud1() (TokenIntrospectionAud1, error) { + var body TokenIntrospectionAud1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromTokenIntrospectionAud1 overwrites any union data inside the TokenIntrospection_Aud as the provided TokenIntrospectionAud1 +func (t *TokenIntrospection_Aud) FromTokenIntrospectionAud1(v TokenIntrospectionAud1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeTokenIntrospectionAud1 performs a merge with any union data inside the TokenIntrospection_Aud, using the provided TokenIntrospectionAud1 +func (t *TokenIntrospection_Aud) MergeTokenIntrospectionAud1(v TokenIntrospectionAud1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t TokenIntrospection_Aud) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + return b, err +} + +func (t *TokenIntrospection_Aud) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + return err +} + +// AsVerifyMFA0 returns the union data inside the VerifyMFA as a VerifyMFA0 +func (t VerifyMFA) AsVerifyMFA0() (VerifyMFA0, error) { + var body VerifyMFA0 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromVerifyMFA0 overwrites any union data inside the VerifyMFA as the provided VerifyMFA0 +func (t *VerifyMFA) FromVerifyMFA0(v VerifyMFA0) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeVerifyMFA0 performs a merge with any union data inside the VerifyMFA, using the provided VerifyMFA0 +func (t *VerifyMFA) MergeVerifyMFA0(v VerifyMFA0) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +// AsVerifyMFA1 returns the union data inside the VerifyMFA as a VerifyMFA1 +func (t VerifyMFA) AsVerifyMFA1() (VerifyMFA1, error) { + var body VerifyMFA1 + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromVerifyMFA1 overwrites any union data inside the VerifyMFA as the provided VerifyMFA1 +func (t *VerifyMFA) FromVerifyMFA1(v VerifyMFA1) error { + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeVerifyMFA1 performs a merge with any union data inside the VerifyMFA, using the provided VerifyMFA1 +func (t *VerifyMFA) MergeVerifyMFA1(v VerifyMFA1) error { + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + +func (t VerifyMFA) MarshalJSON() ([]byte, error) { + b, err := t.union.MarshalJSON() + if err != nil { + return nil, err + } + object := make(map[string]json.RawMessage) + if t.union != nil { + err = json.Unmarshal(b, &object) + if err != nil { + return nil, err + } + } + + object["challenge_id"], err = json.Marshal(t.ChallengeId) + if err != nil { + return nil, fmt.Errorf("error marshaling 'challenge_id': %w", err) + } + + if t.Code != nil { + object["code"], err = json.Marshal(t.Code) + if err != nil { + return nil, fmt.Errorf("error marshaling 'code': %w", err) + } + } + + if t.RecoveryCode != nil { + object["recovery_code"], err = json.Marshal(t.RecoveryCode) + if err != nil { + return nil, fmt.Errorf("error marshaling 'recovery_code': %w", err) + } + } + b, err = json.Marshal(object) + return b, err +} + +func (t *VerifyMFA) UnmarshalJSON(b []byte) error { + err := t.union.UnmarshalJSON(b) + if err != nil { + return err + } + object := make(map[string]json.RawMessage) + err = json.Unmarshal(b, &object) + if err != nil { + return err + } + + if raw, found := object["challenge_id"]; found { + err = json.Unmarshal(raw, &t.ChallengeId) + if err != nil { + return fmt.Errorf("error reading 'challenge_id': %w", err) + } + } + + if raw, found := object["code"]; found { + err = json.Unmarshal(raw, &t.Code) + if err != nil { + return fmt.Errorf("error reading 'code': %w", err) + } + } + + if raw, found := object["recovery_code"]; found { + err = json.Unmarshal(raw, &t.RecoveryCode) + if err != nil { + return fmt.Errorf("error reading 'recovery_code': %w", err) + } + } + + return err +} + // ServerInterface represents all server handlers. type ServerInterface interface { @@ -2598,6 +5085,12 @@ type ServerInterface interface { // (POST /v1/applications/{application_id}/auth/email/verify) EmailVerify(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + // (POST /v1/applications/{application_id}/auth/invitations/exchange) + ExchangeApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + + // (POST /v1/applications/{application_id}/auth/invitations/token) + RedeemApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + // (POST /v1/applications/{application_id}/auth/logout) LogoutCurrentSession(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -2628,18 +5121,12 @@ type ServerInterface interface { // (GET /v1/applications/{application_id}/auth/providers) ListAuthProviders(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - // (POST /v1/applications/{application_id}/auth/providers/apple/callback) - AppleAuthCallback(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - // (POST /v1/applications/{application_id}/auth/providers/apple/exchange) ExchangeAppleAuth(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) // (POST /v1/applications/{application_id}/auth/providers/apple/start) StartAppleAuth(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - // (GET /v1/applications/{application_id}/auth/providers/google/callback) - GoogleAuthCallback(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - // (POST /v1/applications/{application_id}/auth/providers/google/exchange) ExchangeGoogleAuth(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -2667,6 +5154,21 @@ type ServerInterface interface { // (POST /v1/applications/{application_id}/events) PublishCustomEvent(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params PublishCustomEventParams) + // (GET /v1/applications/{application_id}/invitations) + ListApplicationInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + + // (POST /v1/applications/{application_id}/invitations) + CreateApplicationInvitationMachine(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + + // (DELETE /v1/applications/{application_id}/invitations/{invitation_id}) + RevokeApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) + + // (GET /v1/applications/{application_id}/invitations/{invitation_id}) + GetApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) + + // (POST /v1/applications/{application_id}/invitations/{invitation_id}/resend) + ResendApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) + // (POST /v1/applications/{application_id}/local-entitlement-checkouts) LocalEntitlementCheckout(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params LocalEntitlementCheckoutParams) @@ -2830,10 +5332,7 @@ type ServerInterface interface { ListMySubscriptions(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) // (GET /v1/applications/{application_id}/me/workspace-invitations) - ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - - // (POST /v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept) - AcceptMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) + ListMyPendingInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) // (GET /v1/applications/{application_id}/me/workspaces) ListMyWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -2841,9 +5340,33 @@ type ServerInterface interface { // (POST /v1/applications/{application_id}/me/workspaces) CreateMyWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + // (POST /v1/applications/{application_id}/notifications) + SendMachineNotification(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params SendMachineNotificationParams) + + // (GET /v1/applications/{application_id}/permission-grants) + ListPermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params ListPermissionGrantsParams) + + // (POST /v1/applications/{application_id}/permission-grants) + CreatePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params CreatePermissionGrantParams) + + // (GET /v1/applications/{application_id}/permission-grants/effective) + GetEffectiveAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params GetEffectiveAccessParams) + + // (DELETE /v1/applications/{application_id}/permission-grants/{grant_id}) + RevokePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID, params RevokePermissionGrantParams) + + // (GET /v1/applications/{application_id}/permission-grants/{grant_id}) + GetPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID) + // (GET /v1/applications/{application_id}/public-config) PublicConfig(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + // (GET /v1/applications/{application_id}/service/workspaces/{workspace_id}) + ServiceGetApplicationWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + + // (GET /v1/applications/{application_id}/service/workspaces/{workspace_id}/access) + ServiceListApplicationWorkspaceAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + // (GET /v1/applications/{application_id}/storage/objects) ListApplicationStorageObjects(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -2862,6 +5385,21 @@ type ServerInterface interface { // (POST /v1/applications/{application_id}/storage/uploads/{object_id}/complete) CompleteApplicationStorageUpload(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, objectId ObjectID) + // (GET /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing) + ServiceGetSubjectBilling(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, subjectType interface{}, subjectId UUID) + + // (GET /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements) + ServiceGetSubjectEntitlements(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, subjectType interface{}, subjectId UUID) + + // (GET /v1/applications/{application_id}/users) + ServiceListApplicationUsers(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + + // (GET /v1/applications/{application_id}/users/{user_id}) + ServiceGetApplicationUser(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, userId UUID) + + // (GET /v1/applications/{application_id}/workspaces) + ServiceListApplicationWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + // (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}) ArchiveMyWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) @@ -2871,6 +5409,9 @@ type ServerInterface interface { // (PATCH /v1/applications/{application_id}/workspaces/{workspace_id}) UpdateMyWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/access) + ListMyWorkspaceAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/addresses) ListWorkspaceAddresses(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) @@ -2892,9 +5433,18 @@ type ServerInterface interface { // (PATCH /v1/applications/{application_id}/workspaces/{workspace_id}/billing-profile) UpdateWorkspaceBillingProfile(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/invitations) + ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/invitations) CreateMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + // (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}) + RevokeMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID, invitationId UUID) + + // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend) + ResendMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID, invitationId UUID) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/members) ListMyWorkspaceMembers(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) @@ -2910,6 +5460,18 @@ type ServerInterface interface { // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/owner-transfer) TransferMyWorkspaceOwnership(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants) + ListWorkspacePermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, params ListWorkspacePermissionGrantsParams) + + // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants) + CreateWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, params CreateWorkspacePermissionGrantParams) + + // (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}) + RevokeWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, grantId UUID, params RevokeWorkspacePermissionGrantParams) + + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}) + GetWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, grantId UUID) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects) ListWorkspaceStorageObjects(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID) @@ -2928,6 +5490,12 @@ type ServerInterface interface { // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/storage/uploads/{object_id}/complete) CompleteWorkspaceStorageUpload(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, objectId ObjectID) + // (POST /v1/auth/providers/apple/callback) + AppleAuthCallback(w http.ResponseWriter, r *http.Request) + + // (GET /v1/auth/providers/google/callback) + GoogleAuthCallback(w http.ResponseWriter, r *http.Request) + // (GET /v1/control/applications/{application_id}) GetApplication(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -3045,6 +5613,9 @@ type ServerInterface interface { // (DELETE /v1/control/applications/{application_id}/clients/{client_id}) DisableClient(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, clientId string) + // (GET /v1/control/applications/{application_id}/clients/{client_id}) + GetClient(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, clientId string) + // (PATCH /v1/control/applications/{application_id}/clients/{client_id}) UpdateClient(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, clientId string) @@ -3084,6 +5655,9 @@ type ServerInterface interface { // (GET /v1/control/applications/{application_id}/entitlements/{entitlement_id}) GetEntitlement(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, entitlementId UUID) + // (POST /v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust) + AdjustEntitlement(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, entitlementId UUID) + // (POST /v1/control/applications/{application_id}/entitlements/{entitlement_id}/restore) RestoreEntitlement(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, entitlementId UUID) @@ -3120,6 +5694,21 @@ type ServerInterface interface { // (PATCH /v1/control/applications/{application_id}/internal-config) UpdateInternalApplicationConfig(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + // (GET /v1/control/applications/{application_id}/invitations) + ListApplicationInvitationsControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + + // (POST /v1/control/applications/{application_id}/invitations) + CreateApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) + + // (DELETE /v1/control/applications/{application_id}/invitations/{invitation_id}) + RevokeApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) + + // (GET /v1/control/applications/{application_id}/invitations/{invitation_id}) + GetApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) + + // (POST /v1/control/applications/{application_id}/invitations/{invitation_id}/resend) + ResendApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) + // (GET /v1/control/applications/{application_id}/local-entitlement-requests) ListLocalEntitlementRequests(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -3183,9 +5772,6 @@ type ServerInterface interface { // (GET /v1/control/applications/{application_id}/notifications) ListNotifications(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - // (POST /v1/control/applications/{application_id}/notifications) - QueueNotification(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params QueueNotificationParams) - // (GET /v1/control/applications/{application_id}/notifications/statistics) GetNotificationStatistics(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -3201,6 +5787,21 @@ type ServerInterface interface { // (POST /v1/control/applications/{application_id}/oauth-consents/{user_id}/{client_id}/revoke) RevokeOAuthConsent(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, userId UUID, clientId UUID) + // (GET /v1/control/applications/{application_id}/permission-grants) + ListControlPermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params ListControlPermissionGrantsParams) + + // (POST /v1/control/applications/{application_id}/permission-grants) + CreateControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params CreateControlPermissionGrantParams) + + // (GET /v1/control/applications/{application_id}/permission-grants/effective) + GetControlEffectiveAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params GetControlEffectiveAccessParams) + + // (DELETE /v1/control/applications/{application_id}/permission-grants/{grant_id}) + RevokeControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID, params RevokeControlPermissionGrantParams) + + // (GET /v1/control/applications/{application_id}/permission-grants/{grant_id}) + GetControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID) + // (GET /v1/control/applications/{application_id}/products) ListProducts(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -3244,7 +5845,7 @@ type ServerInterface interface { GetRole(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, roleId UUID) // (PATCH /v1/control/applications/{application_id}/roles/{role_id}) - UpdateRole(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, roleId UUID) + UpdateRole(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, roleId UUID, params UpdateRoleParams) // (GET /v1/control/applications/{application_id}/sender-identities) ListSenderIdentities(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -3366,15 +5967,6 @@ type ServerInterface interface { // (POST /v1/control/applications/{application_id}/webhooks/{webhook_id}/test) TestWebhook(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, webhookId UUID, params TestWebhookParams) - // (GET /v1/control/applications/{application_id}/workspace-invitations) - ListWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - - // (POST /v1/control/applications/{application_id}/workspace-invitations) - CreateWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) - - // (DELETE /v1/control/applications/{application_id}/workspace-invitations/{invitation_id}) - RevokeWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) - // (GET /v1/control/applications/{application_id}/workspaces) ListWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) @@ -3403,37 +5995,55 @@ type ServerInterface interface { RecoverWorkspaceOwnership(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) // (POST /v1/control/auth/email/start) - StartOperatorEmailLogin(w http.ResponseWriter, r *http.Request) + StartControlUserEmailLogin(w http.ResponseWriter, r *http.Request) // (POST /v1/control/auth/email/verify) - VerifyOperatorEmailLogin(w http.ResponseWriter, r *http.Request) + VerifyControlUserEmailLogin(w http.ResponseWriter, r *http.Request) + + // (DELETE /v1/control/auth/identities/{identity_id}) + UnlinkControlExternalIdentity(w http.ResponseWriter, r *http.Request, identityId UUID) // (POST /v1/control/auth/logout) - LogoutOperator(w http.ResponseWriter, r *http.Request) + LogoutControlUser(w http.ResponseWriter, r *http.Request) // (POST /v1/control/auth/logout-all) - LogoutAllOperatorSessions(w http.ResponseWriter, r *http.Request) + LogoutAllControlUserSessions(w http.ResponseWriter, r *http.Request) // (GET /v1/control/auth/me) - GetOperatorAccount(w http.ResponseWriter, r *http.Request) + GetControlUserAccount(w http.ResponseWriter, r *http.Request) // (PATCH /v1/control/auth/me) - UpdateOperatorAccount(w http.ResponseWriter, r *http.Request) + UpdateControlUserAccount(w http.ResponseWriter, r *http.Request) + + // (GET /v1/control/auth/methods) + GetControlAuthMethods(w http.ResponseWriter, r *http.Request) // (POST /v1/control/auth/password) - LoginOperatorWithPassword(w http.ResponseWriter, r *http.Request) + LoginControlUserWithPassword(w http.ResponseWriter, r *http.Request) // (PUT /v1/control/auth/password) - ChangeOperatorPassword(w http.ResponseWriter, r *http.Request) + ChangeControlUserPassword(w http.ResponseWriter, r *http.Request) + + // (POST /v1/control/auth/providers/{provider}/link) + LinkControlExternalIdentity(w http.ResponseWriter, r *http.Request, provider string) + + // (POST /v1/control/auth/providers/{provider}/start) + StartControlExternalLogin(w http.ResponseWriter, r *http.Request, provider string) // (GET /v1/control/auth/sessions) - ListOperatorSessions(w http.ResponseWriter, r *http.Request) + ListControlUserSessions(w http.ResponseWriter, r *http.Request) // (DELETE /v1/control/auth/sessions/{session_id}) - RevokeOperatorSession(w http.ResponseWriter, r *http.Request, sessionId UUID) + RevokeControlUserSession(w http.ResponseWriter, r *http.Request, sessionId UUID) // (POST /v1/control/auth/token/refresh) - RefreshOperatorSession(w http.ResponseWriter, r *http.Request) + RefreshControlUserSession(w http.ResponseWriter, r *http.Request) + + // (GET /v1/control/installation/auth-policy) + GetControlAuthPolicy(w http.ResponseWriter, r *http.Request) + + // (PATCH /v1/control/installation/auth-policy) + UpdateControlAuthPolicy(w http.ResponseWriter, r *http.Request) // (GET /v1/control/installation/auth/providers) ListInstallationAuthProviders(w http.ResponseWriter, r *http.Request) @@ -3465,6 +6075,18 @@ type ServerInterface interface { // (POST /v1/control/installation/billing/providers/{provider_id}/verify) VerifyInstallationBillingProvider(w http.ResponseWriter, r *http.Request, providerId ProviderID) + // (GET /v1/control/installation/invitations) + ListInstallationControlUserInvitations(w http.ResponseWriter, r *http.Request) + + // (POST /v1/control/installation/invitations) + CreateInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) + + // (DELETE /v1/control/installation/invitations/{invitation_id}) + RevokeInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request, invitationId UUID) + + // (POST /v1/control/installation/invitations/{invitation_id}/resend) + ResendInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request, invitationId UUID) + // (GET /v1/control/installation/management-api) GetManagementAPIStatus(w http.ResponseWriter, r *http.Request) @@ -3528,18 +6150,6 @@ type ServerInterface interface { // (POST /v1/control/installation/notification-templates/{template_id}/publish) PublishInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request, templateId UUID) - // (GET /v1/control/installation/operators) - ListInstallationOperators(w http.ResponseWriter, r *http.Request) - - // (POST /v1/control/installation/operators) - CreateInstallationOperator(w http.ResponseWriter, r *http.Request) - - // (DELETE /v1/control/installation/operators/{operator_id}) - DeleteInstallationOperator(w http.ResponseWriter, r *http.Request, operatorId UUID) - - // (PATCH /v1/control/installation/operators/{operator_id}) - UpdateInstallationOperator(w http.ResponseWriter, r *http.Request, operatorId UUID) - // (PUT /v1/control/installation/organizations/{organization_id}/policy) UpdateOrganizationPolicy(w http.ResponseWriter, r *http.Request, organizationId OrganizationID, params UpdateOrganizationPolicyParams) @@ -3588,8 +6198,20 @@ type ServerInterface interface { // (POST /v1/control/installation/storage/uploads/{object_id}/complete) CompleteInstallationStorageUpload(w http.ResponseWriter, r *http.Request, objectId ObjectID) - // (POST /v1/control/organization-invitations/accept) - AcceptOrganizationInvitation(w http.ResponseWriter, r *http.Request) + // (GET /v1/control/installation/users) + ListInstallationControlUsers(w http.ResponseWriter, r *http.Request) + + // (DELETE /v1/control/installation/users/{control_user_id}) + DeleteInstallationControlUser(w http.ResponseWriter, r *http.Request, controlUserId UUID) + + // (PATCH /v1/control/installation/users/{control_user_id}) + UpdateInstallationControlUser(w http.ResponseWriter, r *http.Request, controlUserId UUID) + + // (POST /v1/control/invitations/accept) + AcceptControlUserInvitation(w http.ResponseWriter, r *http.Request) + + // (POST /v1/control/invitations/providers/{provider}/start) + StartControlInvitationExternalLogin(w http.ResponseWriter, r *http.Request, provider string) // (GET /v1/control/organizations) ListOrganizations(w http.ResponseWriter, r *http.Request, params ListOrganizationsParams) @@ -3859,6 +6481,16 @@ func (_ Unimplemented) EmailVerify(w http.ResponseWriter, r *http.Request, appli w.WriteHeader(http.StatusNotImplemented) } +// (POST /v1/applications/{application_id}/auth/invitations/exchange) +func (_ Unimplemented) ExchangeApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/applications/{application_id}/auth/invitations/token) +func (_ Unimplemented) RedeemApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (POST /v1/applications/{application_id}/auth/logout) func (_ Unimplemented) LogoutCurrentSession(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -3909,11 +6541,6 @@ func (_ Unimplemented) ListAuthProviders(w http.ResponseWriter, r *http.Request, w.WriteHeader(http.StatusNotImplemented) } -// (POST /v1/applications/{application_id}/auth/providers/apple/callback) -func (_ Unimplemented) AppleAuthCallback(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - w.WriteHeader(http.StatusNotImplemented) -} - // (POST /v1/applications/{application_id}/auth/providers/apple/exchange) func (_ Unimplemented) ExchangeAppleAuth(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -3924,11 +6551,6 @@ func (_ Unimplemented) StartAppleAuth(w http.ResponseWriter, r *http.Request, ap w.WriteHeader(http.StatusNotImplemented) } -// (GET /v1/applications/{application_id}/auth/providers/google/callback) -func (_ Unimplemented) GoogleAuthCallback(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - w.WriteHeader(http.StatusNotImplemented) -} - // (POST /v1/applications/{application_id}/auth/providers/google/exchange) func (_ Unimplemented) ExchangeGoogleAuth(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -3974,6 +6596,31 @@ func (_ Unimplemented) PublishCustomEvent(w http.ResponseWriter, r *http.Request w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/applications/{application_id}/invitations) +func (_ Unimplemented) ListApplicationInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/applications/{application_id}/invitations) +func (_ Unimplemented) CreateApplicationInvitationMachine(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/applications/{application_id}/invitations/{invitation_id}) +func (_ Unimplemented) RevokeApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/invitations/{invitation_id}) +func (_ Unimplemented) GetApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/applications/{application_id}/invitations/{invitation_id}/resend) +func (_ Unimplemented) ResendApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (POST /v1/applications/{application_id}/local-entitlement-checkouts) func (_ Unimplemented) LocalEntitlementCheckout(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params LocalEntitlementCheckoutParams) { w.WriteHeader(http.StatusNotImplemented) @@ -4245,12 +6892,7 @@ func (_ Unimplemented) ListMySubscriptions(w http.ResponseWriter, r *http.Reques } // (GET /v1/applications/{application_id}/me/workspace-invitations) -func (_ Unimplemented) ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - w.WriteHeader(http.StatusNotImplemented) -} - -// (POST /v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept) -func (_ Unimplemented) AcceptMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { +func (_ Unimplemented) ListMyPendingInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) } @@ -4264,11 +6906,51 @@ func (_ Unimplemented) CreateMyWorkspace(w http.ResponseWriter, r *http.Request, w.WriteHeader(http.StatusNotImplemented) } +// (POST /v1/applications/{application_id}/notifications) +func (_ Unimplemented) SendMachineNotification(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params SendMachineNotificationParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/permission-grants) +func (_ Unimplemented) ListPermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params ListPermissionGrantsParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/applications/{application_id}/permission-grants) +func (_ Unimplemented) CreatePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params CreatePermissionGrantParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/permission-grants/effective) +func (_ Unimplemented) GetEffectiveAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params GetEffectiveAccessParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/applications/{application_id}/permission-grants/{grant_id}) +func (_ Unimplemented) RevokePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID, params RevokePermissionGrantParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/permission-grants/{grant_id}) +func (_ Unimplemented) GetPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/applications/{application_id}/public-config) func (_ Unimplemented) PublicConfig(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/applications/{application_id}/service/workspaces/{workspace_id}) +func (_ Unimplemented) ServiceGetApplicationWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/service/workspaces/{workspace_id}/access) +func (_ Unimplemented) ServiceListApplicationWorkspaceAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/applications/{application_id}/storage/objects) func (_ Unimplemented) ListApplicationStorageObjects(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -4299,6 +6981,31 @@ func (_ Unimplemented) CompleteApplicationStorageUpload(w http.ResponseWriter, r w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing) +func (_ Unimplemented) ServiceGetSubjectBilling(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, subjectType interface{}, subjectId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements) +func (_ Unimplemented) ServiceGetSubjectEntitlements(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, subjectType interface{}, subjectId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/users) +func (_ Unimplemented) ServiceListApplicationUsers(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/users/{user_id}) +func (_ Unimplemented) ServiceGetApplicationUser(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, userId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/workspaces) +func (_ Unimplemented) ServiceListApplicationWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}) func (_ Unimplemented) ArchiveMyWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { w.WriteHeader(http.StatusNotImplemented) @@ -4314,6 +7021,11 @@ func (_ Unimplemented) UpdateMyWorkspace(w http.ResponseWriter, r *http.Request, w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/applications/{application_id}/workspaces/{workspace_id}/access) +func (_ Unimplemented) ListMyWorkspaceAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/addresses) func (_ Unimplemented) ListWorkspaceAddresses(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { w.WriteHeader(http.StatusNotImplemented) @@ -4349,11 +7061,26 @@ func (_ Unimplemented) UpdateWorkspaceBillingProfile(w http.ResponseWriter, r *h w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/applications/{application_id}/workspaces/{workspace_id}/invitations) +func (_ Unimplemented) ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/invitations) func (_ Unimplemented) CreateMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { w.WriteHeader(http.StatusNotImplemented) } +// (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}) +func (_ Unimplemented) RevokeMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend) +func (_ Unimplemented) ResendMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/members) func (_ Unimplemented) ListMyWorkspaceMembers(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { w.WriteHeader(http.StatusNotImplemented) @@ -4379,6 +7106,26 @@ func (_ Unimplemented) TransferMyWorkspaceOwnership(w http.ResponseWriter, r *ht w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants) +func (_ Unimplemented) ListWorkspacePermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, params ListWorkspacePermissionGrantsParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants) +func (_ Unimplemented) CreateWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, params CreateWorkspacePermissionGrantParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}) +func (_ Unimplemented) RevokeWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, grantId UUID, params RevokeWorkspacePermissionGrantParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}) +func (_ Unimplemented) GetWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, grantId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects) func (_ Unimplemented) ListWorkspaceStorageObjects(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID) { w.WriteHeader(http.StatusNotImplemented) @@ -4409,6 +7156,16 @@ func (_ Unimplemented) CompleteWorkspaceStorageUpload(w http.ResponseWriter, r * w.WriteHeader(http.StatusNotImplemented) } +// (POST /v1/auth/providers/apple/callback) +func (_ Unimplemented) AppleAuthCallback(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/auth/providers/google/callback) +func (_ Unimplemented) GoogleAuthCallback(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/control/applications/{application_id}) func (_ Unimplemented) GetApplication(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -4604,6 +7361,11 @@ func (_ Unimplemented) DisableClient(w http.ResponseWriter, r *http.Request, app w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/control/applications/{application_id}/clients/{client_id}) +func (_ Unimplemented) GetClient(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, clientId string) { + w.WriteHeader(http.StatusNotImplemented) +} + // (PATCH /v1/control/applications/{application_id}/clients/{client_id}) func (_ Unimplemented) UpdateClient(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, clientId string) { w.WriteHeader(http.StatusNotImplemented) @@ -4669,6 +7431,11 @@ func (_ Unimplemented) GetEntitlement(w http.ResponseWriter, r *http.Request, ap w.WriteHeader(http.StatusNotImplemented) } +// (POST /v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust) +func (_ Unimplemented) AdjustEntitlement(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, entitlementId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (POST /v1/control/applications/{application_id}/entitlements/{entitlement_id}/restore) func (_ Unimplemented) RestoreEntitlement(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, entitlementId UUID) { w.WriteHeader(http.StatusNotImplemented) @@ -4729,6 +7496,31 @@ func (_ Unimplemented) UpdateInternalApplicationConfig(w http.ResponseWriter, r w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/control/applications/{application_id}/invitations) +func (_ Unimplemented) ListApplicationInvitationsControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/applications/{application_id}/invitations) +func (_ Unimplemented) CreateApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/control/applications/{application_id}/invitations/{invitation_id}) +func (_ Unimplemented) RevokeApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/control/applications/{application_id}/invitations/{invitation_id}) +func (_ Unimplemented) GetApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/applications/{application_id}/invitations/{invitation_id}/resend) +func (_ Unimplemented) ResendApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/control/applications/{application_id}/local-entitlement-requests) func (_ Unimplemented) ListLocalEntitlementRequests(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -4834,11 +7626,6 @@ func (_ Unimplemented) ListNotifications(w http.ResponseWriter, r *http.Request, w.WriteHeader(http.StatusNotImplemented) } -// (POST /v1/control/applications/{application_id}/notifications) -func (_ Unimplemented) QueueNotification(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params QueueNotificationParams) { - w.WriteHeader(http.StatusNotImplemented) -} - // (GET /v1/control/applications/{application_id}/notifications/statistics) func (_ Unimplemented) GetNotificationStatistics(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -4864,6 +7651,31 @@ func (_ Unimplemented) RevokeOAuthConsent(w http.ResponseWriter, r *http.Request w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/control/applications/{application_id}/permission-grants) +func (_ Unimplemented) ListControlPermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params ListControlPermissionGrantsParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/applications/{application_id}/permission-grants) +func (_ Unimplemented) CreateControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params CreateControlPermissionGrantParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/control/applications/{application_id}/permission-grants/effective) +func (_ Unimplemented) GetControlEffectiveAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params GetControlEffectiveAccessParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/control/applications/{application_id}/permission-grants/{grant_id}) +func (_ Unimplemented) RevokeControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID, params RevokeControlPermissionGrantParams) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/control/applications/{application_id}/permission-grants/{grant_id}) +func (_ Unimplemented) GetControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/control/applications/{application_id}/products) func (_ Unimplemented) ListProducts(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -4935,7 +7747,7 @@ func (_ Unimplemented) GetRole(w http.ResponseWriter, r *http.Request, applicati } // (PATCH /v1/control/applications/{application_id}/roles/{role_id}) -func (_ Unimplemented) UpdateRole(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, roleId UUID) { +func (_ Unimplemented) UpdateRole(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, roleId UUID, params UpdateRoleParams) { w.WriteHeader(http.StatusNotImplemented) } @@ -5139,21 +7951,6 @@ func (_ Unimplemented) TestWebhook(w http.ResponseWriter, r *http.Request, appli w.WriteHeader(http.StatusNotImplemented) } -// (GET /v1/control/applications/{application_id}/workspace-invitations) -func (_ Unimplemented) ListWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - w.WriteHeader(http.StatusNotImplemented) -} - -// (POST /v1/control/applications/{application_id}/workspace-invitations) -func (_ Unimplemented) CreateWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - w.WriteHeader(http.StatusNotImplemented) -} - -// (DELETE /v1/control/applications/{application_id}/workspace-invitations/{invitation_id}) -func (_ Unimplemented) RevokeWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { - w.WriteHeader(http.StatusNotImplemented) -} - // (GET /v1/control/applications/{application_id}/workspaces) func (_ Unimplemented) ListWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { w.WriteHeader(http.StatusNotImplemented) @@ -5200,57 +7997,87 @@ func (_ Unimplemented) RecoverWorkspaceOwnership(w http.ResponseWriter, r *http. } // (POST /v1/control/auth/email/start) -func (_ Unimplemented) StartOperatorEmailLogin(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) StartControlUserEmailLogin(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } // (POST /v1/control/auth/email/verify) -func (_ Unimplemented) VerifyOperatorEmailLogin(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) VerifyControlUserEmailLogin(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/control/auth/identities/{identity_id}) +func (_ Unimplemented) UnlinkControlExternalIdentity(w http.ResponseWriter, r *http.Request, identityId UUID) { w.WriteHeader(http.StatusNotImplemented) } // (POST /v1/control/auth/logout) -func (_ Unimplemented) LogoutOperator(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) LogoutControlUser(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } // (POST /v1/control/auth/logout-all) -func (_ Unimplemented) LogoutAllOperatorSessions(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) LogoutAllControlUserSessions(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } // (GET /v1/control/auth/me) -func (_ Unimplemented) GetOperatorAccount(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) GetControlUserAccount(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } // (PATCH /v1/control/auth/me) -func (_ Unimplemented) UpdateOperatorAccount(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) UpdateControlUserAccount(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/control/auth/methods) +func (_ Unimplemented) GetControlAuthMethods(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } // (POST /v1/control/auth/password) -func (_ Unimplemented) LoginOperatorWithPassword(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) LoginControlUserWithPassword(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } // (PUT /v1/control/auth/password) -func (_ Unimplemented) ChangeOperatorPassword(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) ChangeControlUserPassword(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/auth/providers/{provider}/link) +func (_ Unimplemented) LinkControlExternalIdentity(w http.ResponseWriter, r *http.Request, provider string) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/auth/providers/{provider}/start) +func (_ Unimplemented) StartControlExternalLogin(w http.ResponseWriter, r *http.Request, provider string) { w.WriteHeader(http.StatusNotImplemented) } // (GET /v1/control/auth/sessions) -func (_ Unimplemented) ListOperatorSessions(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) ListControlUserSessions(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } // (DELETE /v1/control/auth/sessions/{session_id}) -func (_ Unimplemented) RevokeOperatorSession(w http.ResponseWriter, r *http.Request, sessionId UUID) { +func (_ Unimplemented) RevokeControlUserSession(w http.ResponseWriter, r *http.Request, sessionId UUID) { w.WriteHeader(http.StatusNotImplemented) } // (POST /v1/control/auth/token/refresh) -func (_ Unimplemented) RefreshOperatorSession(w http.ResponseWriter, r *http.Request) { +func (_ Unimplemented) RefreshControlUserSession(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (GET /v1/control/installation/auth-policy) +func (_ Unimplemented) GetControlAuthPolicy(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (PATCH /v1/control/installation/auth-policy) +func (_ Unimplemented) UpdateControlAuthPolicy(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) } @@ -5304,6 +8131,26 @@ func (_ Unimplemented) VerifyInstallationBillingProvider(w http.ResponseWriter, w.WriteHeader(http.StatusNotImplemented) } +// (GET /v1/control/installation/invitations) +func (_ Unimplemented) ListInstallationControlUserInvitations(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/installation/invitations) +func (_ Unimplemented) CreateInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/control/installation/invitations/{invitation_id}) +func (_ Unimplemented) RevokeInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/installation/invitations/{invitation_id}/resend) +func (_ Unimplemented) ResendInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request, invitationId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + // (GET /v1/control/installation/management-api) func (_ Unimplemented) GetManagementAPIStatus(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNotImplemented) @@ -5409,26 +8256,6 @@ func (_ Unimplemented) PublishInstallationNotificationTemplate(w http.ResponseWr w.WriteHeader(http.StatusNotImplemented) } -// (GET /v1/control/installation/operators) -func (_ Unimplemented) ListInstallationOperators(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// (POST /v1/control/installation/operators) -func (_ Unimplemented) CreateInstallationOperator(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusNotImplemented) -} - -// (DELETE /v1/control/installation/operators/{operator_id}) -func (_ Unimplemented) DeleteInstallationOperator(w http.ResponseWriter, r *http.Request, operatorId UUID) { - w.WriteHeader(http.StatusNotImplemented) -} - -// (PATCH /v1/control/installation/operators/{operator_id}) -func (_ Unimplemented) UpdateInstallationOperator(w http.ResponseWriter, r *http.Request, operatorId UUID) { - w.WriteHeader(http.StatusNotImplemented) -} - // (PUT /v1/control/installation/organizations/{organization_id}/policy) func (_ Unimplemented) UpdateOrganizationPolicy(w http.ResponseWriter, r *http.Request, organizationId OrganizationID, params UpdateOrganizationPolicyParams) { w.WriteHeader(http.StatusNotImplemented) @@ -5509,8 +8336,28 @@ func (_ Unimplemented) CompleteInstallationStorageUpload(w http.ResponseWriter, w.WriteHeader(http.StatusNotImplemented) } -// (POST /v1/control/organization-invitations/accept) -func (_ Unimplemented) AcceptOrganizationInvitation(w http.ResponseWriter, r *http.Request) { +// (GET /v1/control/installation/users) +func (_ Unimplemented) ListInstallationControlUsers(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (DELETE /v1/control/installation/users/{control_user_id}) +func (_ Unimplemented) DeleteInstallationControlUser(w http.ResponseWriter, r *http.Request, controlUserId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (PATCH /v1/control/installation/users/{control_user_id}) +func (_ Unimplemented) UpdateInstallationControlUser(w http.ResponseWriter, r *http.Request, controlUserId UUID) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/invitations/accept) +func (_ Unimplemented) AcceptControlUserInvitation(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) +} + +// (POST /v1/control/invitations/providers/{provider}/start) +func (_ Unimplemented) StartControlInvitationExternalLogin(w http.ResponseWriter, r *http.Request, provider string) { w.WriteHeader(http.StatusNotImplemented) } @@ -6208,8 +9055,8 @@ func (siw *ServerInterfaceWrapper) EmailVerify(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// LogoutCurrentSession operation middleware -func (siw *ServerInterfaceWrapper) LogoutCurrentSession(w http.ResponseWriter, r *http.Request) { +// ExchangeApplicationInvitation operation middleware +func (siw *ServerInterfaceWrapper) ExchangeApplicationInvitation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6223,14 +9070,8 @@ func (siw *ServerInterfaceWrapper) LogoutCurrentSession(w http.ResponseWriter, r return } - ctx := r.Context() - - ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) - - r = r.WithContext(ctx) - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.LogoutCurrentSession(w, r, applicationId) + siw.Handler.ExchangeApplicationInvitation(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6240,8 +9081,8 @@ func (siw *ServerInterfaceWrapper) LogoutCurrentSession(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// AuthMethods operation middleware -func (siw *ServerInterfaceWrapper) AuthMethods(w http.ResponseWriter, r *http.Request) { +// RedeemApplicationInvitation operation middleware +func (siw *ServerInterfaceWrapper) RedeemApplicationInvitation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6256,7 +9097,7 @@ func (siw *ServerInterfaceWrapper) AuthMethods(w http.ResponseWriter, r *http.Re } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.AuthMethods(w, r, applicationId) + siw.Handler.RedeemApplicationInvitation(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6266,8 +9107,8 @@ func (siw *ServerInterfaceWrapper) AuthMethods(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// VerifyMFA operation middleware -func (siw *ServerInterfaceWrapper) VerifyMFA(w http.ResponseWriter, r *http.Request) { +// LogoutCurrentSession operation middleware +func (siw *ServerInterfaceWrapper) LogoutCurrentSession(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6281,8 +9122,14 @@ func (siw *ServerInterfaceWrapper) VerifyMFA(w http.ResponseWriter, r *http.Requ return } + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyMFA(w, r, applicationId) + siw.Handler.LogoutCurrentSession(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6292,8 +9139,8 @@ func (siw *ServerInterfaceWrapper) VerifyMFA(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -// BeginWebAuthnAuthentication operation middleware -func (siw *ServerInterfaceWrapper) BeginWebAuthnAuthentication(w http.ResponseWriter, r *http.Request) { +// AuthMethods operation middleware +func (siw *ServerInterfaceWrapper) AuthMethods(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6308,7 +9155,7 @@ func (siw *ServerInterfaceWrapper) BeginWebAuthnAuthentication(w http.ResponseWr } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.BeginWebAuthnAuthentication(w, r, applicationId) + siw.Handler.AuthMethods(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6318,8 +9165,8 @@ func (siw *ServerInterfaceWrapper) BeginWebAuthnAuthentication(w http.ResponseWr handler.ServeHTTP(w, r) } -// FinishWebAuthnAuthentication operation middleware -func (siw *ServerInterfaceWrapper) FinishWebAuthnAuthentication(w http.ResponseWriter, r *http.Request) { +// VerifyMFA operation middleware +func (siw *ServerInterfaceWrapper) VerifyMFA(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6334,7 +9181,7 @@ func (siw *ServerInterfaceWrapper) FinishWebAuthnAuthentication(w http.ResponseW } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.FinishWebAuthnAuthentication(w, r, applicationId) + siw.Handler.VerifyMFA(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6344,8 +9191,8 @@ func (siw *ServerInterfaceWrapper) FinishWebAuthnAuthentication(w http.ResponseW handler.ServeHTTP(w, r) } -// PasswordResetStart operation middleware -func (siw *ServerInterfaceWrapper) PasswordResetStart(w http.ResponseWriter, r *http.Request) { +// BeginWebAuthnAuthentication operation middleware +func (siw *ServerInterfaceWrapper) BeginWebAuthnAuthentication(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6360,7 +9207,7 @@ func (siw *ServerInterfaceWrapper) PasswordResetStart(w http.ResponseWriter, r * } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PasswordResetStart(w, r, applicationId) + siw.Handler.BeginWebAuthnAuthentication(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6370,8 +9217,8 @@ func (siw *ServerInterfaceWrapper) PasswordResetStart(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// PasswordResetVerify operation middleware -func (siw *ServerInterfaceWrapper) PasswordResetVerify(w http.ResponseWriter, r *http.Request) { +// FinishWebAuthnAuthentication operation middleware +func (siw *ServerInterfaceWrapper) FinishWebAuthnAuthentication(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6386,7 +9233,7 @@ func (siw *ServerInterfaceWrapper) PasswordResetVerify(w http.ResponseWriter, r } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PasswordResetVerify(w, r, applicationId) + siw.Handler.FinishWebAuthnAuthentication(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6396,8 +9243,8 @@ func (siw *ServerInterfaceWrapper) PasswordResetVerify(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// PasswordSignIn operation middleware -func (siw *ServerInterfaceWrapper) PasswordSignIn(w http.ResponseWriter, r *http.Request) { +// PasswordResetStart operation middleware +func (siw *ServerInterfaceWrapper) PasswordResetStart(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6412,7 +9259,7 @@ func (siw *ServerInterfaceWrapper) PasswordSignIn(w http.ResponseWriter, r *http } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PasswordSignIn(w, r, applicationId) + siw.Handler.PasswordResetStart(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6422,8 +9269,8 @@ func (siw *ServerInterfaceWrapper) PasswordSignIn(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// PasswordSignUp operation middleware -func (siw *ServerInterfaceWrapper) PasswordSignUp(w http.ResponseWriter, r *http.Request) { +// PasswordResetVerify operation middleware +func (siw *ServerInterfaceWrapper) PasswordResetVerify(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6438,7 +9285,7 @@ func (siw *ServerInterfaceWrapper) PasswordSignUp(w http.ResponseWriter, r *http } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PasswordSignUp(w, r, applicationId) + siw.Handler.PasswordResetVerify(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6448,8 +9295,8 @@ func (siw *ServerInterfaceWrapper) PasswordSignUp(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// ListAuthProviders operation middleware -func (siw *ServerInterfaceWrapper) ListAuthProviders(w http.ResponseWriter, r *http.Request) { +// PasswordSignIn operation middleware +func (siw *ServerInterfaceWrapper) PasswordSignIn(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6464,7 +9311,7 @@ func (siw *ServerInterfaceWrapper) ListAuthProviders(w http.ResponseWriter, r *h } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListAuthProviders(w, r, applicationId) + siw.Handler.PasswordSignIn(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6474,8 +9321,8 @@ func (siw *ServerInterfaceWrapper) ListAuthProviders(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// AppleAuthCallback operation middleware -func (siw *ServerInterfaceWrapper) AppleAuthCallback(w http.ResponseWriter, r *http.Request) { +// PasswordSignUp operation middleware +func (siw *ServerInterfaceWrapper) PasswordSignUp(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6490,7 +9337,7 @@ func (siw *ServerInterfaceWrapper) AppleAuthCallback(w http.ResponseWriter, r *h } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.AppleAuthCallback(w, r, applicationId) + siw.Handler.PasswordSignUp(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6500,8 +9347,8 @@ func (siw *ServerInterfaceWrapper) AppleAuthCallback(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// ExchangeAppleAuth operation middleware -func (siw *ServerInterfaceWrapper) ExchangeAppleAuth(w http.ResponseWriter, r *http.Request) { +// ListAuthProviders operation middleware +func (siw *ServerInterfaceWrapper) ListAuthProviders(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6516,7 +9363,7 @@ func (siw *ServerInterfaceWrapper) ExchangeAppleAuth(w http.ResponseWriter, r *h } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ExchangeAppleAuth(w, r, applicationId) + siw.Handler.ListAuthProviders(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6526,8 +9373,8 @@ func (siw *ServerInterfaceWrapper) ExchangeAppleAuth(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// StartAppleAuth operation middleware -func (siw *ServerInterfaceWrapper) StartAppleAuth(w http.ResponseWriter, r *http.Request) { +// ExchangeAppleAuth operation middleware +func (siw *ServerInterfaceWrapper) ExchangeAppleAuth(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6542,7 +9389,7 @@ func (siw *ServerInterfaceWrapper) StartAppleAuth(w http.ResponseWriter, r *http } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.StartAppleAuth(w, r, applicationId) + siw.Handler.ExchangeAppleAuth(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6552,8 +9399,8 @@ func (siw *ServerInterfaceWrapper) StartAppleAuth(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// GoogleAuthCallback operation middleware -func (siw *ServerInterfaceWrapper) GoogleAuthCallback(w http.ResponseWriter, r *http.Request) { +// StartAppleAuth operation middleware +func (siw *ServerInterfaceWrapper) StartAppleAuth(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -6568,7 +9415,7 @@ func (siw *ServerInterfaceWrapper) GoogleAuthCallback(w http.ResponseWriter, r * } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GoogleAuthCallback(w, r, applicationId) + siw.Handler.StartAppleAuth(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -6930,6 +9777,193 @@ func (siw *ServerInterfaceWrapper) PublishCustomEvent(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } +// ListApplicationInvitations operation middleware +func (siw *ServerInterfaceWrapper) ListApplicationInvitations(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListApplicationInvitations(w, r, applicationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// CreateApplicationInvitationMachine operation middleware +func (siw *ServerInterfaceWrapper) CreateApplicationInvitationMachine(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CreateApplicationInvitationMachine(w, r, applicationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// RevokeApplicationInvitation operation middleware +func (siw *ServerInterfaceWrapper) RevokeApplicationInvitation(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.RevokeApplicationInvitation(w, r, applicationId, invitationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetApplicationInvitation operation middleware +func (siw *ServerInterfaceWrapper) GetApplicationInvitation(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetApplicationInvitation(w, r, applicationId, invitationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ResendApplicationInvitation operation middleware +func (siw *ServerInterfaceWrapper) ResendApplicationInvitation(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ResendApplicationInvitation(w, r, applicationId, invitationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + // LocalEntitlementCheckout operation middleware func (siw *ServerInterfaceWrapper) LocalEntitlementCheckout(w http.ResponseWriter, r *http.Request) { @@ -8870,8 +11904,8 @@ func (siw *ServerInterfaceWrapper) ListMySubscriptions(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// ListMyWorkspaceInvitations operation middleware -func (siw *ServerInterfaceWrapper) ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request) { +// ListMyPendingInvitations operation middleware +func (siw *ServerInterfaceWrapper) ListMyPendingInvitations(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -8892,7 +11926,7 @@ func (siw *ServerInterfaceWrapper) ListMyWorkspaceInvitations(w http.ResponseWri r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListMyWorkspaceInvitations(w, r, applicationId) + siw.Handler.ListMyPendingInvitations(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -8902,8 +11936,8 @@ func (siw *ServerInterfaceWrapper) ListMyWorkspaceInvitations(w http.ResponseWri handler.ServeHTTP(w, r) } -// AcceptMyWorkspaceInvitation operation middleware -func (siw *ServerInterfaceWrapper) AcceptMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { +// ListMyWorkspaces operation middleware +func (siw *ServerInterfaceWrapper) ListMyWorkspaces(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -8917,15 +11951,6 @@ func (siw *ServerInterfaceWrapper) AcceptMyWorkspaceInvitation(w http.ResponseWr return } - // ------------- Path parameter "invitation_id" ------------- - var invitationId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -8933,7 +11958,7 @@ func (siw *ServerInterfaceWrapper) AcceptMyWorkspaceInvitation(w http.ResponseWr r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.AcceptMyWorkspaceInvitation(w, r, applicationId, invitationId) + siw.Handler.ListMyWorkspaces(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -8943,8 +11968,8 @@ func (siw *ServerInterfaceWrapper) AcceptMyWorkspaceInvitation(w http.ResponseWr handler.ServeHTTP(w, r) } -// ListMyWorkspaces operation middleware -func (siw *ServerInterfaceWrapper) ListMyWorkspaces(w http.ResponseWriter, r *http.Request) { +// CreateMyWorkspace operation middleware +func (siw *ServerInterfaceWrapper) CreateMyWorkspace(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -8965,7 +11990,7 @@ func (siw *ServerInterfaceWrapper) ListMyWorkspaces(w http.ResponseWriter, r *ht r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListMyWorkspaces(w, r, applicationId) + siw.Handler.CreateMyWorkspace(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -8975,8 +12000,8 @@ func (siw *ServerInterfaceWrapper) ListMyWorkspaces(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// CreateMyWorkspace operation middleware -func (siw *ServerInterfaceWrapper) CreateMyWorkspace(w http.ResponseWriter, r *http.Request) { +// SendMachineNotification operation middleware +func (siw *ServerInterfaceWrapper) SendMachineNotification(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -8996,34 +12021,36 @@ func (siw *ServerInterfaceWrapper) CreateMyWorkspace(w http.ResponseWriter, r *h r = r.WithContext(ctx) - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateMyWorkspace(w, r, applicationId) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } + // Parameter object where we will unmarshal all parameters from the context + var params SendMachineNotificationParams - handler.ServeHTTP(w, r) -} + headers := r.Header -// PublicConfig operation middleware -func (siw *ServerInterfaceWrapper) PublicConfig(w http.ResponseWriter, r *http.Request) { + // ------------- Required header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey RequiredIdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } - var err error - _ = err + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + params.IdempotencyKey = IdempotencyKey - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PublicConfig(w, r, applicationId) + siw.Handler.SendMachineNotification(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9033,8 +12060,8 @@ func (siw *ServerInterfaceWrapper) PublicConfig(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// ListApplicationStorageObjects operation middleware -func (siw *ServerInterfaceWrapper) ListApplicationStorageObjects(w http.ResponseWriter, r *http.Request) { +// ListPermissionGrants operation middleware +func (siw *ServerInterfaceWrapper) ListPermissionGrants(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9054,8 +12081,63 @@ func (siw *ServerInterfaceWrapper) ListApplicationStorageObjects(w http.Response r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params ListPermissionGrantsParams + + // ------------- Optional query parameter "subject_type" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } + return + } + + // ------------- Optional query parameter "subject_id" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } + return + } + + // ------------- Optional query parameter "workspace_id" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "workspace_id", r.URL.Query(), ¶ms.WorkspaceId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "workspace_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + } + return + } + + // ------------- Optional query parameter "status" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "status", r.URL.Query(), ¶ms.Status, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "status"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "status", Err: err}) + } + return + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListApplicationStorageObjects(w, r, applicationId) + siw.Handler.ListPermissionGrants(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9065,8 +12147,8 @@ func (siw *ServerInterfaceWrapper) ListApplicationStorageObjects(w http.Response handler.ServeHTTP(w, r) } -// DeleteApplicationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DeleteApplicationStorageObject(w http.ResponseWriter, r *http.Request) { +// CreatePermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) CreatePermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9080,64 +12162,94 @@ func (siw *ServerInterfaceWrapper) DeleteApplicationStorageObject(w http.Respons return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID - - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteApplicationStorageObject(w, r, applicationId, objectId) - })) + // Parameter object where we will unmarshal all parameters from the context + var params CreatePermissionGrantParams - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } + // ------------- Optional query parameter "subject_type" ------------- - handler.ServeHTTP(w, r) -} + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } + return + } -// GetApplicationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) GetApplicationStorageObject(w http.ResponseWriter, r *http.Request) { + // ------------- Optional query parameter "subject_id" ------------- - var err error - _ = err + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } + return + } - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + // ------------- Optional query parameter "workspace_id" ------------- - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindQueryParameterWithOptions("form", true, false, "workspace_id", r.URL.Query(), ¶ms.WorkspaceId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "workspace_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + } return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Optional query parameter "status" ------------- - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindQueryParameterWithOptions("form", true, false, "status", r.URL.Query(), ¶ms.Status, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "status"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "status", Err: err}) + } return } - ctx := r.Context() + headers := r.Header - ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + // ------------- Required header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey RequiredIdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } - r = r.WithContext(ctx) + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = IdempotencyKey + + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetApplicationStorageObject(w, r, applicationId, objectId) + siw.Handler.CreatePermissionGrant(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9147,8 +12259,8 @@ func (siw *ServerInterfaceWrapper) GetApplicationStorageObject(w http.ResponseWr handler.ServeHTTP(w, r) } -// DownloadApplicationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DownloadApplicationStorageObject(w http.ResponseWriter, r *http.Request) { +// GetEffectiveAccess operation middleware +func (siw *ServerInterfaceWrapper) GetEffectiveAccess(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9162,23 +12274,56 @@ func (siw *ServerInterfaceWrapper) DownloadApplicationStorageObject(w http.Respo return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params GetEffectiveAccessParams + + // ------------- Required query parameter "subject_type" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, true, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } return } - ctx := r.Context() + // ------------- Required query parameter "subject_id" ------------- - ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + err = runtime.BindQueryParameterWithOptions("form", true, true, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } + return + } - r = r.WithContext(ctx) + // ------------- Optional query parameter "workspace_id" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "workspace_id", r.URL.Query(), ¶ms.WorkspaceId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "workspace_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + } + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DownloadApplicationStorageObject(w, r, applicationId, objectId) + siw.Handler.GetEffectiveAccess(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9188,8 +12333,8 @@ func (siw *ServerInterfaceWrapper) DownloadApplicationStorageObject(w http.Respo handler.ServeHTTP(w, r) } -// CreateApplicationStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CreateApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { +// RevokePermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) RevokePermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9203,6 +12348,15 @@ func (siw *ServerInterfaceWrapper) CreateApplicationStorageUpload(w http.Respons return } + // ------------- Path parameter "grant_id" ------------- + var grantId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "grant_id", chi.URLParam(r, "grant_id"), &grantId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "grant_id", Err: err}) + return + } + ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -9210,35 +12364,35 @@ func (siw *ServerInterfaceWrapper) CreateApplicationStorageUpload(w http.Respons r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params CreateApplicationStorageUploadParams + var params RevokePermissionGrantParams headers := r.Header - // ------------- Required header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey RequiredIdempotencyKey + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch n := len(valueList) if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) return } - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) return } - params.IdempotencyKey = IdempotencyKey + params.IfMatch = IfMatch } else { - err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateApplicationStorageUpload(w, r, applicationId, params) + siw.Handler.RevokePermissionGrant(w, r, applicationId, grantId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9248,8 +12402,8 @@ func (siw *ServerInterfaceWrapper) CreateApplicationStorageUpload(w http.Respons handler.ServeHTTP(w, r) } -// CompleteApplicationStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CompleteApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { +// GetPermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) GetPermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9263,12 +12417,12 @@ func (siw *ServerInterfaceWrapper) CompleteApplicationStorageUpload(w http.Respo return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "grant_id" ------------- + var grantId UUID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "grant_id", chi.URLParam(r, "grant_id"), &grantId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "grant_id", Err: err}) return } @@ -9279,7 +12433,7 @@ func (siw *ServerInterfaceWrapper) CompleteApplicationStorageUpload(w http.Respo r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CompleteApplicationStorageUpload(w, r, applicationId, objectId) + siw.Handler.GetPermissionGrant(w, r, applicationId, grantId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9289,8 +12443,8 @@ func (siw *ServerInterfaceWrapper) CompleteApplicationStorageUpload(w http.Respo handler.ServeHTTP(w, r) } -// ArchiveMyWorkspace operation middleware -func (siw *ServerInterfaceWrapper) ArchiveMyWorkspace(w http.ResponseWriter, r *http.Request) { +// PublicConfig operation middleware +func (siw *ServerInterfaceWrapper) PublicConfig(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9304,23 +12458,8 @@ func (siw *ServerInterfaceWrapper) ArchiveMyWorkspace(w http.ResponseWriter, r * return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - - ctx := r.Context() - - ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) - - r = r.WithContext(ctx) - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ArchiveMyWorkspace(w, r, applicationId, workspaceId) + siw.Handler.PublicConfig(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9330,8 +12469,8 @@ func (siw *ServerInterfaceWrapper) ArchiveMyWorkspace(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// GetMyWorkspace operation middleware -func (siw *ServerInterfaceWrapper) GetMyWorkspace(w http.ResponseWriter, r *http.Request) { +// ServiceGetApplicationWorkspace operation middleware +func (siw *ServerInterfaceWrapper) ServiceGetApplicationWorkspace(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9361,7 +12500,7 @@ func (siw *ServerInterfaceWrapper) GetMyWorkspace(w http.ResponseWriter, r *http r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetMyWorkspace(w, r, applicationId, workspaceId) + siw.Handler.ServiceGetApplicationWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9371,8 +12510,8 @@ func (siw *ServerInterfaceWrapper) GetMyWorkspace(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// UpdateMyWorkspace operation middleware -func (siw *ServerInterfaceWrapper) UpdateMyWorkspace(w http.ResponseWriter, r *http.Request) { +// ServiceListApplicationWorkspaceAccess operation middleware +func (siw *ServerInterfaceWrapper) ServiceListApplicationWorkspaceAccess(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9402,7 +12541,7 @@ func (siw *ServerInterfaceWrapper) UpdateMyWorkspace(w http.ResponseWriter, r *h r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateMyWorkspace(w, r, applicationId, workspaceId) + siw.Handler.ServiceListApplicationWorkspaceAccess(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9412,8 +12551,8 @@ func (siw *ServerInterfaceWrapper) UpdateMyWorkspace(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// ListWorkspaceAddresses operation middleware -func (siw *ServerInterfaceWrapper) ListWorkspaceAddresses(w http.ResponseWriter, r *http.Request) { +// ListApplicationStorageObjects operation middleware +func (siw *ServerInterfaceWrapper) ListApplicationStorageObjects(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9427,15 +12566,6 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceAddresses(w http.ResponseWriter, return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -9443,7 +12573,7 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceAddresses(w http.ResponseWriter, r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListWorkspaceAddresses(w, r, applicationId, workspaceId) + siw.Handler.ListApplicationStorageObjects(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9453,8 +12583,8 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceAddresses(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// CreateWorkspaceAddress operation middleware -func (siw *ServerInterfaceWrapper) CreateWorkspaceAddress(w http.ResponseWriter, r *http.Request) { +// DeleteApplicationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DeleteApplicationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9468,12 +12598,12 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceAddress(w http.ResponseWriter, return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } @@ -9484,7 +12614,7 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceAddress(w http.ResponseWriter, r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateWorkspaceAddress(w, r, applicationId, workspaceId) + siw.Handler.DeleteApplicationStorageObject(w, r, applicationId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9494,8 +12624,8 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceAddress(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// DeleteWorkspaceAddress operation middleware -func (siw *ServerInterfaceWrapper) DeleteWorkspaceAddress(w http.ResponseWriter, r *http.Request) { +// GetApplicationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) GetApplicationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9509,21 +12639,12 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceAddress(w http.ResponseWriter, return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - - // ------------- Path parameter "address_id" ------------- - var addressId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "address_id", chi.URLParam(r, "address_id"), &addressId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "address_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } @@ -9534,7 +12655,7 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceAddress(w http.ResponseWriter, r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteWorkspaceAddress(w, r, applicationId, workspaceId, addressId) + siw.Handler.GetApplicationStorageObject(w, r, applicationId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9544,8 +12665,8 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceAddress(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// UpdateWorkspaceAddress operation middleware -func (siw *ServerInterfaceWrapper) UpdateWorkspaceAddress(w http.ResponseWriter, r *http.Request) { +// DownloadApplicationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DownloadApplicationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9559,21 +12680,12 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspaceAddress(w http.ResponseWriter, return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - - // ------------- Path parameter "address_id" ------------- - var addressId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "address_id", chi.URLParam(r, "address_id"), &addressId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "address_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } @@ -9584,7 +12696,7 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspaceAddress(w http.ResponseWriter, r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateWorkspaceAddress(w, r, applicationId, workspaceId, addressId) + siw.Handler.DownloadApplicationStorageObject(w, r, applicationId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9594,8 +12706,8 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspaceAddress(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// ActivateWorkspaceAddress operation middleware -func (siw *ServerInterfaceWrapper) ActivateWorkspaceAddress(w http.ResponseWriter, r *http.Request) { +// CreateApplicationStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CreateApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9609,32 +12721,42 @@ func (siw *ServerInterfaceWrapper) ActivateWorkspaceAddress(w http.ResponseWrite return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) - // ------------- Path parameter "address_id" ------------- - var addressId UUID + r = r.WithContext(ctx) - err = runtime.BindStyledParameterWithOptions("simple", "address_id", chi.URLParam(r, "address_id"), &addressId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "address_id", Err: err}) - return - } + // Parameter object where we will unmarshal all parameters from the context + var params CreateApplicationStorageUploadParams - ctx := r.Context() + headers := r.Header - ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) + // ------------- Required header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey RequiredIdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } - r = r.WithContext(ctx) + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = IdempotencyKey + + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ActivateWorkspaceAddress(w, r, applicationId, workspaceId, addressId) + siw.Handler.CreateApplicationStorageUpload(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9644,8 +12766,8 @@ func (siw *ServerInterfaceWrapper) ActivateWorkspaceAddress(w http.ResponseWrite handler.ServeHTTP(w, r) } -// GetWorkspaceBillingProfile operation middleware -func (siw *ServerInterfaceWrapper) GetWorkspaceBillingProfile(w http.ResponseWriter, r *http.Request) { +// CompleteApplicationStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CompleteApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9659,12 +12781,12 @@ func (siw *ServerInterfaceWrapper) GetWorkspaceBillingProfile(w http.ResponseWri return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } @@ -9675,7 +12797,7 @@ func (siw *ServerInterfaceWrapper) GetWorkspaceBillingProfile(w http.ResponseWri r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetWorkspaceBillingProfile(w, r, applicationId, workspaceId) + siw.Handler.CompleteApplicationStorageUpload(w, r, applicationId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9685,8 +12807,8 @@ func (siw *ServerInterfaceWrapper) GetWorkspaceBillingProfile(w http.ResponseWri handler.ServeHTTP(w, r) } -// UpdateWorkspaceBillingProfile operation middleware -func (siw *ServerInterfaceWrapper) UpdateWorkspaceBillingProfile(w http.ResponseWriter, r *http.Request) { +// ServiceGetSubjectBilling operation middleware +func (siw *ServerInterfaceWrapper) ServiceGetSubjectBilling(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9700,12 +12822,21 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspaceBillingProfile(w http.Response return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "subject_type" ------------- + var subjectType interface{} - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "subject_type", chi.URLParam(r, "subject_type"), &subjectType, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + return + } + + // ------------- Path parameter "subject_id" ------------- + var subjectId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "subject_id", chi.URLParam(r, "subject_id"), &subjectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) return } @@ -9716,7 +12847,7 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspaceBillingProfile(w http.Response r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateWorkspaceBillingProfile(w, r, applicationId, workspaceId) + siw.Handler.ServiceGetSubjectBilling(w, r, applicationId, subjectType, subjectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9726,8 +12857,8 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspaceBillingProfile(w http.Response handler.ServeHTTP(w, r) } -// CreateMyWorkspaceInvitation operation middleware -func (siw *ServerInterfaceWrapper) CreateMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { +// ServiceGetSubjectEntitlements operation middleware +func (siw *ServerInterfaceWrapper) ServiceGetSubjectEntitlements(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9741,12 +12872,21 @@ func (siw *ServerInterfaceWrapper) CreateMyWorkspaceInvitation(w http.ResponseWr return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "subject_type" ------------- + var subjectType interface{} - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "subject_type", chi.URLParam(r, "subject_type"), &subjectType, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + return + } + + // ------------- Path parameter "subject_id" ------------- + var subjectId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "subject_id", chi.URLParam(r, "subject_id"), &subjectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) return } @@ -9757,7 +12897,7 @@ func (siw *ServerInterfaceWrapper) CreateMyWorkspaceInvitation(w http.ResponseWr r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateMyWorkspaceInvitation(w, r, applicationId, workspaceId) + siw.Handler.ServiceGetSubjectEntitlements(w, r, applicationId, subjectType, subjectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9767,8 +12907,8 @@ func (siw *ServerInterfaceWrapper) CreateMyWorkspaceInvitation(w http.ResponseWr handler.ServeHTTP(w, r) } -// ListMyWorkspaceMembers operation middleware -func (siw *ServerInterfaceWrapper) ListMyWorkspaceMembers(w http.ResponseWriter, r *http.Request) { +// ServiceListApplicationUsers operation middleware +func (siw *ServerInterfaceWrapper) ServiceListApplicationUsers(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9782,15 +12922,6 @@ func (siw *ServerInterfaceWrapper) ListMyWorkspaceMembers(w http.ResponseWriter, return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -9798,7 +12929,7 @@ func (siw *ServerInterfaceWrapper) ListMyWorkspaceMembers(w http.ResponseWriter, r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListMyWorkspaceMembers(w, r, applicationId, workspaceId) + siw.Handler.ServiceListApplicationUsers(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9808,8 +12939,8 @@ func (siw *ServerInterfaceWrapper) ListMyWorkspaceMembers(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// RemoveMyWorkspaceMember operation middleware -func (siw *ServerInterfaceWrapper) RemoveMyWorkspaceMember(w http.ResponseWriter, r *http.Request) { +// ServiceGetApplicationUser operation middleware +func (siw *ServerInterfaceWrapper) ServiceGetApplicationUser(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9823,15 +12954,6 @@ func (siw *ServerInterfaceWrapper) RemoveMyWorkspaceMember(w http.ResponseWriter return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - // ------------- Path parameter "user_id" ------------- var userId UUID @@ -9848,7 +12970,7 @@ func (siw *ServerInterfaceWrapper) RemoveMyWorkspaceMember(w http.ResponseWriter r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RemoveMyWorkspaceMember(w, r, applicationId, workspaceId, userId) + siw.Handler.ServiceGetApplicationUser(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9858,8 +12980,8 @@ func (siw *ServerInterfaceWrapper) RemoveMyWorkspaceMember(w http.ResponseWriter handler.ServeHTTP(w, r) } -// ReplaceMyWorkspaceMemberRoles operation middleware -func (siw *ServerInterfaceWrapper) ReplaceMyWorkspaceMemberRoles(w http.ResponseWriter, r *http.Request) { +// ServiceListApplicationWorkspaces operation middleware +func (siw *ServerInterfaceWrapper) ServiceListApplicationWorkspaces(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9873,24 +12995,6 @@ func (siw *ServerInterfaceWrapper) ReplaceMyWorkspaceMemberRoles(w http.Response return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - - // ------------- Path parameter "user_id" ------------- - var userId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -9898,7 +13002,7 @@ func (siw *ServerInterfaceWrapper) ReplaceMyWorkspaceMemberRoles(w http.Response r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ReplaceMyWorkspaceMemberRoles(w, r, applicationId, workspaceId, userId) + siw.Handler.ServiceListApplicationWorkspaces(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9908,8 +13012,8 @@ func (siw *ServerInterfaceWrapper) ReplaceMyWorkspaceMemberRoles(w http.Response handler.ServeHTTP(w, r) } -// LeaveWorkspace operation middleware -func (siw *ServerInterfaceWrapper) LeaveWorkspace(w http.ResponseWriter, r *http.Request) { +// ArchiveMyWorkspace operation middleware +func (siw *ServerInterfaceWrapper) ArchiveMyWorkspace(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9939,7 +13043,7 @@ func (siw *ServerInterfaceWrapper) LeaveWorkspace(w http.ResponseWriter, r *http r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.LeaveWorkspace(w, r, applicationId, workspaceId) + siw.Handler.ArchiveMyWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9949,8 +13053,8 @@ func (siw *ServerInterfaceWrapper) LeaveWorkspace(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// TransferMyWorkspaceOwnership operation middleware -func (siw *ServerInterfaceWrapper) TransferMyWorkspaceOwnership(w http.ResponseWriter, r *http.Request) { +// GetMyWorkspace operation middleware +func (siw *ServerInterfaceWrapper) GetMyWorkspace(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -9980,7 +13084,7 @@ func (siw *ServerInterfaceWrapper) TransferMyWorkspaceOwnership(w http.ResponseW r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.TransferMyWorkspaceOwnership(w, r, applicationId, workspaceId) + siw.Handler.GetMyWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -9990,8 +13094,8 @@ func (siw *ServerInterfaceWrapper) TransferMyWorkspaceOwnership(w http.ResponseW handler.ServeHTTP(w, r) } -// ListWorkspaceStorageObjects operation middleware -func (siw *ServerInterfaceWrapper) ListWorkspaceStorageObjects(w http.ResponseWriter, r *http.Request) { +// UpdateMyWorkspace operation middleware +func (siw *ServerInterfaceWrapper) UpdateMyWorkspace(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10006,7 +13110,7 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceStorageObjects(w http.ResponseWr } // ------------- Path parameter "workspace_id" ------------- - var workspaceId WorkspaceID + var workspaceId UUID err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -10021,7 +13125,7 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceStorageObjects(w http.ResponseWr r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListWorkspaceStorageObjects(w, r, applicationId, workspaceId) + siw.Handler.UpdateMyWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10031,8 +13135,8 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceStorageObjects(w http.ResponseWr handler.ServeHTTP(w, r) } -// DeleteWorkspaceStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DeleteWorkspaceStorageObject(w http.ResponseWriter, r *http.Request) { +// ListMyWorkspaceAccess operation middleware +func (siw *ServerInterfaceWrapper) ListMyWorkspaceAccess(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10047,7 +13151,7 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceStorageObject(w http.ResponseW } // ------------- Path parameter "workspace_id" ------------- - var workspaceId WorkspaceID + var workspaceId UUID err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -10055,15 +13159,6 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceStorageObject(w http.ResponseW return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID - - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -10071,7 +13166,7 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceStorageObject(w http.ResponseW r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteWorkspaceStorageObject(w, r, applicationId, workspaceId, objectId) + siw.Handler.ListMyWorkspaceAccess(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10081,8 +13176,8 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceStorageObject(w http.ResponseW handler.ServeHTTP(w, r) } -// GetWorkspaceStorageObject operation middleware -func (siw *ServerInterfaceWrapper) GetWorkspaceStorageObject(w http.ResponseWriter, r *http.Request) { +// ListWorkspaceAddresses operation middleware +func (siw *ServerInterfaceWrapper) ListWorkspaceAddresses(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10097,7 +13192,7 @@ func (siw *ServerInterfaceWrapper) GetWorkspaceStorageObject(w http.ResponseWrit } // ------------- Path parameter "workspace_id" ------------- - var workspaceId WorkspaceID + var workspaceId UUID err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -10105,15 +13200,6 @@ func (siw *ServerInterfaceWrapper) GetWorkspaceStorageObject(w http.ResponseWrit return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID - - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -10121,7 +13207,7 @@ func (siw *ServerInterfaceWrapper) GetWorkspaceStorageObject(w http.ResponseWrit r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetWorkspaceStorageObject(w, r, applicationId, workspaceId, objectId) + siw.Handler.ListWorkspaceAddresses(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10131,8 +13217,8 @@ func (siw *ServerInterfaceWrapper) GetWorkspaceStorageObject(w http.ResponseWrit handler.ServeHTTP(w, r) } -// DownloadWorkspaceStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DownloadWorkspaceStorageObject(w http.ResponseWriter, r *http.Request) { +// CreateWorkspaceAddress operation middleware +func (siw *ServerInterfaceWrapper) CreateWorkspaceAddress(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10147,7 +13233,7 @@ func (siw *ServerInterfaceWrapper) DownloadWorkspaceStorageObject(w http.Respons } // ------------- Path parameter "workspace_id" ------------- - var workspaceId WorkspaceID + var workspaceId UUID err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -10155,15 +13241,6 @@ func (siw *ServerInterfaceWrapper) DownloadWorkspaceStorageObject(w http.Respons return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID - - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) - return - } - ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) @@ -10171,7 +13248,7 @@ func (siw *ServerInterfaceWrapper) DownloadWorkspaceStorageObject(w http.Respons r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DownloadWorkspaceStorageObject(w, r, applicationId, workspaceId, objectId) + siw.Handler.CreateWorkspaceAddress(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10181,8 +13258,8 @@ func (siw *ServerInterfaceWrapper) DownloadWorkspaceStorageObject(w http.Respons handler.ServeHTTP(w, r) } -// CreateWorkspaceStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CreateWorkspaceStorageUpload(w http.ResponseWriter, r *http.Request) { +// DeleteWorkspaceAddress operation middleware +func (siw *ServerInterfaceWrapper) DeleteWorkspaceAddress(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10197,7 +13274,7 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceStorageUpload(w http.ResponseW } // ------------- Path parameter "workspace_id" ------------- - var workspaceId WorkspaceID + var workspaceId UUID err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -10205,42 +13282,23 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceStorageUpload(w http.ResponseW return } + // ------------- Path parameter "address_id" ------------- + var addressId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "address_id", chi.URLParam(r, "address_id"), &addressId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "address_id", Err: err}) + return + } + ctx := r.Context() ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params CreateWorkspaceStorageUploadParams - - headers := r.Header - - // ------------- Required header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey RequiredIdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } - - params.IdempotencyKey = IdempotencyKey - - } else { - err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateWorkspaceStorageUpload(w, r, applicationId, workspaceId, params) + siw.Handler.DeleteWorkspaceAddress(w, r, applicationId, workspaceId, addressId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10250,8 +13308,8 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceStorageUpload(w http.ResponseW handler.ServeHTTP(w, r) } -// CompleteWorkspaceStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CompleteWorkspaceStorageUpload(w http.ResponseWriter, r *http.Request) { +// UpdateWorkspaceAddress operation middleware +func (siw *ServerInterfaceWrapper) UpdateWorkspaceAddress(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10266,7 +13324,7 @@ func (siw *ServerInterfaceWrapper) CompleteWorkspaceStorageUpload(w http.Respons } // ------------- Path parameter "workspace_id" ------------- - var workspaceId WorkspaceID + var workspaceId UUID err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -10274,12 +13332,12 @@ func (siw *ServerInterfaceWrapper) CompleteWorkspaceStorageUpload(w http.Respons return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "address_id" ------------- + var addressId UUID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "address_id", chi.URLParam(r, "address_id"), &addressId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "address_id", Err: err}) return } @@ -10290,7 +13348,7 @@ func (siw *ServerInterfaceWrapper) CompleteWorkspaceStorageUpload(w http.Respons r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CompleteWorkspaceStorageUpload(w, r, applicationId, workspaceId, objectId) + siw.Handler.UpdateWorkspaceAddress(w, r, applicationId, workspaceId, addressId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10300,8 +13358,8 @@ func (siw *ServerInterfaceWrapper) CompleteWorkspaceStorageUpload(w http.Respons handler.ServeHTTP(w, r) } -// GetApplication operation middleware -func (siw *ServerInterfaceWrapper) GetApplication(w http.ResponseWriter, r *http.Request) { +// ActivateWorkspaceAddress operation middleware +func (siw *ServerInterfaceWrapper) ActivateWorkspaceAddress(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10315,50 +13373,32 @@ func (siw *ServerInterfaceWrapper) GetApplication(w http.ResponseWriter, r *http return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetApplication(w, r, applicationId) - })) + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return } - handler.ServeHTTP(w, r) -} - -// CreateAuditExport operation middleware -func (siw *ServerInterfaceWrapper) CreateAuditExport(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + // ------------- Path parameter "address_id" ------------- + var addressId UUID - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "address_id", chi.URLParam(r, "address_id"), &addressId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "address_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateAuditExport(w, r, applicationId) + siw.Handler.ActivateWorkspaceAddress(w, r, applicationId, workspaceId, addressId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10368,8 +13408,8 @@ func (siw *ServerInterfaceWrapper) CreateAuditExport(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// GetAuditExport operation middleware -func (siw *ServerInterfaceWrapper) GetAuditExport(w http.ResponseWriter, r *http.Request) { +// GetWorkspaceBillingProfile operation middleware +func (siw *ServerInterfaceWrapper) GetWorkspaceBillingProfile(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10383,25 +13423,23 @@ func (siw *ServerInterfaceWrapper) GetAuditExport(w http.ResponseWriter, r *http return } - // ------------- Path parameter "export_id" ------------- - var exportId UUID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - err = runtime.BindStyledParameterWithOptions("simple", "export_id", chi.URLParam(r, "export_id"), &exportId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "export_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetAuditExport(w, r, applicationId, exportId) + siw.Handler.GetWorkspaceBillingProfile(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10411,8 +13449,8 @@ func (siw *ServerInterfaceWrapper) GetAuditExport(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// ListAuditLogs operation middleware -func (siw *ServerInterfaceWrapper) ListAuditLogs(w http.ResponseWriter, r *http.Request) { +// UpdateWorkspaceBillingProfile operation middleware +func (siw *ServerInterfaceWrapper) UpdateWorkspaceBillingProfile(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10426,16 +13464,23 @@ func (siw *ServerInterfaceWrapper) ListAuditLogs(w http.ResponseWriter, r *http. return } - ctx := r.Context() + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListAuditLogs(w, r, applicationId) + siw.Handler.UpdateWorkspaceBillingProfile(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10445,8 +13490,8 @@ func (siw *ServerInterfaceWrapper) ListAuditLogs(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// GetAuditLog operation middleware -func (siw *ServerInterfaceWrapper) GetAuditLog(w http.ResponseWriter, r *http.Request) { +// ListMyWorkspaceInvitations operation middleware +func (siw *ServerInterfaceWrapper) ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10460,25 +13505,23 @@ func (siw *ServerInterfaceWrapper) GetAuditLog(w http.ResponseWriter, r *http.Re return } - // ------------- Path parameter "audit_id" ------------- - var auditId UUID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - err = runtime.BindStyledParameterWithOptions("simple", "audit_id", chi.URLParam(r, "audit_id"), &auditId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "audit_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetAuditLog(w, r, applicationId, auditId) + siw.Handler.ListMyWorkspaceInvitations(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10488,8 +13531,8 @@ func (siw *ServerInterfaceWrapper) GetAuditLog(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// UpdateAuthConfig operation middleware -func (siw *ServerInterfaceWrapper) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) { +// CreateMyWorkspaceInvitation operation middleware +func (siw *ServerInterfaceWrapper) CreateMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10503,16 +13546,23 @@ func (siw *ServerInterfaceWrapper) UpdateAuthConfig(w http.ResponseWriter, r *ht return } - ctx := r.Context() + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateAuthConfig(w, r, applicationId) + siw.Handler.CreateMyWorkspaceInvitation(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10522,8 +13572,8 @@ func (siw *ServerInterfaceWrapper) UpdateAuthConfig(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// ListApplicationAuthProviders operation middleware -func (siw *ServerInterfaceWrapper) ListApplicationAuthProviders(w http.ResponseWriter, r *http.Request) { +// RevokeMyWorkspaceInvitation operation middleware +func (siw *ServerInterfaceWrapper) RevokeMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10537,50 +13587,32 @@ func (siw *ServerInterfaceWrapper) ListApplicationAuthProviders(w http.ResponseW return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListApplicationAuthProviders(w, r, applicationId) - })) + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return } - handler.ServeHTTP(w, r) -} - -// ConfigureAppleProvider operation middleware -func (siw *ServerInterfaceWrapper) ConfigureAppleProvider(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ConfigureAppleProvider(w, r, applicationId) + siw.Handler.RevokeMyWorkspaceInvitation(w, r, applicationId, workspaceId, invitationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10590,8 +13622,8 @@ func (siw *ServerInterfaceWrapper) ConfigureAppleProvider(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// ConfigureGoogleProvider operation middleware -func (siw *ServerInterfaceWrapper) ConfigureGoogleProvider(w http.ResponseWriter, r *http.Request) { +// ResendMyWorkspaceInvitation operation middleware +func (siw *ServerInterfaceWrapper) ResendMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10605,16 +13637,32 @@ func (siw *ServerInterfaceWrapper) ConfigureGoogleProvider(w http.ResponseWriter return } - ctx := r.Context() + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } + + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ConfigureGoogleProvider(w, r, applicationId) + siw.Handler.ResendMyWorkspaceInvitation(w, r, applicationId, workspaceId, invitationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10624,8 +13672,8 @@ func (siw *ServerInterfaceWrapper) ConfigureGoogleProvider(w http.ResponseWriter handler.ServeHTTP(w, r) } -// DisableApplicationAuthProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableApplicationAuthProvider(w http.ResponseWriter, r *http.Request) { +// ListMyWorkspaceMembers operation middleware +func (siw *ServerInterfaceWrapper) ListMyWorkspaceMembers(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10639,25 +13687,23 @@ func (siw *ServerInterfaceWrapper) DisableApplicationAuthProvider(w http.Respons return } - // ------------- Path parameter "provider" ------------- - var provider string + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableApplicationAuthProvider(w, r, applicationId, provider) + siw.Handler.ListMyWorkspaceMembers(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10667,8 +13713,8 @@ func (siw *ServerInterfaceWrapper) DisableApplicationAuthProvider(w http.Respons handler.ServeHTTP(w, r) } -// ListDisputes operation middleware -func (siw *ServerInterfaceWrapper) ListDisputes(w http.ResponseWriter, r *http.Request) { +// RemoveMyWorkspaceMember operation middleware +func (siw *ServerInterfaceWrapper) RemoveMyWorkspaceMember(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10682,16 +13728,32 @@ func (siw *ServerInterfaceWrapper) ListDisputes(w http.ResponseWriter, r *http.R return } - ctx := r.Context() + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListDisputes(w, r, applicationId) + siw.Handler.RemoveMyWorkspaceMember(w, r, applicationId, workspaceId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10701,8 +13763,8 @@ func (siw *ServerInterfaceWrapper) ListDisputes(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// GetDispute operation middleware -func (siw *ServerInterfaceWrapper) GetDispute(w http.ResponseWriter, r *http.Request) { +// ReplaceMyWorkspaceMemberRoles operation middleware +func (siw *ServerInterfaceWrapper) ReplaceMyWorkspaceMemberRoles(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10716,25 +13778,32 @@ func (siw *ServerInterfaceWrapper) GetDispute(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "dispute_id" ------------- - var disputeId UUID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - err = runtime.BindStyledParameterWithOptions("simple", "dispute_id", chi.URLParam(r, "dispute_id"), &disputeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "dispute_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } - ctx := r.Context() + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetDispute(w, r, applicationId, disputeId) + siw.Handler.ReplaceMyWorkspaceMemberRoles(w, r, applicationId, workspaceId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10744,8 +13813,8 @@ func (siw *ServerInterfaceWrapper) GetDispute(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// ListInvoices operation middleware -func (siw *ServerInterfaceWrapper) ListInvoices(w http.ResponseWriter, r *http.Request) { +// LeaveWorkspace operation middleware +func (siw *ServerInterfaceWrapper) LeaveWorkspace(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10759,16 +13828,23 @@ func (siw *ServerInterfaceWrapper) ListInvoices(w http.ResponseWriter, r *http.R return } - ctx := r.Context() + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } + + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInvoices(w, r, applicationId) + siw.Handler.LeaveWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10778,8 +13854,8 @@ func (siw *ServerInterfaceWrapper) ListInvoices(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// GetInvoice operation middleware -func (siw *ServerInterfaceWrapper) GetInvoice(w http.ResponseWriter, r *http.Request) { +// TransferMyWorkspaceOwnership operation middleware +func (siw *ServerInterfaceWrapper) TransferMyWorkspaceOwnership(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10793,25 +13869,23 @@ func (siw *ServerInterfaceWrapper) GetInvoice(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "invoice_id" ------------- - var invoiceId UUID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID - err = runtime.BindStyledParameterWithOptions("simple", "invoice_id", chi.URLParam(r, "invoice_id"), &invoiceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invoice_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetInvoice(w, r, applicationId, invoiceId) + siw.Handler.TransferMyWorkspaceOwnership(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10821,8 +13895,8 @@ func (siw *ServerInterfaceWrapper) GetInvoice(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// ListPayments operation middleware -func (siw *ServerInterfaceWrapper) ListPayments(w http.ResponseWriter, r *http.Request) { +// ListWorkspacePermissionGrants operation middleware +func (siw *ServerInterfaceWrapper) ListWorkspacePermissionGrants(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10836,59 +13910,65 @@ func (siw *ServerInterfaceWrapper) ListPayments(w http.ResponseWriter, r *http.R return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListPayments(w, r, applicationId) - })) + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return } - handler.ServeHTTP(w, r) -} + ctx := r.Context() -// GetPayment operation middleware -func (siw *ServerInterfaceWrapper) GetPayment(w http.ResponseWriter, r *http.Request) { + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) - var err error - _ = err + r = r.WithContext(ctx) - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + // Parameter object where we will unmarshal all parameters from the context + var params ListWorkspacePermissionGrantsParams - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + // ------------- Optional query parameter "subject_type" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } return } - // ------------- Path parameter "payment_id" ------------- - var paymentId PaymentID + // ------------- Optional query parameter "subject_id" ------------- - err = runtime.BindStyledParameterWithOptions("simple", "payment_id", chi.URLParam(r, "payment_id"), &paymentId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "payment_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + // ------------- Optional query parameter "status" ------------- - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) + err = runtime.BindQueryParameterWithOptions("form", true, false, "status", r.URL.Query(), ¶ms.Status, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "status"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "status", Err: err}) + } + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetPayment(w, r, applicationId, paymentId) + siw.Handler.ListWorkspacePermissionGrants(w, r, applicationId, workspaceId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10898,8 +13978,8 @@ func (siw *ServerInterfaceWrapper) GetPayment(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// CreateRefund operation middleware -func (siw *ServerInterfaceWrapper) CreateRefund(w http.ResponseWriter, r *http.Request) { +// CreateWorkspacePermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) CreateWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10913,49 +13993,90 @@ func (siw *ServerInterfaceWrapper) CreateRefund(w http.ResponseWriter, r *http.R return } - // ------------- Path parameter "payment_id" ------------- - var paymentId PaymentID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - err = runtime.BindStyledParameterWithOptions("simple", "payment_id", chi.URLParam(r, "payment_id"), &paymentId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "payment_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params CreateRefundParams + var params CreateWorkspacePermissionGrantParams + + // ------------- Optional query parameter "subject_type" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } + return + } + + // ------------- Optional query parameter "subject_id" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } + return + } + + // ------------- Optional query parameter "status" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "status", r.URL.Query(), ¶ms.Status, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "status"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "status", Err: err}) + } + return + } headers := r.Header - // ------------- Optional header parameter "Idempotency-Key" ------------- + // ------------- Required header parameter "Idempotency-Key" ------------- if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey + var IdempotencyKey RequiredIdempotencyKey n := len(valueList) if n != 1 { siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) return } - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) return } - params.IdempotencyKey = &IdempotencyKey + params.IdempotencyKey = IdempotencyKey + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) + return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateRefund(w, r, applicationId, paymentId, params) + siw.Handler.CreateWorkspacePermissionGrant(w, r, applicationId, workspaceId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -10965,8 +14086,8 @@ func (siw *ServerInterfaceWrapper) CreateRefund(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// ListBillingProviderEvents operation middleware -func (siw *ServerInterfaceWrapper) ListBillingProviderEvents(w http.ResponseWriter, r *http.Request) { +// RevokeWorkspacePermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) RevokeWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -10980,59 +14101,60 @@ func (siw *ServerInterfaceWrapper) ListBillingProviderEvents(w http.ResponseWrit return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - r = r.WithContext(ctx) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListBillingProviderEvents(w, r, applicationId) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r) -} - -// ReplayBillingProviderEvent operation middleware -func (siw *ServerInterfaceWrapper) ReplayBillingProviderEvent(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID - - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } - // ------------- Path parameter "event_id" ------------- - var eventId UUID + // ------------- Path parameter "grant_id" ------------- + var grantId UUID - err = runtime.BindStyledParameterWithOptions("simple", "event_id", chi.URLParam(r, "event_id"), &eventId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "grant_id", chi.URLParam(r, "grant_id"), &grantId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "grant_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params RevokeWorkspacePermissionGrantParams + + headers := r.Header + + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) + return + } + + params.IfMatch = IfMatch + + } else { + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) + return + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ReplayBillingProviderEvent(w, r, applicationId, eventId) + siw.Handler.RevokeWorkspacePermissionGrant(w, r, applicationId, workspaceId, grantId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11042,8 +14164,8 @@ func (siw *ServerInterfaceWrapper) ReplayBillingProviderEvent(w http.ResponseWri handler.ServeHTTP(w, r) } -// ListBillingProviders operation middleware -func (siw *ServerInterfaceWrapper) ListBillingProviders(w http.ResponseWriter, r *http.Request) { +// GetWorkspacePermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) GetWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11057,16 +14179,32 @@ func (siw *ServerInterfaceWrapper) ListBillingProviders(w http.ResponseWriter, r return } - ctx := r.Context() + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } + + // ------------- Path parameter "grant_id" ------------- + var grantId UUID - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + err = runtime.BindStyledParameterWithOptions("simple", "grant_id", chi.URLParam(r, "grant_id"), &grantId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "grant_id", Err: err}) + return + } + + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListBillingProviders(w, r, applicationId) + siw.Handler.GetWorkspacePermissionGrant(w, r, applicationId, workspaceId, grantId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11076,8 +14214,8 @@ func (siw *ServerInterfaceWrapper) ListBillingProviders(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// CreateBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateBillingProvider(w http.ResponseWriter, r *http.Request) { +// ListWorkspaceStorageObjects operation middleware +func (siw *ServerInterfaceWrapper) ListWorkspaceStorageObjects(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11091,16 +14229,23 @@ func (siw *ServerInterfaceWrapper) CreateBillingProvider(w http.ResponseWriter, return } - ctx := r.Context() + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateBillingProvider(w, r, applicationId) + siw.Handler.ListWorkspaceStorageObjects(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11110,8 +14255,8 @@ func (siw *ServerInterfaceWrapper) CreateBillingProvider(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// DisableBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableBillingProvider(w http.ResponseWriter, r *http.Request) { +// DeleteWorkspaceStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DeleteWorkspaceStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11125,25 +14270,32 @@ func (siw *ServerInterfaceWrapper) DisableBillingProvider(w http.ResponseWriter, return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } - ctx := r.Context() + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID + + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableBillingProvider(w, r, applicationId, providerId) + siw.Handler.DeleteWorkspaceStorageObject(w, r, applicationId, workspaceId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11153,8 +14305,8 @@ func (siw *ServerInterfaceWrapper) DisableBillingProvider(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// GetBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) GetBillingProvider(w http.ResponseWriter, r *http.Request) { +// GetWorkspaceStorageObject operation middleware +func (siw *ServerInterfaceWrapper) GetWorkspaceStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11168,25 +14320,32 @@ func (siw *ServerInterfaceWrapper) GetBillingProvider(w http.ResponseWriter, r * return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } - ctx := r.Context() + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } + + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetBillingProvider(w, r, applicationId, providerId) + siw.Handler.GetWorkspaceStorageObject(w, r, applicationId, workspaceId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11196,8 +14355,8 @@ func (siw *ServerInterfaceWrapper) GetBillingProvider(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// UpdateBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateBillingProvider(w http.ResponseWriter, r *http.Request) { +// DownloadWorkspaceStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DownloadWorkspaceStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11211,25 +14370,32 @@ func (siw *ServerInterfaceWrapper) UpdateBillingProvider(w http.ResponseWriter, return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } - ctx := r.Context() + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID + + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateBillingProvider(w, r, applicationId, providerId) + siw.Handler.DownloadWorkspaceStorageObject(w, r, applicationId, workspaceId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11239,8 +14405,8 @@ func (siw *ServerInterfaceWrapper) UpdateBillingProvider(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// CreateBillingReconciliationRun operation middleware -func (siw *ServerInterfaceWrapper) CreateBillingReconciliationRun(w http.ResponseWriter, r *http.Request) { +// CreateWorkspaceStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CreateWorkspaceStorageUpload(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11254,49 +14420,51 @@ func (siw *ServerInterfaceWrapper) CreateBillingReconciliationRun(w http.Respons return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params CreateBillingReconciliationRunParams + var params CreateWorkspaceStorageUploadParams headers := r.Header - // ------------- Optional header parameter "Idempotency-Key" ------------- + // ------------- Required header parameter "Idempotency-Key" ------------- if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey + var IdempotencyKey RequiredIdempotencyKey n := len(valueList) if n != 1 { siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) return } - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) return } - params.IdempotencyKey = &IdempotencyKey + params.IdempotencyKey = IdempotencyKey + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) + return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateBillingReconciliationRun(w, r, applicationId, providerId, params) + siw.Handler.CreateWorkspaceStorageUpload(w, r, applicationId, workspaceId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11306,8 +14474,8 @@ func (siw *ServerInterfaceWrapper) CreateBillingReconciliationRun(w http.Respons handler.ServeHTTP(w, r) } -// VerifyBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyBillingProvider(w http.ResponseWriter, r *http.Request) { +// CompleteWorkspaceStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CompleteWorkspaceStorageUpload(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11321,25 +14489,32 @@ func (siw *ServerInterfaceWrapper) VerifyBillingProvider(w http.ResponseWriter, return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "workspace_id" ------------- + var workspaceId WorkspaceID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } - ctx := r.Context() + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } + + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, BearerAuthScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyBillingProvider(w, r, applicationId, providerId) + siw.Handler.CompleteWorkspaceStorageUpload(w, r, applicationId, workspaceId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11349,31 +14524,25 @@ func (siw *ServerInterfaceWrapper) VerifyBillingProvider(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// ListBillingReconciliationRuns operation middleware -func (siw *ServerInterfaceWrapper) ListBillingReconciliationRuns(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err +// AppleAuthCallback operation middleware +func (siw *ServerInterfaceWrapper) AppleAuthCallback(w http.ResponseWriter, r *http.Request) { - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.AppleAuthCallback(w, r) + })) - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) - return + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + handler.ServeHTTP(w, r) +} - r = r.WithContext(ctx) +// GoogleAuthCallback operation middleware +func (siw *ServerInterfaceWrapper) GoogleAuthCallback(w http.ResponseWriter, r *http.Request) { handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListBillingReconciliationRuns(w, r, applicationId) + siw.Handler.GoogleAuthCallback(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11383,8 +14552,8 @@ func (siw *ServerInterfaceWrapper) ListBillingReconciliationRuns(w http.Response handler.ServeHTTP(w, r) } -// GetBillingReconciliationRun operation middleware -func (siw *ServerInterfaceWrapper) GetBillingReconciliationRun(w http.ResponseWriter, r *http.Request) { +// GetApplication operation middleware +func (siw *ServerInterfaceWrapper) GetApplication(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11398,25 +14567,16 @@ func (siw *ServerInterfaceWrapper) GetBillingReconciliationRun(w http.ResponseWr return } - // ------------- Path parameter "run_id" ------------- - var runId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "run_id", chi.URLParam(r, "run_id"), &runId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "run_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetBillingReconciliationRun(w, r, applicationId, runId) + siw.Handler.GetApplication(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11426,8 +14586,8 @@ func (siw *ServerInterfaceWrapper) GetBillingReconciliationRun(w http.ResponseWr handler.ServeHTTP(w, r) } -// ListRefunds operation middleware -func (siw *ServerInterfaceWrapper) ListRefunds(w http.ResponseWriter, r *http.Request) { +// CreateAuditExport operation middleware +func (siw *ServerInterfaceWrapper) CreateAuditExport(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11443,14 +14603,14 @@ func (siw *ServerInterfaceWrapper) ListRefunds(w http.ResponseWriter, r *http.Re ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListRefunds(w, r, applicationId) + siw.Handler.CreateAuditExport(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11460,8 +14620,8 @@ func (siw *ServerInterfaceWrapper) ListRefunds(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// GetRefund operation middleware -func (siw *ServerInterfaceWrapper) GetRefund(w http.ResponseWriter, r *http.Request) { +// GetAuditExport operation middleware +func (siw *ServerInterfaceWrapper) GetAuditExport(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11475,25 +14635,25 @@ func (siw *ServerInterfaceWrapper) GetRefund(w http.ResponseWriter, r *http.Requ return } - // ------------- Path parameter "refund_id" ------------- - var refundId UUID + // ------------- Path parameter "export_id" ------------- + var exportId UUID - err = runtime.BindStyledParameterWithOptions("simple", "refund_id", chi.URLParam(r, "refund_id"), &refundId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "export_id", chi.URLParam(r, "export_id"), &exportId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "refund_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "export_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetRefund(w, r, applicationId, refundId) + siw.Handler.GetAuditExport(w, r, applicationId, exportId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11503,8 +14663,8 @@ func (siw *ServerInterfaceWrapper) GetRefund(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -// GetBillingStatistics operation middleware -func (siw *ServerInterfaceWrapper) GetBillingStatistics(w http.ResponseWriter, r *http.Request) { +// ListAuditLogs operation middleware +func (siw *ServerInterfaceWrapper) ListAuditLogs(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11520,43 +14680,14 @@ func (siw *ServerInterfaceWrapper) GetBillingStatistics(w http.ResponseWriter, r ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params GetBillingStatisticsParams - - // ------------- Optional query parameter "from" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "from", r.URL.Query(), ¶ms.From, runtime.BindQueryParameterOptions{Type: "string", Format: "date-time"}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "from"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "from", Err: err}) - } - return - } - - // ------------- Optional query parameter "to" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "to", r.URL.Query(), ¶ms.To, runtime.BindQueryParameterOptions{Type: "string", Format: "date-time"}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "to"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "to", Err: err}) - } - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetBillingStatistics(w, r, applicationId, params) + siw.Handler.ListAuditLogs(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11566,8 +14697,8 @@ func (siw *ServerInterfaceWrapper) GetBillingStatistics(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// ListSubscriptions operation middleware -func (siw *ServerInterfaceWrapper) ListSubscriptions(w http.ResponseWriter, r *http.Request) { +// GetAuditLog operation middleware +func (siw *ServerInterfaceWrapper) GetAuditLog(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11581,16 +14712,25 @@ func (siw *ServerInterfaceWrapper) ListSubscriptions(w http.ResponseWriter, r *h return } + // ------------- Path parameter "audit_id" ------------- + var auditId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "audit_id", chi.URLParam(r, "audit_id"), &auditId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "audit_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListSubscriptions(w, r, applicationId) + siw.Handler.GetAuditLog(w, r, applicationId, auditId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11600,8 +14740,8 @@ func (siw *ServerInterfaceWrapper) ListSubscriptions(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// GetSubscription operation middleware -func (siw *ServerInterfaceWrapper) GetSubscription(w http.ResponseWriter, r *http.Request) { +// UpdateAuthConfig operation middleware +func (siw *ServerInterfaceWrapper) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11615,25 +14755,16 @@ func (siw *ServerInterfaceWrapper) GetSubscription(w http.ResponseWriter, r *htt return } - // ------------- Path parameter "subscription_id" ------------- - var subscriptionId SubscriptionID - - err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetSubscription(w, r, applicationId, subscriptionId) + siw.Handler.UpdateAuthConfig(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11643,8 +14774,8 @@ func (siw *ServerInterfaceWrapper) GetSubscription(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// CancelSubscription operation middleware -func (siw *ServerInterfaceWrapper) CancelSubscription(w http.ResponseWriter, r *http.Request) { +// ListApplicationAuthProviders operation middleware +func (siw *ServerInterfaceWrapper) ListApplicationAuthProviders(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11658,49 +14789,16 @@ func (siw *ServerInterfaceWrapper) CancelSubscription(w http.ResponseWriter, r * return } - // ------------- Path parameter "subscription_id" ------------- - var subscriptionId SubscriptionID - - err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params CancelSubscriptionParams - - headers := r.Header - - // ------------- Optional header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } - - params.IdempotencyKey = &IdempotencyKey - - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CancelSubscription(w, r, applicationId, subscriptionId, params) + siw.Handler.ListApplicationAuthProviders(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11710,8 +14808,8 @@ func (siw *ServerInterfaceWrapper) CancelSubscription(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// ChangeSubscriptionPrice operation middleware -func (siw *ServerInterfaceWrapper) ChangeSubscriptionPrice(w http.ResponseWriter, r *http.Request) { +// ConfigureAppleProvider operation middleware +func (siw *ServerInterfaceWrapper) ConfigureAppleProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11725,49 +14823,16 @@ func (siw *ServerInterfaceWrapper) ChangeSubscriptionPrice(w http.ResponseWriter return } - // ------------- Path parameter "subscription_id" ------------- - var subscriptionId SubscriptionID - - err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params ChangeSubscriptionPriceParams - - headers := r.Header - - // ------------- Optional header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } - - params.IdempotencyKey = &IdempotencyKey - - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ChangeSubscriptionPrice(w, r, applicationId, subscriptionId, params) + siw.Handler.ConfigureAppleProvider(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11777,8 +14842,8 @@ func (siw *ServerInterfaceWrapper) ChangeSubscriptionPrice(w http.ResponseWriter handler.ServeHTTP(w, r) } -// ResumeSubscription operation middleware -func (siw *ServerInterfaceWrapper) ResumeSubscription(w http.ResponseWriter, r *http.Request) { +// ConfigureGoogleProvider operation middleware +func (siw *ServerInterfaceWrapper) ConfigureGoogleProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11792,49 +14857,16 @@ func (siw *ServerInterfaceWrapper) ResumeSubscription(w http.ResponseWriter, r * return } - // ------------- Path parameter "subscription_id" ------------- - var subscriptionId SubscriptionID - - err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params ResumeSubscriptionParams - - headers := r.Header - - // ------------- Optional header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } - - params.IdempotencyKey = &IdempotencyKey - - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ResumeSubscription(w, r, applicationId, subscriptionId, params) + siw.Handler.ConfigureGoogleProvider(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11844,8 +14876,8 @@ func (siw *ServerInterfaceWrapper) ResumeSubscription(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// ListClients operation middleware -func (siw *ServerInterfaceWrapper) ListClients(w http.ResponseWriter, r *http.Request) { +// DisableApplicationAuthProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableApplicationAuthProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11859,16 +14891,25 @@ func (siw *ServerInterfaceWrapper) ListClients(w http.ResponseWriter, r *http.Re return } + // ------------- Path parameter "provider" ------------- + var provider string + + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListClients(w, r, applicationId) + siw.Handler.DisableApplicationAuthProvider(w, r, applicationId, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11878,8 +14919,8 @@ func (siw *ServerInterfaceWrapper) ListClients(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// CreateClient operation middleware -func (siw *ServerInterfaceWrapper) CreateClient(w http.ResponseWriter, r *http.Request) { +// ListDisputes operation middleware +func (siw *ServerInterfaceWrapper) ListDisputes(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11895,14 +14936,14 @@ func (siw *ServerInterfaceWrapper) CreateClient(w http.ResponseWriter, r *http.R ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateClient(w, r, applicationId) + siw.Handler.ListDisputes(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11912,8 +14953,8 @@ func (siw *ServerInterfaceWrapper) CreateClient(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// DisableClient operation middleware -func (siw *ServerInterfaceWrapper) DisableClient(w http.ResponseWriter, r *http.Request) { +// GetDispute operation middleware +func (siw *ServerInterfaceWrapper) GetDispute(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11927,25 +14968,25 @@ func (siw *ServerInterfaceWrapper) DisableClient(w http.ResponseWriter, r *http. return } - // ------------- Path parameter "client_id" ------------- - var clientId string + // ------------- Path parameter "dispute_id" ------------- + var disputeId UUID - err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "dispute_id", chi.URLParam(r, "dispute_id"), &disputeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "dispute_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableClient(w, r, applicationId, clientId) + siw.Handler.GetDispute(w, r, applicationId, disputeId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11955,8 +14996,8 @@ func (siw *ServerInterfaceWrapper) DisableClient(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// UpdateClient operation middleware -func (siw *ServerInterfaceWrapper) UpdateClient(w http.ResponseWriter, r *http.Request) { +// ListInvoices operation middleware +func (siw *ServerInterfaceWrapper) ListInvoices(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -11970,25 +15011,16 @@ func (siw *ServerInterfaceWrapper) UpdateClient(w http.ResponseWriter, r *http.R return } - // ------------- Path parameter "client_id" ------------- - var clientId string + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) - return - } + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateClient(w, r, applicationId, clientId) + siw.Handler.ListInvoices(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -11998,8 +15030,8 @@ func (siw *ServerInterfaceWrapper) UpdateClient(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// RotateClientSecret operation middleware -func (siw *ServerInterfaceWrapper) RotateClientSecret(w http.ResponseWriter, r *http.Request) { +// GetInvoice operation middleware +func (siw *ServerInterfaceWrapper) GetInvoice(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12013,25 +15045,25 @@ func (siw *ServerInterfaceWrapper) RotateClientSecret(w http.ResponseWriter, r * return } - // ------------- Path parameter "client_id" ------------- - var clientId string + // ------------- Path parameter "invoice_id" ------------- + var invoiceId UUID - err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "invoice_id", chi.URLParam(r, "invoice_id"), &invoiceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invoice_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RotateClientSecret(w, r, applicationId, clientId) + siw.Handler.GetInvoice(w, r, applicationId, invoiceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12041,8 +15073,8 @@ func (siw *ServerInterfaceWrapper) RotateClientSecret(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// ListDelegations operation middleware -func (siw *ServerInterfaceWrapper) ListDelegations(w http.ResponseWriter, r *http.Request) { +// ListPayments operation middleware +func (siw *ServerInterfaceWrapper) ListPayments(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12058,14 +15090,14 @@ func (siw *ServerInterfaceWrapper) ListDelegations(w http.ResponseWriter, r *htt ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListDelegations(w, r, applicationId) + siw.Handler.ListPayments(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12075,8 +15107,8 @@ func (siw *ServerInterfaceWrapper) ListDelegations(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// CreateDelegation operation middleware -func (siw *ServerInterfaceWrapper) CreateDelegation(w http.ResponseWriter, r *http.Request) { +// GetPayment operation middleware +func (siw *ServerInterfaceWrapper) GetPayment(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12090,16 +15122,25 @@ func (siw *ServerInterfaceWrapper) CreateDelegation(w http.ResponseWriter, r *ht return } + // ------------- Path parameter "payment_id" ------------- + var paymentId PaymentID + + err = runtime.BindStyledParameterWithOptions("simple", "payment_id", chi.URLParam(r, "payment_id"), &paymentId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "payment_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateDelegation(w, r, applicationId) + siw.Handler.GetPayment(w, r, applicationId, paymentId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12109,8 +15150,8 @@ func (siw *ServerInterfaceWrapper) CreateDelegation(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// GetDelegation operation middleware -func (siw *ServerInterfaceWrapper) GetDelegation(w http.ResponseWriter, r *http.Request) { +// CreateRefund operation middleware +func (siw *ServerInterfaceWrapper) CreateRefund(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12124,25 +15165,49 @@ func (siw *ServerInterfaceWrapper) GetDelegation(w http.ResponseWriter, r *http. return } - // ------------- Path parameter "delegation_id" ------------- - var delegationId UUID + // ------------- Path parameter "payment_id" ------------- + var paymentId PaymentID - err = runtime.BindStyledParameterWithOptions("simple", "delegation_id", chi.URLParam(r, "delegation_id"), &delegationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "payment_id", chi.URLParam(r, "payment_id"), &paymentId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delegation_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "payment_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params CreateRefundParams + + headers := r.Header + + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = &IdempotencyKey + + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetDelegation(w, r, applicationId, delegationId) + siw.Handler.CreateRefund(w, r, applicationId, paymentId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12152,8 +15217,8 @@ func (siw *ServerInterfaceWrapper) GetDelegation(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// RevokeDelegation operation middleware -func (siw *ServerInterfaceWrapper) RevokeDelegation(w http.ResponseWriter, r *http.Request) { +// ListBillingProviderEvents operation middleware +func (siw *ServerInterfaceWrapper) ListBillingProviderEvents(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12167,25 +15232,16 @@ func (siw *ServerInterfaceWrapper) RevokeDelegation(w http.ResponseWriter, r *ht return } - // ------------- Path parameter "delegation_id" ------------- - var delegationId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "delegation_id", chi.URLParam(r, "delegation_id"), &delegationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delegation_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RevokeDelegation(w, r, applicationId, delegationId) + siw.Handler.ListBillingProviderEvents(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12195,8 +15251,8 @@ func (siw *ServerInterfaceWrapper) RevokeDelegation(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// ListApplicationDomains operation middleware -func (siw *ServerInterfaceWrapper) ListApplicationDomains(w http.ResponseWriter, r *http.Request) { +// ReplayBillingProviderEvent operation middleware +func (siw *ServerInterfaceWrapper) ReplayBillingProviderEvent(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12210,16 +15266,25 @@ func (siw *ServerInterfaceWrapper) ListApplicationDomains(w http.ResponseWriter, return } + // ------------- Path parameter "event_id" ------------- + var eventId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "event_id", chi.URLParam(r, "event_id"), &eventId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListApplicationDomains(w, r, applicationId) + siw.Handler.ReplayBillingProviderEvent(w, r, applicationId, eventId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12229,8 +15294,8 @@ func (siw *ServerInterfaceWrapper) ListApplicationDomains(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// CreateApplicationDomain operation middleware -func (siw *ServerInterfaceWrapper) CreateApplicationDomain(w http.ResponseWriter, r *http.Request) { +// ListBillingProviders operation middleware +func (siw *ServerInterfaceWrapper) ListBillingProviders(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12246,14 +15311,14 @@ func (siw *ServerInterfaceWrapper) CreateApplicationDomain(w http.ResponseWriter ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateApplicationDomain(w, r, applicationId) + siw.Handler.ListBillingProviders(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12263,8 +15328,8 @@ func (siw *ServerInterfaceWrapper) CreateApplicationDomain(w http.ResponseWriter handler.ServeHTTP(w, r) } -// DeleteApplicationDomain operation middleware -func (siw *ServerInterfaceWrapper) DeleteApplicationDomain(w http.ResponseWriter, r *http.Request) { +// CreateBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12278,25 +15343,16 @@ func (siw *ServerInterfaceWrapper) DeleteApplicationDomain(w http.ResponseWriter return } - // ------------- Path parameter "domain_id" ------------- - var domainId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "domain_id", chi.URLParam(r, "domain_id"), &domainId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "domain_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteApplicationDomain(w, r, applicationId, domainId) + siw.Handler.CreateBillingProvider(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12306,8 +15362,8 @@ func (siw *ServerInterfaceWrapper) DeleteApplicationDomain(w http.ResponseWriter handler.ServeHTTP(w, r) } -// VerifyApplicationDomain operation middleware -func (siw *ServerInterfaceWrapper) VerifyApplicationDomain(w http.ResponseWriter, r *http.Request) { +// DisableBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12321,25 +15377,25 @@ func (siw *ServerInterfaceWrapper) VerifyApplicationDomain(w http.ResponseWriter return } - // ------------- Path parameter "domain_id" ------------- - var domainId UUID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "domain_id", chi.URLParam(r, "domain_id"), &domainId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "domain_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyApplicationDomain(w, r, applicationId, domainId) + siw.Handler.DisableBillingProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12349,8 +15405,8 @@ func (siw *ServerInterfaceWrapper) VerifyApplicationDomain(w http.ResponseWriter handler.ServeHTTP(w, r) } -// ListEntitlements operation middleware -func (siw *ServerInterfaceWrapper) ListEntitlements(w http.ResponseWriter, r *http.Request) { +// GetBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) GetBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12364,16 +15420,25 @@ func (siw *ServerInterfaceWrapper) ListEntitlements(w http.ResponseWriter, r *ht return } + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListEntitlements(w, r, applicationId) + siw.Handler.GetBillingProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12383,8 +15448,8 @@ func (siw *ServerInterfaceWrapper) ListEntitlements(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// CreateEntitlement operation middleware -func (siw *ServerInterfaceWrapper) CreateEntitlement(w http.ResponseWriter, r *http.Request) { +// UpdateBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12398,16 +15463,25 @@ func (siw *ServerInterfaceWrapper) CreateEntitlement(w http.ResponseWriter, r *h return } + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateEntitlement(w, r, applicationId) + siw.Handler.UpdateBillingProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12417,8 +15491,8 @@ func (siw *ServerInterfaceWrapper) CreateEntitlement(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// GetEntitlement operation middleware -func (siw *ServerInterfaceWrapper) GetEntitlement(w http.ResponseWriter, r *http.Request) { +// CreateBillingReconciliationRun operation middleware +func (siw *ServerInterfaceWrapper) CreateBillingReconciliationRun(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12432,25 +15506,49 @@ func (siw *ServerInterfaceWrapper) GetEntitlement(w http.ResponseWriter, r *http return } - // ------------- Path parameter "entitlement_id" ------------- - var entitlementId UUID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "entitlement_id", chi.URLParam(r, "entitlement_id"), &entitlementId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "entitlement_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params CreateBillingReconciliationRunParams + + headers := r.Header + + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = &IdempotencyKey + + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetEntitlement(w, r, applicationId, entitlementId) + siw.Handler.CreateBillingReconciliationRun(w, r, applicationId, providerId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12460,8 +15558,8 @@ func (siw *ServerInterfaceWrapper) GetEntitlement(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// RestoreEntitlement operation middleware -func (siw *ServerInterfaceWrapper) RestoreEntitlement(w http.ResponseWriter, r *http.Request) { +// VerifyBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12475,25 +15573,25 @@ func (siw *ServerInterfaceWrapper) RestoreEntitlement(w http.ResponseWriter, r * return } - // ------------- Path parameter "entitlement_id" ------------- - var entitlementId UUID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "entitlement_id", chi.URLParam(r, "entitlement_id"), &entitlementId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "entitlement_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RestoreEntitlement(w, r, applicationId, entitlementId) + siw.Handler.VerifyBillingProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12503,8 +15601,8 @@ func (siw *ServerInterfaceWrapper) RestoreEntitlement(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// RevokeEntitlement operation middleware -func (siw *ServerInterfaceWrapper) RevokeEntitlement(w http.ResponseWriter, r *http.Request) { +// ListBillingReconciliationRuns operation middleware +func (siw *ServerInterfaceWrapper) ListBillingReconciliationRuns(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12518,25 +15616,16 @@ func (siw *ServerInterfaceWrapper) RevokeEntitlement(w http.ResponseWriter, r *h return } - // ------------- Path parameter "entitlement_id" ------------- - var entitlementId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "entitlement_id", chi.URLParam(r, "entitlement_id"), &entitlementId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "entitlement_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RevokeEntitlement(w, r, applicationId, entitlementId) + siw.Handler.ListBillingReconciliationRuns(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12546,8 +15635,8 @@ func (siw *ServerInterfaceWrapper) RevokeEntitlement(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// ListEventTypes operation middleware -func (siw *ServerInterfaceWrapper) ListEventTypes(w http.ResponseWriter, r *http.Request) { +// GetBillingReconciliationRun operation middleware +func (siw *ServerInterfaceWrapper) GetBillingReconciliationRun(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12561,16 +15650,25 @@ func (siw *ServerInterfaceWrapper) ListEventTypes(w http.ResponseWriter, r *http return } + // ------------- Path parameter "run_id" ------------- + var runId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "run_id", chi.URLParam(r, "run_id"), &runId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "run_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListEventTypes(w, r, applicationId) + siw.Handler.GetBillingReconciliationRun(w, r, applicationId, runId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12580,8 +15678,8 @@ func (siw *ServerInterfaceWrapper) ListEventTypes(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// CreateEventType operation middleware -func (siw *ServerInterfaceWrapper) CreateEventType(w http.ResponseWriter, r *http.Request) { +// ListRefunds operation middleware +func (siw *ServerInterfaceWrapper) ListRefunds(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12597,14 +15695,14 @@ func (siw *ServerInterfaceWrapper) CreateEventType(w http.ResponseWriter, r *htt ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateEventType(w, r, applicationId) + siw.Handler.ListRefunds(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12614,8 +15712,8 @@ func (siw *ServerInterfaceWrapper) CreateEventType(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// ArchiveEventType operation middleware -func (siw *ServerInterfaceWrapper) ArchiveEventType(w http.ResponseWriter, r *http.Request) { +// GetRefund operation middleware +func (siw *ServerInterfaceWrapper) GetRefund(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12629,25 +15727,25 @@ func (siw *ServerInterfaceWrapper) ArchiveEventType(w http.ResponseWriter, r *ht return } - // ------------- Path parameter "event_type_id" ------------- - var eventTypeId UUID + // ------------- Path parameter "refund_id" ------------- + var refundId UUID - err = runtime.BindStyledParameterWithOptions("simple", "event_type_id", chi.URLParam(r, "event_type_id"), &eventTypeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "refund_id", chi.URLParam(r, "refund_id"), &refundId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_type_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "refund_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ArchiveEventType(w, r, applicationId, eventTypeId) + siw.Handler.GetRefund(w, r, applicationId, refundId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12657,8 +15755,8 @@ func (siw *ServerInterfaceWrapper) ArchiveEventType(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// GetEventType operation middleware -func (siw *ServerInterfaceWrapper) GetEventType(w http.ResponseWriter, r *http.Request) { +// GetBillingStatistics operation middleware +func (siw *ServerInterfaceWrapper) GetBillingStatistics(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12672,25 +15770,45 @@ func (siw *ServerInterfaceWrapper) GetEventType(w http.ResponseWriter, r *http.R return } - // ------------- Path parameter "event_type_id" ------------- - var eventTypeId UUID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "event_type_id", chi.URLParam(r, "event_type_id"), &eventTypeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params GetBillingStatisticsParams + + // ------------- Optional query parameter "from" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "from", r.URL.Query(), ¶ms.From, runtime.BindQueryParameterOptions{Type: "string", Format: "date-time"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_type_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "from"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "from", Err: err}) + } return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + // ------------- Optional query parameter "to" ------------- - r = r.WithContext(ctx) + err = runtime.BindQueryParameterWithOptions("form", true, false, "to", r.URL.Query(), ¶ms.To, runtime.BindQueryParameterOptions{Type: "string", Format: "date-time"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "to"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "to", Err: err}) + } + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetEventType(w, r, applicationId, eventTypeId) + siw.Handler.GetBillingStatistics(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12700,8 +15818,8 @@ func (siw *ServerInterfaceWrapper) GetEventType(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// UpdateEventType operation middleware -func (siw *ServerInterfaceWrapper) UpdateEventType(w http.ResponseWriter, r *http.Request) { +// ListSubscriptions operation middleware +func (siw *ServerInterfaceWrapper) ListSubscriptions(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12715,25 +15833,16 @@ func (siw *ServerInterfaceWrapper) UpdateEventType(w http.ResponseWriter, r *htt return } - // ------------- Path parameter "event_type_id" ------------- - var eventTypeId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "event_type_id", chi.URLParam(r, "event_type_id"), &eventTypeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_type_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateEventType(w, r, applicationId, eventTypeId) + siw.Handler.ListSubscriptions(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12743,8 +15852,8 @@ func (siw *ServerInterfaceWrapper) UpdateEventType(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// ListEvents operation middleware -func (siw *ServerInterfaceWrapper) ListEvents(w http.ResponseWriter, r *http.Request) { +// GetSubscription operation middleware +func (siw *ServerInterfaceWrapper) GetSubscription(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12758,16 +15867,25 @@ func (siw *ServerInterfaceWrapper) ListEvents(w http.ResponseWriter, r *http.Req return } + // ------------- Path parameter "subscription_id" ------------- + var subscriptionId SubscriptionID + + err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListEvents(w, r, applicationId) + siw.Handler.GetSubscription(w, r, applicationId, subscriptionId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12777,8 +15895,8 @@ func (siw *ServerInterfaceWrapper) ListEvents(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// GetEvent operation middleware -func (siw *ServerInterfaceWrapper) GetEvent(w http.ResponseWriter, r *http.Request) { +// CancelSubscription operation middleware +func (siw *ServerInterfaceWrapper) CancelSubscription(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12792,25 +15910,49 @@ func (siw *ServerInterfaceWrapper) GetEvent(w http.ResponseWriter, r *http.Reque return } - // ------------- Path parameter "event_id" ------------- - var eventId UUID + // ------------- Path parameter "subscription_id" ------------- + var subscriptionId SubscriptionID - err = runtime.BindStyledParameterWithOptions("simple", "event_id", chi.URLParam(r, "event_id"), &eventId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params CancelSubscriptionParams + + headers := r.Header + + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = &IdempotencyKey + + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetEvent(w, r, applicationId, eventId) + siw.Handler.CancelSubscription(w, r, applicationId, subscriptionId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12820,8 +15962,8 @@ func (siw *ServerInterfaceWrapper) GetEvent(w http.ResponseWriter, r *http.Reque handler.ServeHTTP(w, r) } -// ListFeatures operation middleware -func (siw *ServerInterfaceWrapper) ListFeatures(w http.ResponseWriter, r *http.Request) { +// ChangeSubscriptionPrice operation middleware +func (siw *ServerInterfaceWrapper) ChangeSubscriptionPrice(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12835,16 +15977,49 @@ func (siw *ServerInterfaceWrapper) ListFeatures(w http.ResponseWriter, r *http.R return } + // ------------- Path parameter "subscription_id" ------------- + var subscriptionId SubscriptionID + + err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params ChangeSubscriptionPriceParams + + headers := r.Header + + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = &IdempotencyKey + + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListFeatures(w, r, applicationId) + siw.Handler.ChangeSubscriptionPrice(w, r, applicationId, subscriptionId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12854,8 +16029,8 @@ func (siw *ServerInterfaceWrapper) ListFeatures(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// CreateFeature operation middleware -func (siw *ServerInterfaceWrapper) CreateFeature(w http.ResponseWriter, r *http.Request) { +// ResumeSubscription operation middleware +func (siw *ServerInterfaceWrapper) ResumeSubscription(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12869,16 +16044,49 @@ func (siw *ServerInterfaceWrapper) CreateFeature(w http.ResponseWriter, r *http. return } + // ------------- Path parameter "subscription_id" ------------- + var subscriptionId SubscriptionID + + err = runtime.BindStyledParameterWithOptions("simple", "subscription_id", chi.URLParam(r, "subscription_id"), &subscriptionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subscription_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params ResumeSubscriptionParams + + headers := r.Header + + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = &IdempotencyKey + + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateFeature(w, r, applicationId) + siw.Handler.ResumeSubscription(w, r, applicationId, subscriptionId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12888,8 +16096,8 @@ func (siw *ServerInterfaceWrapper) CreateFeature(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// UpdateInternalApplicationConfig operation middleware -func (siw *ServerInterfaceWrapper) UpdateInternalApplicationConfig(w http.ResponseWriter, r *http.Request) { +// ListClients operation middleware +func (siw *ServerInterfaceWrapper) ListClients(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12905,14 +16113,14 @@ func (siw *ServerInterfaceWrapper) UpdateInternalApplicationConfig(w http.Respon ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateInternalApplicationConfig(w, r, applicationId) + siw.Handler.ListClients(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12922,8 +16130,8 @@ func (siw *ServerInterfaceWrapper) UpdateInternalApplicationConfig(w http.Respon handler.ServeHTTP(w, r) } -// ListLocalEntitlementRequests operation middleware -func (siw *ServerInterfaceWrapper) ListLocalEntitlementRequests(w http.ResponseWriter, r *http.Request) { +// CreateClient operation middleware +func (siw *ServerInterfaceWrapper) CreateClient(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12939,14 +16147,14 @@ func (siw *ServerInterfaceWrapper) ListLocalEntitlementRequests(w http.ResponseW ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListLocalEntitlementRequests(w, r, applicationId) + siw.Handler.CreateClient(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12956,8 +16164,8 @@ func (siw *ServerInterfaceWrapper) ListLocalEntitlementRequests(w http.ResponseW handler.ServeHTTP(w, r) } -// GetLocalEntitlementRequest operation middleware -func (siw *ServerInterfaceWrapper) GetLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { +// DisableClient operation middleware +func (siw *ServerInterfaceWrapper) DisableClient(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -12971,25 +16179,25 @@ func (siw *ServerInterfaceWrapper) GetLocalEntitlementRequest(w http.ResponseWri return } - // ------------- Path parameter "request_id" ------------- - var requestId RequestID + // ------------- Path parameter "client_id" ------------- + var clientId string - err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetLocalEntitlementRequest(w, r, applicationId, requestId) + siw.Handler.DisableClient(w, r, applicationId, clientId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -12999,8 +16207,8 @@ func (siw *ServerInterfaceWrapper) GetLocalEntitlementRequest(w http.ResponseWri handler.ServeHTTP(w, r) } -// ApproveLocalEntitlementRequest operation middleware -func (siw *ServerInterfaceWrapper) ApproveLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { +// GetClient operation middleware +func (siw *ServerInterfaceWrapper) GetClient(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13014,25 +16222,25 @@ func (siw *ServerInterfaceWrapper) ApproveLocalEntitlementRequest(w http.Respons return } - // ------------- Path parameter "request_id" ------------- - var requestId RequestID + // ------------- Path parameter "client_id" ------------- + var clientId string - err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ApproveLocalEntitlementRequest(w, r, applicationId, requestId) + siw.Handler.GetClient(w, r, applicationId, clientId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13042,8 +16250,8 @@ func (siw *ServerInterfaceWrapper) ApproveLocalEntitlementRequest(w http.Respons handler.ServeHTTP(w, r) } -// RejectLocalEntitlementRequest operation middleware -func (siw *ServerInterfaceWrapper) RejectLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { +// UpdateClient operation middleware +func (siw *ServerInterfaceWrapper) UpdateClient(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13057,25 +16265,25 @@ func (siw *ServerInterfaceWrapper) RejectLocalEntitlementRequest(w http.Response return } - // ------------- Path parameter "request_id" ------------- - var requestId RequestID + // ------------- Path parameter "client_id" ------------- + var clientId string - err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RejectLocalEntitlementRequest(w, r, applicationId, requestId) + siw.Handler.UpdateClient(w, r, applicationId, clientId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13085,8 +16293,8 @@ func (siw *ServerInterfaceWrapper) RejectLocalEntitlementRequest(w http.Response handler.ServeHTTP(w, r) } -// ReopenLocalEntitlementRequest operation middleware -func (siw *ServerInterfaceWrapper) ReopenLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { +// RotateClientSecret operation middleware +func (siw *ServerInterfaceWrapper) RotateClientSecret(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13100,25 +16308,25 @@ func (siw *ServerInterfaceWrapper) ReopenLocalEntitlementRequest(w http.Response return } - // ------------- Path parameter "request_id" ------------- - var requestId RequestID + // ------------- Path parameter "client_id" ------------- + var clientId string - err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ReopenLocalEntitlementRequest(w, r, applicationId, requestId) + siw.Handler.RotateClientSecret(w, r, applicationId, clientId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13128,8 +16336,8 @@ func (siw *ServerInterfaceWrapper) ReopenLocalEntitlementRequest(w http.Response handler.ServeHTTP(w, r) } -// ListNotificationProviders operation middleware -func (siw *ServerInterfaceWrapper) ListNotificationProviders(w http.ResponseWriter, r *http.Request) { +// ListDelegations operation middleware +func (siw *ServerInterfaceWrapper) ListDelegations(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13145,14 +16353,14 @@ func (siw *ServerInterfaceWrapper) ListNotificationProviders(w http.ResponseWrit ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListNotificationProviders(w, r, applicationId) + siw.Handler.ListDelegations(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13162,8 +16370,8 @@ func (siw *ServerInterfaceWrapper) ListNotificationProviders(w http.ResponseWrit handler.ServeHTTP(w, r) } -// CreateNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateNotificationProvider(w http.ResponseWriter, r *http.Request) { +// CreateDelegation operation middleware +func (siw *ServerInterfaceWrapper) CreateDelegation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13179,14 +16387,14 @@ func (siw *ServerInterfaceWrapper) CreateNotificationProvider(w http.ResponseWri ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateNotificationProvider(w, r, applicationId) + siw.Handler.CreateDelegation(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13196,8 +16404,8 @@ func (siw *ServerInterfaceWrapper) CreateNotificationProvider(w http.ResponseWri handler.ServeHTTP(w, r) } -// DisableNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableNotificationProvider(w http.ResponseWriter, r *http.Request) { +// GetDelegation operation middleware +func (siw *ServerInterfaceWrapper) GetDelegation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13211,25 +16419,25 @@ func (siw *ServerInterfaceWrapper) DisableNotificationProvider(w http.ResponseWr return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "delegation_id" ------------- + var delegationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "delegation_id", chi.URLParam(r, "delegation_id"), &delegationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delegation_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableNotificationProvider(w, r, applicationId, providerId) + siw.Handler.GetDelegation(w, r, applicationId, delegationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13239,8 +16447,8 @@ func (siw *ServerInterfaceWrapper) DisableNotificationProvider(w http.ResponseWr handler.ServeHTTP(w, r) } -// GetNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) GetNotificationProvider(w http.ResponseWriter, r *http.Request) { +// RevokeDelegation operation middleware +func (siw *ServerInterfaceWrapper) RevokeDelegation(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13254,25 +16462,25 @@ func (siw *ServerInterfaceWrapper) GetNotificationProvider(w http.ResponseWriter return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "delegation_id" ------------- + var delegationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "delegation_id", chi.URLParam(r, "delegation_id"), &delegationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delegation_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetNotificationProvider(w, r, applicationId, providerId) + siw.Handler.RevokeDelegation(w, r, applicationId, delegationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13282,8 +16490,8 @@ func (siw *ServerInterfaceWrapper) GetNotificationProvider(w http.ResponseWriter handler.ServeHTTP(w, r) } -// UpdateNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateNotificationProvider(w http.ResponseWriter, r *http.Request) { +// ListApplicationDomains operation middleware +func (siw *ServerInterfaceWrapper) ListApplicationDomains(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13297,25 +16505,16 @@ func (siw *ServerInterfaceWrapper) UpdateNotificationProvider(w http.ResponseWri return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateNotificationProvider(w, r, applicationId, providerId) + siw.Handler.ListApplicationDomains(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13325,8 +16524,8 @@ func (siw *ServerInterfaceWrapper) UpdateNotificationProvider(w http.ResponseWri handler.ServeHTTP(w, r) } -// TestNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) TestNotificationProvider(w http.ResponseWriter, r *http.Request) { +// CreateApplicationDomain operation middleware +func (siw *ServerInterfaceWrapper) CreateApplicationDomain(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13340,49 +16539,16 @@ func (siw *ServerInterfaceWrapper) TestNotificationProvider(w http.ResponseWrite return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params TestNotificationProviderParams - - headers := r.Header - - // ------------- Optional header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } - - params.IdempotencyKey = &IdempotencyKey - - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.TestNotificationProvider(w, r, applicationId, providerId, params) + siw.Handler.CreateApplicationDomain(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13392,8 +16558,8 @@ func (siw *ServerInterfaceWrapper) TestNotificationProvider(w http.ResponseWrite handler.ServeHTTP(w, r) } -// VerifyNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyNotificationProvider(w http.ResponseWriter, r *http.Request) { +// DeleteApplicationDomain operation middleware +func (siw *ServerInterfaceWrapper) DeleteApplicationDomain(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13407,25 +16573,25 @@ func (siw *ServerInterfaceWrapper) VerifyNotificationProvider(w http.ResponseWri return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "domain_id" ------------- + var domainId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "domain_id", chi.URLParam(r, "domain_id"), &domainId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "domain_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyNotificationProvider(w, r, applicationId, providerId) + siw.Handler.DeleteApplicationDomain(w, r, applicationId, domainId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13435,8 +16601,8 @@ func (siw *ServerInterfaceWrapper) VerifyNotificationProvider(w http.ResponseWri handler.ServeHTTP(w, r) } -// ListNotificationTemplateVariables operation middleware -func (siw *ServerInterfaceWrapper) ListNotificationTemplateVariables(w http.ResponseWriter, r *http.Request) { +// VerifyApplicationDomain operation middleware +func (siw *ServerInterfaceWrapper) VerifyApplicationDomain(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13450,16 +16616,25 @@ func (siw *ServerInterfaceWrapper) ListNotificationTemplateVariables(w http.Resp return } + // ------------- Path parameter "domain_id" ------------- + var domainId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "domain_id", chi.URLParam(r, "domain_id"), &domainId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "domain_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListNotificationTemplateVariables(w, r, applicationId) + siw.Handler.VerifyApplicationDomain(w, r, applicationId, domainId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13469,8 +16644,8 @@ func (siw *ServerInterfaceWrapper) ListNotificationTemplateVariables(w http.Resp handler.ServeHTTP(w, r) } -// ListNotificationTemplates operation middleware -func (siw *ServerInterfaceWrapper) ListNotificationTemplates(w http.ResponseWriter, r *http.Request) { +// ListEntitlements operation middleware +func (siw *ServerInterfaceWrapper) ListEntitlements(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13486,14 +16661,14 @@ func (siw *ServerInterfaceWrapper) ListNotificationTemplates(w http.ResponseWrit ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListNotificationTemplates(w, r, applicationId) + siw.Handler.ListEntitlements(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13503,8 +16678,8 @@ func (siw *ServerInterfaceWrapper) ListNotificationTemplates(w http.ResponseWrit handler.ServeHTTP(w, r) } -// CreateNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) CreateNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// CreateEntitlement operation middleware +func (siw *ServerInterfaceWrapper) CreateEntitlement(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13520,14 +16695,14 @@ func (siw *ServerInterfaceWrapper) CreateNotificationTemplate(w http.ResponseWri ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateNotificationTemplate(w, r, applicationId) + siw.Handler.CreateEntitlement(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13537,8 +16712,8 @@ func (siw *ServerInterfaceWrapper) CreateNotificationTemplate(w http.ResponseWri handler.ServeHTTP(w, r) } -// GetNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) GetNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// GetEntitlement operation middleware +func (siw *ServerInterfaceWrapper) GetEntitlement(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13552,25 +16727,25 @@ func (siw *ServerInterfaceWrapper) GetNotificationTemplate(w http.ResponseWriter return } - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "entitlement_id" ------------- + var entitlementId UUID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "entitlement_id", chi.URLParam(r, "entitlement_id"), &entitlementId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "entitlement_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetNotificationTemplate(w, r, applicationId, templateId) + siw.Handler.GetEntitlement(w, r, applicationId, entitlementId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13580,8 +16755,8 @@ func (siw *ServerInterfaceWrapper) GetNotificationTemplate(w http.ResponseWriter handler.ServeHTTP(w, r) } -// UpdateNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) UpdateNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// AdjustEntitlement operation middleware +func (siw *ServerInterfaceWrapper) AdjustEntitlement(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13595,25 +16770,25 @@ func (siw *ServerInterfaceWrapper) UpdateNotificationTemplate(w http.ResponseWri return } - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "entitlement_id" ------------- + var entitlementId UUID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "entitlement_id", chi.URLParam(r, "entitlement_id"), &entitlementId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "entitlement_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateNotificationTemplate(w, r, applicationId, templateId) + siw.Handler.AdjustEntitlement(w, r, applicationId, entitlementId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13623,8 +16798,8 @@ func (siw *ServerInterfaceWrapper) UpdateNotificationTemplate(w http.ResponseWri handler.ServeHTTP(w, r) } -// ArchiveNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) ArchiveNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// RestoreEntitlement operation middleware +func (siw *ServerInterfaceWrapper) RestoreEntitlement(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13638,25 +16813,25 @@ func (siw *ServerInterfaceWrapper) ArchiveNotificationTemplate(w http.ResponseWr return } - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "entitlement_id" ------------- + var entitlementId UUID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "entitlement_id", chi.URLParam(r, "entitlement_id"), &entitlementId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "entitlement_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ArchiveNotificationTemplate(w, r, applicationId, templateId) + siw.Handler.RestoreEntitlement(w, r, applicationId, entitlementId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13666,8 +16841,8 @@ func (siw *ServerInterfaceWrapper) ArchiveNotificationTemplate(w http.ResponseWr handler.ServeHTTP(w, r) } -// PreviewNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) PreviewNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// RevokeEntitlement operation middleware +func (siw *ServerInterfaceWrapper) RevokeEntitlement(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13681,25 +16856,25 @@ func (siw *ServerInterfaceWrapper) PreviewNotificationTemplate(w http.ResponseWr return } - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "entitlement_id" ------------- + var entitlementId UUID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "entitlement_id", chi.URLParam(r, "entitlement_id"), &entitlementId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "entitlement_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PreviewNotificationTemplate(w, r, applicationId, templateId) + siw.Handler.RevokeEntitlement(w, r, applicationId, entitlementId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13709,8 +16884,8 @@ func (siw *ServerInterfaceWrapper) PreviewNotificationTemplate(w http.ResponseWr handler.ServeHTTP(w, r) } -// PublishNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) PublishNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// ListEventTypes operation middleware +func (siw *ServerInterfaceWrapper) ListEventTypes(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13724,25 +16899,16 @@ func (siw *ServerInterfaceWrapper) PublishNotificationTemplate(w http.ResponseWr return } - // ------------- Path parameter "template_id" ------------- - var templateId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PublishNotificationTemplate(w, r, applicationId, templateId) + siw.Handler.ListEventTypes(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13752,8 +16918,8 @@ func (siw *ServerInterfaceWrapper) PublishNotificationTemplate(w http.ResponseWr handler.ServeHTTP(w, r) } -// ListNotifications operation middleware -func (siw *ServerInterfaceWrapper) ListNotifications(w http.ResponseWriter, r *http.Request) { +// CreateEventType operation middleware +func (siw *ServerInterfaceWrapper) CreateEventType(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13769,14 +16935,14 @@ func (siw *ServerInterfaceWrapper) ListNotifications(w http.ResponseWriter, r *h ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListNotifications(w, r, applicationId) + siw.Handler.CreateEventType(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13786,8 +16952,8 @@ func (siw *ServerInterfaceWrapper) ListNotifications(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// QueueNotification operation middleware -func (siw *ServerInterfaceWrapper) QueueNotification(w http.ResponseWriter, r *http.Request) { +// ArchiveEventType operation middleware +func (siw *ServerInterfaceWrapper) ArchiveEventType(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13801,40 +16967,25 @@ func (siw *ServerInterfaceWrapper) QueueNotification(w http.ResponseWriter, r *h return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) - - // Parameter object where we will unmarshal all parameters from the context - var params QueueNotificationParams + // ------------- Path parameter "event_type_id" ------------- + var eventTypeId UUID - headers := r.Header + err = runtime.BindStyledParameterWithOptions("simple", "event_type_id", chi.URLParam(r, "event_type_id"), &eventTypeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_type_id", Err: err}) + return + } - // ------------- Optional header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - params.IdempotencyKey = &IdempotencyKey + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) - } + r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.QueueNotification(w, r, applicationId, params) + siw.Handler.ArchiveEventType(w, r, applicationId, eventTypeId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13844,8 +16995,8 @@ func (siw *ServerInterfaceWrapper) QueueNotification(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// GetNotificationStatistics operation middleware -func (siw *ServerInterfaceWrapper) GetNotificationStatistics(w http.ResponseWriter, r *http.Request) { +// GetEventType operation middleware +func (siw *ServerInterfaceWrapper) GetEventType(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13859,16 +17010,25 @@ func (siw *ServerInterfaceWrapper) GetNotificationStatistics(w http.ResponseWrit return } + // ------------- Path parameter "event_type_id" ------------- + var eventTypeId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "event_type_id", chi.URLParam(r, "event_type_id"), &eventTypeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_type_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetNotificationStatistics(w, r, applicationId) + siw.Handler.GetEventType(w, r, applicationId, eventTypeId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13878,8 +17038,8 @@ func (siw *ServerInterfaceWrapper) GetNotificationStatistics(w http.ResponseWrit handler.ServeHTTP(w, r) } -// GetNotification operation middleware -func (siw *ServerInterfaceWrapper) GetNotification(w http.ResponseWriter, r *http.Request) { +// UpdateEventType operation middleware +func (siw *ServerInterfaceWrapper) UpdateEventType(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13893,25 +17053,25 @@ func (siw *ServerInterfaceWrapper) GetNotification(w http.ResponseWriter, r *htt return } - // ------------- Path parameter "notification_id" ------------- - var notificationId UUID + // ------------- Path parameter "event_type_id" ------------- + var eventTypeId UUID - err = runtime.BindStyledParameterWithOptions("simple", "notification_id", chi.URLParam(r, "notification_id"), ¬ificationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "event_type_id", chi.URLParam(r, "event_type_id"), &eventTypeId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "notification_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_type_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetNotification(w, r, applicationId, notificationId) + siw.Handler.UpdateEventType(w, r, applicationId, eventTypeId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13921,8 +17081,8 @@ func (siw *ServerInterfaceWrapper) GetNotification(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// RetryNotification operation middleware -func (siw *ServerInterfaceWrapper) RetryNotification(w http.ResponseWriter, r *http.Request) { +// ListEvents operation middleware +func (siw *ServerInterfaceWrapper) ListEvents(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13936,25 +17096,16 @@ func (siw *ServerInterfaceWrapper) RetryNotification(w http.ResponseWriter, r *h return } - // ------------- Path parameter "notification_id" ------------- - var notificationId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "notification_id", chi.URLParam(r, "notification_id"), ¬ificationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "notification_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RetryNotification(w, r, applicationId, notificationId) + siw.Handler.ListEvents(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13964,8 +17115,8 @@ func (siw *ServerInterfaceWrapper) RetryNotification(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// ListOAuthConsents operation middleware -func (siw *ServerInterfaceWrapper) ListOAuthConsents(w http.ResponseWriter, r *http.Request) { +// GetEvent operation middleware +func (siw *ServerInterfaceWrapper) GetEvent(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -13979,16 +17130,25 @@ func (siw *ServerInterfaceWrapper) ListOAuthConsents(w http.ResponseWriter, r *h return } + // ------------- Path parameter "event_id" ------------- + var eventId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "event_id", chi.URLParam(r, "event_id"), &eventId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "event_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOAuthConsents(w, r, applicationId) + siw.Handler.GetEvent(w, r, applicationId, eventId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -13998,8 +17158,8 @@ func (siw *ServerInterfaceWrapper) ListOAuthConsents(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// RevokeOAuthConsent operation middleware -func (siw *ServerInterfaceWrapper) RevokeOAuthConsent(w http.ResponseWriter, r *http.Request) { +// ListFeatures operation middleware +func (siw *ServerInterfaceWrapper) ListFeatures(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14013,34 +17173,16 @@ func (siw *ServerInterfaceWrapper) RevokeOAuthConsent(w http.ResponseWriter, r * return } - // ------------- Path parameter "user_id" ------------- - var userId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) - return - } - - // ------------- Path parameter "client_id" ------------- - var clientId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RevokeOAuthConsent(w, r, applicationId, userId, clientId) + siw.Handler.ListFeatures(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14050,8 +17192,8 @@ func (siw *ServerInterfaceWrapper) RevokeOAuthConsent(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// ListProducts operation middleware -func (siw *ServerInterfaceWrapper) ListProducts(w http.ResponseWriter, r *http.Request) { +// CreateFeature operation middleware +func (siw *ServerInterfaceWrapper) CreateFeature(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14067,14 +17209,14 @@ func (siw *ServerInterfaceWrapper) ListProducts(w http.ResponseWriter, r *http.R ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListProducts(w, r, applicationId) + siw.Handler.CreateFeature(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14084,8 +17226,8 @@ func (siw *ServerInterfaceWrapper) ListProducts(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// CreateProduct operation middleware -func (siw *ServerInterfaceWrapper) CreateProduct(w http.ResponseWriter, r *http.Request) { +// UpdateInternalApplicationConfig operation middleware +func (siw *ServerInterfaceWrapper) UpdateInternalApplicationConfig(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14101,14 +17243,14 @@ func (siw *ServerInterfaceWrapper) CreateProduct(w http.ResponseWriter, r *http. ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateProduct(w, r, applicationId) + siw.Handler.UpdateInternalApplicationConfig(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14118,8 +17260,8 @@ func (siw *ServerInterfaceWrapper) CreateProduct(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// GetProduct operation middleware -func (siw *ServerInterfaceWrapper) GetProduct(w http.ResponseWriter, r *http.Request) { +// ListApplicationInvitationsControl operation middleware +func (siw *ServerInterfaceWrapper) ListApplicationInvitationsControl(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14133,25 +17275,16 @@ func (siw *ServerInterfaceWrapper) GetProduct(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "product_id" ------------- - var productId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetProduct(w, r, applicationId, productId) + siw.Handler.ListApplicationInvitationsControl(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14161,8 +17294,8 @@ func (siw *ServerInterfaceWrapper) GetProduct(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// UpdateProduct operation middleware -func (siw *ServerInterfaceWrapper) UpdateProduct(w http.ResponseWriter, r *http.Request) { +// CreateApplicationInvitationControl operation middleware +func (siw *ServerInterfaceWrapper) CreateApplicationInvitationControl(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14176,25 +17309,16 @@ func (siw *ServerInterfaceWrapper) UpdateProduct(w http.ResponseWriter, r *http. return } - // ------------- Path parameter "product_id" ------------- - var productId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateProduct(w, r, applicationId, productId) + siw.Handler.CreateApplicationInvitationControl(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14204,8 +17328,8 @@ func (siw *ServerInterfaceWrapper) UpdateProduct(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// ListPrices operation middleware -func (siw *ServerInterfaceWrapper) ListPrices(w http.ResponseWriter, r *http.Request) { +// RevokeApplicationInvitationControl operation middleware +func (siw *ServerInterfaceWrapper) RevokeApplicationInvitationControl(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14219,25 +17343,25 @@ func (siw *ServerInterfaceWrapper) ListPrices(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "product_id" ------------- - var productId UUID + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListPrices(w, r, applicationId, productId) + siw.Handler.RevokeApplicationInvitationControl(w, r, applicationId, invitationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14247,8 +17371,8 @@ func (siw *ServerInterfaceWrapper) ListPrices(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// CreatePrice operation middleware -func (siw *ServerInterfaceWrapper) CreatePrice(w http.ResponseWriter, r *http.Request) { +// GetApplicationInvitationControl operation middleware +func (siw *ServerInterfaceWrapper) GetApplicationInvitationControl(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14262,25 +17386,25 @@ func (siw *ServerInterfaceWrapper) CreatePrice(w http.ResponseWriter, r *http.Re return } - // ------------- Path parameter "product_id" ------------- - var productId UUID + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreatePrice(w, r, applicationId, productId) + siw.Handler.GetApplicationInvitationControl(w, r, applicationId, invitationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14290,8 +17414,8 @@ func (siw *ServerInterfaceWrapper) CreatePrice(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// UpdatePublicApplicationConfig operation middleware -func (siw *ServerInterfaceWrapper) UpdatePublicApplicationConfig(w http.ResponseWriter, r *http.Request) { +// ResendApplicationInvitationControl operation middleware +func (siw *ServerInterfaceWrapper) ResendApplicationInvitationControl(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14305,16 +17429,25 @@ func (siw *ServerInterfaceWrapper) UpdatePublicApplicationConfig(w http.Response return } + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdatePublicApplicationConfig(w, r, applicationId) + siw.Handler.ResendApplicationInvitationControl(w, r, applicationId, invitationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14324,8 +17457,8 @@ func (siw *ServerInterfaceWrapper) UpdatePublicApplicationConfig(w http.Response handler.ServeHTTP(w, r) } -// ListRoleAssignments operation middleware -func (siw *ServerInterfaceWrapper) ListRoleAssignments(w http.ResponseWriter, r *http.Request) { +// ListLocalEntitlementRequests operation middleware +func (siw *ServerInterfaceWrapper) ListLocalEntitlementRequests(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14341,14 +17474,14 @@ func (siw *ServerInterfaceWrapper) ListRoleAssignments(w http.ResponseWriter, r ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListRoleAssignments(w, r, applicationId) + siw.Handler.ListLocalEntitlementRequests(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14358,8 +17491,8 @@ func (siw *ServerInterfaceWrapper) ListRoleAssignments(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// CreateRoleAssignment operation middleware -func (siw *ServerInterfaceWrapper) CreateRoleAssignment(w http.ResponseWriter, r *http.Request) { +// GetLocalEntitlementRequest operation middleware +func (siw *ServerInterfaceWrapper) GetLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14373,16 +17506,25 @@ func (siw *ServerInterfaceWrapper) CreateRoleAssignment(w http.ResponseWriter, r return } + // ------------- Path parameter "request_id" ------------- + var requestId RequestID + + err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateRoleAssignment(w, r, applicationId) + siw.Handler.GetLocalEntitlementRequest(w, r, applicationId, requestId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14392,8 +17534,8 @@ func (siw *ServerInterfaceWrapper) CreateRoleAssignment(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// DeleteRoleAssignment operation middleware -func (siw *ServerInterfaceWrapper) DeleteRoleAssignment(w http.ResponseWriter, r *http.Request) { +// ApproveLocalEntitlementRequest operation middleware +func (siw *ServerInterfaceWrapper) ApproveLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14407,25 +17549,25 @@ func (siw *ServerInterfaceWrapper) DeleteRoleAssignment(w http.ResponseWriter, r return } - // ------------- Path parameter "assignment_id" ------------- - var assignmentId UUID + // ------------- Path parameter "request_id" ------------- + var requestId RequestID - err = runtime.BindStyledParameterWithOptions("simple", "assignment_id", chi.URLParam(r, "assignment_id"), &assignmentId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "assignment_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteRoleAssignment(w, r, applicationId, assignmentId) + siw.Handler.ApproveLocalEntitlementRequest(w, r, applicationId, requestId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14435,8 +17577,8 @@ func (siw *ServerInterfaceWrapper) DeleteRoleAssignment(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// ListRoles operation middleware -func (siw *ServerInterfaceWrapper) ListRoles(w http.ResponseWriter, r *http.Request) { +// RejectLocalEntitlementRequest operation middleware +func (siw *ServerInterfaceWrapper) RejectLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14450,16 +17592,25 @@ func (siw *ServerInterfaceWrapper) ListRoles(w http.ResponseWriter, r *http.Requ return } + // ------------- Path parameter "request_id" ------------- + var requestId RequestID + + err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListRoles(w, r, applicationId) + siw.Handler.RejectLocalEntitlementRequest(w, r, applicationId, requestId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14469,8 +17620,8 @@ func (siw *ServerInterfaceWrapper) ListRoles(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -// CreateRole operation middleware -func (siw *ServerInterfaceWrapper) CreateRole(w http.ResponseWriter, r *http.Request) { +// ReopenLocalEntitlementRequest operation middleware +func (siw *ServerInterfaceWrapper) ReopenLocalEntitlementRequest(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14484,16 +17635,25 @@ func (siw *ServerInterfaceWrapper) CreateRole(w http.ResponseWriter, r *http.Req return } + // ------------- Path parameter "request_id" ------------- + var requestId RequestID + + err = runtime.BindStyledParameterWithOptions("simple", "request_id", chi.URLParam(r, "request_id"), &requestId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "request_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateRole(w, r, applicationId) + siw.Handler.ReopenLocalEntitlementRequest(w, r, applicationId, requestId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14503,8 +17663,8 @@ func (siw *ServerInterfaceWrapper) CreateRole(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// DeleteRole operation middleware -func (siw *ServerInterfaceWrapper) DeleteRole(w http.ResponseWriter, r *http.Request) { +// ListNotificationProviders operation middleware +func (siw *ServerInterfaceWrapper) ListNotificationProviders(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14518,25 +17678,16 @@ func (siw *ServerInterfaceWrapper) DeleteRole(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "role_id" ------------- - var roleId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "role_id", chi.URLParam(r, "role_id"), &roleId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "role_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteRole(w, r, applicationId, roleId) + siw.Handler.ListNotificationProviders(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14546,8 +17697,8 @@ func (siw *ServerInterfaceWrapper) DeleteRole(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// GetRole operation middleware -func (siw *ServerInterfaceWrapper) GetRole(w http.ResponseWriter, r *http.Request) { +// CreateNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14561,25 +17712,16 @@ func (siw *ServerInterfaceWrapper) GetRole(w http.ResponseWriter, r *http.Reques return } - // ------------- Path parameter "role_id" ------------- - var roleId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "role_id", chi.URLParam(r, "role_id"), &roleId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "role_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetRole(w, r, applicationId, roleId) + siw.Handler.CreateNotificationProvider(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14589,8 +17731,8 @@ func (siw *ServerInterfaceWrapper) GetRole(w http.ResponseWriter, r *http.Reques handler.ServeHTTP(w, r) } -// UpdateRole operation middleware -func (siw *ServerInterfaceWrapper) UpdateRole(w http.ResponseWriter, r *http.Request) { +// DisableNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14604,25 +17746,25 @@ func (siw *ServerInterfaceWrapper) UpdateRole(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "role_id" ------------- - var roleId UUID + // ------------- Path parameter "provider_id" ------------- + var providerId UUID - err = runtime.BindStyledParameterWithOptions("simple", "role_id", chi.URLParam(r, "role_id"), &roleId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "role_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateRole(w, r, applicationId, roleId) + siw.Handler.DisableNotificationProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14632,8 +17774,8 @@ func (siw *ServerInterfaceWrapper) UpdateRole(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// ListSenderIdentities operation middleware -func (siw *ServerInterfaceWrapper) ListSenderIdentities(w http.ResponseWriter, r *http.Request) { +// GetNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) GetNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14647,50 +17789,25 @@ func (siw *ServerInterfaceWrapper) ListSenderIdentities(w http.ResponseWriter, r return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListSenderIdentities(w, r, applicationId) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r) -} - -// CreateSenderIdentity operation middleware -func (siw *ServerInterfaceWrapper) CreateSenderIdentity(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + // ------------- Path parameter "provider_id" ------------- + var providerId UUID - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateSenderIdentity(w, r, applicationId) + siw.Handler.GetNotificationProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14700,8 +17817,8 @@ func (siw *ServerInterfaceWrapper) CreateSenderIdentity(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// SetDefaultSenderIdentity operation middleware -func (siw *ServerInterfaceWrapper) SetDefaultSenderIdentity(w http.ResponseWriter, r *http.Request) { +// UpdateNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14715,25 +17832,25 @@ func (siw *ServerInterfaceWrapper) SetDefaultSenderIdentity(w http.ResponseWrite return } - // ------------- Path parameter "sender_id" ------------- - var senderId UUID + // ------------- Path parameter "provider_id" ------------- + var providerId UUID - err = runtime.BindStyledParameterWithOptions("simple", "sender_id", chi.URLParam(r, "sender_id"), &senderId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "sender_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.SetDefaultSenderIdentity(w, r, applicationId, senderId) + siw.Handler.UpdateNotificationProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14743,8 +17860,8 @@ func (siw *ServerInterfaceWrapper) SetDefaultSenderIdentity(w http.ResponseWrite handler.ServeHTTP(w, r) } -// GetApplicationStatistics operation middleware -func (siw *ServerInterfaceWrapper) GetApplicationStatistics(w http.ResponseWriter, r *http.Request) { +// TestNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) TestNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14758,50 +17875,49 @@ func (siw *ServerInterfaceWrapper) GetApplicationStatistics(w http.ResponseWrite return } + // ------------- Path parameter "provider_id" ------------- + var providerId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetApplicationStatistics(w, r, applicationId) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } + // Parameter object where we will unmarshal all parameters from the context + var params TestNotificationProviderParams - handler.ServeHTTP(w, r) -} + headers := r.Header -// ListControlApplicationStorageObjects operation middleware -func (siw *ServerInterfaceWrapper) ListControlApplicationStorageObjects(w http.ResponseWriter, r *http.Request) { + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } - var err error - _ = err + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } - // ------------- Path parameter "application_id" ------------- - var applicationId ApplicationID + params.IdempotencyKey = &IdempotencyKey - err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) - return } - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListControlApplicationStorageObjects(w, r, applicationId) + siw.Handler.TestNotificationProvider(w, r, applicationId, providerId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14811,8 +17927,8 @@ func (siw *ServerInterfaceWrapper) ListControlApplicationStorageObjects(w http.R handler.ServeHTTP(w, r) } -// DeleteControlApplicationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DeleteControlApplicationStorageObject(w http.ResponseWriter, r *http.Request) { +// VerifyNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14826,41 +17942,25 @@ func (siw *ServerInterfaceWrapper) DeleteControlApplicationStorageObject(w http. return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "provider_id" ------------- + var providerId UUID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params DeleteControlApplicationStorageObjectParams - - // ------------- Optional query parameter "force" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "force", r.URL.Query(), ¶ms.Force, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "force"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "force", Err: err}) - } - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteControlApplicationStorageObject(w, r, applicationId, objectId, params) + siw.Handler.VerifyNotificationProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14870,8 +17970,8 @@ func (siw *ServerInterfaceWrapper) DeleteControlApplicationStorageObject(w http. handler.ServeHTTP(w, r) } -// GetControlApplicationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) GetControlApplicationStorageObject(w http.ResponseWriter, r *http.Request) { +// ListNotificationTemplateVariables operation middleware +func (siw *ServerInterfaceWrapper) ListNotificationTemplateVariables(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14885,25 +17985,16 @@ func (siw *ServerInterfaceWrapper) GetControlApplicationStorageObject(w http.Res return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID - - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetControlApplicationStorageObject(w, r, applicationId, objectId) + siw.Handler.ListNotificationTemplateVariables(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14913,8 +18004,8 @@ func (siw *ServerInterfaceWrapper) GetControlApplicationStorageObject(w http.Res handler.ServeHTTP(w, r) } -// DownloadControlApplicationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DownloadControlApplicationStorageObject(w http.ResponseWriter, r *http.Request) { +// ListNotificationTemplates operation middleware +func (siw *ServerInterfaceWrapper) ListNotificationTemplates(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14928,25 +18019,16 @@ func (siw *ServerInterfaceWrapper) DownloadControlApplicationStorageObject(w htt return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID - - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DownloadControlApplicationStorageObject(w, r, applicationId, objectId) + siw.Handler.ListNotificationTemplates(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14956,8 +18038,8 @@ func (siw *ServerInterfaceWrapper) DownloadControlApplicationStorageObject(w htt handler.ServeHTTP(w, r) } -// ListApplicationStorageProviders operation middleware -func (siw *ServerInterfaceWrapper) ListApplicationStorageProviders(w http.ResponseWriter, r *http.Request) { +// CreateNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) CreateNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -14973,14 +18055,14 @@ func (siw *ServerInterfaceWrapper) ListApplicationStorageProviders(w http.Respon ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListApplicationStorageProviders(w, r, applicationId) + siw.Handler.CreateNotificationTemplate(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -14990,8 +18072,8 @@ func (siw *ServerInterfaceWrapper) ListApplicationStorageProviders(w http.Respon handler.ServeHTTP(w, r) } -// CreateApplicationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { +// GetNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) GetNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15005,16 +18087,25 @@ func (siw *ServerInterfaceWrapper) CreateApplicationStorageProvider(w http.Respo return } + // ------------- Path parameter "template_id" ------------- + var templateId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateApplicationStorageProvider(w, r, applicationId) + siw.Handler.GetNotificationTemplate(w, r, applicationId, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15024,8 +18115,8 @@ func (siw *ServerInterfaceWrapper) CreateApplicationStorageProvider(w http.Respo handler.ServeHTTP(w, r) } -// DisableApplicationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { +// UpdateNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) UpdateNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15039,41 +18130,25 @@ func (siw *ServerInterfaceWrapper) DisableApplicationStorageProvider(w http.Resp return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params DisableApplicationStorageProviderParams - - // ------------- Optional query parameter "confirm_affected_objects" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "confirm_affected_objects", r.URL.Query(), ¶ms.ConfirmAffectedObjects, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "confirm_affected_objects"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "confirm_affected_objects", Err: err}) - } - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableApplicationStorageProvider(w, r, applicationId, providerId, params) + siw.Handler.UpdateNotificationTemplate(w, r, applicationId, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15083,8 +18158,8 @@ func (siw *ServerInterfaceWrapper) DisableApplicationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// GetApplicationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) GetApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { +// ArchiveNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) ArchiveNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15098,25 +18173,25 @@ func (siw *ServerInterfaceWrapper) GetApplicationStorageProvider(w http.Response return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetApplicationStorageProvider(w, r, applicationId, providerId) + siw.Handler.ArchiveNotificationTemplate(w, r, applicationId, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15126,8 +18201,8 @@ func (siw *ServerInterfaceWrapper) GetApplicationStorageProvider(w http.Response handler.ServeHTTP(w, r) } -// UpdateApplicationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { +// PreviewNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) PreviewNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15141,25 +18216,25 @@ func (siw *ServerInterfaceWrapper) UpdateApplicationStorageProvider(w http.Respo return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateApplicationStorageProvider(w, r, applicationId, providerId) + siw.Handler.PreviewNotificationTemplate(w, r, applicationId, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15169,8 +18244,8 @@ func (siw *ServerInterfaceWrapper) UpdateApplicationStorageProvider(w http.Respo handler.ServeHTTP(w, r) } -// EnableApplicationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) EnableApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { +// PublishNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) PublishNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15184,25 +18259,25 @@ func (siw *ServerInterfaceWrapper) EnableApplicationStorageProvider(w http.Respo return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.EnableApplicationStorageProvider(w, r, applicationId, providerId) + siw.Handler.PublishNotificationTemplate(w, r, applicationId, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15212,8 +18287,8 @@ func (siw *ServerInterfaceWrapper) EnableApplicationStorageProvider(w http.Respo handler.ServeHTTP(w, r) } -// VerifyApplicationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { +// ListNotifications operation middleware +func (siw *ServerInterfaceWrapper) ListNotifications(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15227,25 +18302,16 @@ func (siw *ServerInterfaceWrapper) VerifyApplicationStorageProvider(w http.Respo return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyApplicationStorageProvider(w, r, applicationId, providerId) + siw.Handler.ListNotifications(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15255,8 +18321,8 @@ func (siw *ServerInterfaceWrapper) VerifyApplicationStorageProvider(w http.Respo handler.ServeHTTP(w, r) } -// CreateControlApplicationStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CreateControlApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { +// GetNotificationStatistics operation middleware +func (siw *ServerInterfaceWrapper) GetNotificationStatistics(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15272,42 +18338,14 @@ func (siw *ServerInterfaceWrapper) CreateControlApplicationStorageUpload(w http. ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params CreateControlApplicationStorageUploadParams - - headers := r.Header - - // ------------- Required header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey RequiredIdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } - - params.IdempotencyKey = IdempotencyKey - - } else { - err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateControlApplicationStorageUpload(w, r, applicationId, params) + siw.Handler.GetNotificationStatistics(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15317,8 +18355,8 @@ func (siw *ServerInterfaceWrapper) CreateControlApplicationStorageUpload(w http. handler.ServeHTTP(w, r) } -// CompleteControlApplicationStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CompleteControlApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { +// GetNotification operation middleware +func (siw *ServerInterfaceWrapper) GetNotification(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15332,25 +18370,25 @@ func (siw *ServerInterfaceWrapper) CompleteControlApplicationStorageUpload(w htt return } - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "notification_id" ------------- + var notificationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "notification_id", chi.URLParam(r, "notification_id"), ¬ificationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "notification_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CompleteControlApplicationStorageUpload(w, r, applicationId, objectId) + siw.Handler.GetNotification(w, r, applicationId, notificationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15360,8 +18398,8 @@ func (siw *ServerInterfaceWrapper) CompleteControlApplicationStorageUpload(w htt handler.ServeHTTP(w, r) } -// ListUsers operation middleware -func (siw *ServerInterfaceWrapper) ListUsers(w http.ResponseWriter, r *http.Request) { +// RetryNotification operation middleware +func (siw *ServerInterfaceWrapper) RetryNotification(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15375,16 +18413,25 @@ func (siw *ServerInterfaceWrapper) ListUsers(w http.ResponseWriter, r *http.Requ return } + // ------------- Path parameter "notification_id" ------------- + var notificationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "notification_id", chi.URLParam(r, "notification_id"), ¬ificationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "notification_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListUsers(w, r, applicationId) + siw.Handler.RetryNotification(w, r, applicationId, notificationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15394,8 +18441,8 @@ func (siw *ServerInterfaceWrapper) ListUsers(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -// CreateUser operation middleware -func (siw *ServerInterfaceWrapper) CreateUser(w http.ResponseWriter, r *http.Request) { +// ListOAuthConsents operation middleware +func (siw *ServerInterfaceWrapper) ListOAuthConsents(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15411,14 +18458,14 @@ func (siw *ServerInterfaceWrapper) CreateUser(w http.ResponseWriter, r *http.Req ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateUser(w, r, applicationId) + siw.Handler.ListOAuthConsents(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15428,8 +18475,8 @@ func (siw *ServerInterfaceWrapper) CreateUser(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// GetUser operation middleware -func (siw *ServerInterfaceWrapper) GetUser(w http.ResponseWriter, r *http.Request) { +// RevokeOAuthConsent operation middleware +func (siw *ServerInterfaceWrapper) RevokeOAuthConsent(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15452,16 +18499,25 @@ func (siw *ServerInterfaceWrapper) GetUser(w http.ResponseWriter, r *http.Reques return } + // ------------- Path parameter "client_id" ------------- + var clientId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "client_id", chi.URLParam(r, "client_id"), &clientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "client_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetUser(w, r, applicationId, userId) + siw.Handler.RevokeOAuthConsent(w, r, applicationId, userId, clientId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15471,8 +18527,8 @@ func (siw *ServerInterfaceWrapper) GetUser(w http.ResponseWriter, r *http.Reques handler.ServeHTTP(w, r) } -// UpdateUser operation middleware -func (siw *ServerInterfaceWrapper) UpdateUser(w http.ResponseWriter, r *http.Request) { +// ListControlPermissionGrants operation middleware +func (siw *ServerInterfaceWrapper) ListControlPermissionGrants(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15486,25 +18542,71 @@ func (siw *ServerInterfaceWrapper) UpdateUser(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params ListControlPermissionGrantsParams + + // ------------- Optional query parameter "subject_type" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } return } - ctx := r.Context() + // ------------- Optional query parameter "subject_id" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } + return + } + + // ------------- Optional query parameter "workspace_id" ------------- - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + err = runtime.BindQueryParameterWithOptions("form", true, false, "workspace_id", r.URL.Query(), ¶ms.WorkspaceId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "workspace_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + } + return + } - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + // ------------- Optional query parameter "status" ------------- - r = r.WithContext(ctx) + err = runtime.BindQueryParameterWithOptions("form", true, false, "status", r.URL.Query(), ¶ms.Status, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "status"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "status", Err: err}) + } + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateUser(w, r, applicationId, userId) + siw.Handler.ListControlPermissionGrants(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15514,8 +18616,8 @@ func (siw *ServerInterfaceWrapper) UpdateUser(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// ListUserAddresses operation middleware -func (siw *ServerInterfaceWrapper) ListUserAddresses(w http.ResponseWriter, r *http.Request) { +// CreateControlPermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) CreateControlPermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15529,25 +18631,96 @@ func (siw *ServerInterfaceWrapper) ListUserAddresses(w http.ResponseWriter, r *h return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params CreateControlPermissionGrantParams + + // ------------- Optional query parameter "subject_type" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } return } - ctx := r.Context() + // ------------- Optional query parameter "subject_id" ------------- - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + err = runtime.BindQueryParameterWithOptions("form", true, false, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } + return + } - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + // ------------- Optional query parameter "workspace_id" ------------- - r = r.WithContext(ctx) + err = runtime.BindQueryParameterWithOptions("form", true, false, "workspace_id", r.URL.Query(), ¶ms.WorkspaceId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "workspace_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + } + return + } + + // ------------- Optional query parameter "status" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "status", r.URL.Query(), ¶ms.Status, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "status"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "status", Err: err}) + } + return + } + + headers := r.Header + + // ------------- Required header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey RequiredIdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = IdempotencyKey + + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListUserAddresses(w, r, applicationId, userId) + siw.Handler.CreateControlPermissionGrant(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15557,8 +18730,8 @@ func (siw *ServerInterfaceWrapper) ListUserAddresses(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// RestoreUser operation middleware -func (siw *ServerInterfaceWrapper) RestoreUser(w http.ResponseWriter, r *http.Request) { +// GetControlEffectiveAccess operation middleware +func (siw *ServerInterfaceWrapper) GetControlEffectiveAccess(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15572,25 +18745,58 @@ func (siw *ServerInterfaceWrapper) RestoreUser(w http.ResponseWriter, r *http.Re return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params GetControlEffectiveAccessParams + + // ------------- Required query parameter "subject_type" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, true, "subject_type", r.URL.Query(), ¶ms.SubjectType, runtime.BindQueryParameterOptions{Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_type"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_type", Err: err}) + } return } - ctx := r.Context() + // ------------- Required query parameter "subject_id" ------------- - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + err = runtime.BindQueryParameterWithOptions("form", true, true, "subject_id", r.URL.Query(), ¶ms.SubjectId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "subject_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "subject_id", Err: err}) + } + return + } - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + // ------------- Optional query parameter "workspace_id" ------------- - r = r.WithContext(ctx) + err = runtime.BindQueryParameterWithOptions("form", true, false, "workspace_id", r.URL.Query(), ¶ms.WorkspaceId, runtime.BindQueryParameterOptions{Type: "string", Format: "uuid"}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "workspace_id"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + } + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RestoreUser(w, r, applicationId, userId) + siw.Handler.GetControlEffectiveAccess(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15600,8 +18806,8 @@ func (siw *ServerInterfaceWrapper) RestoreUser(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// ListUserSessions operation middleware -func (siw *ServerInterfaceWrapper) ListUserSessions(w http.ResponseWriter, r *http.Request) { +// RevokeControlPermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) RevokeControlPermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15615,25 +18821,53 @@ func (siw *ServerInterfaceWrapper) ListUserSessions(w http.ResponseWriter, r *ht return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + // ------------- Path parameter "grant_id" ------------- + var grantId UUID - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "grant_id", chi.URLParam(r, "grant_id"), &grantId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "grant_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params RevokeControlPermissionGrantParams + + headers := r.Header + + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) + return + } + + params.IfMatch = IfMatch + + } else { + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) + return + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListUserSessions(w, r, applicationId, userId) + siw.Handler.RevokeControlPermissionGrant(w, r, applicationId, grantId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15643,8 +18877,8 @@ func (siw *ServerInterfaceWrapper) ListUserSessions(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// RevokeUserSessions operation middleware -func (siw *ServerInterfaceWrapper) RevokeUserSessions(w http.ResponseWriter, r *http.Request) { +// GetControlPermissionGrant operation middleware +func (siw *ServerInterfaceWrapper) GetControlPermissionGrant(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15658,25 +18892,25 @@ func (siw *ServerInterfaceWrapper) RevokeUserSessions(w http.ResponseWriter, r * return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + // ------------- Path parameter "grant_id" ------------- + var grantId UUID - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "grant_id", chi.URLParam(r, "grant_id"), &grantId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "grant_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RevokeUserSessions(w, r, applicationId, userId) + siw.Handler.GetControlPermissionGrant(w, r, applicationId, grantId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15686,8 +18920,8 @@ func (siw *ServerInterfaceWrapper) RevokeUserSessions(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// SuspendUser operation middleware -func (siw *ServerInterfaceWrapper) SuspendUser(w http.ResponseWriter, r *http.Request) { +// ListProducts operation middleware +func (siw *ServerInterfaceWrapper) ListProducts(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15701,25 +18935,16 @@ func (siw *ServerInterfaceWrapper) SuspendUser(w http.ResponseWriter, r *http.Re return } - // ------------- Path parameter "user_id" ------------- - var userId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.SuspendUser(w, r, applicationId, userId) + siw.Handler.ListProducts(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15729,8 +18954,8 @@ func (siw *ServerInterfaceWrapper) SuspendUser(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// UnverifyUserEmail operation middleware -func (siw *ServerInterfaceWrapper) UnverifyUserEmail(w http.ResponseWriter, r *http.Request) { +// CreateProduct operation middleware +func (siw *ServerInterfaceWrapper) CreateProduct(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15744,25 +18969,16 @@ func (siw *ServerInterfaceWrapper) UnverifyUserEmail(w http.ResponseWriter, r *h return } - // ------------- Path parameter "user_id" ------------- - var userId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UnverifyUserEmail(w, r, applicationId, userId) + siw.Handler.CreateProduct(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15772,8 +18988,8 @@ func (siw *ServerInterfaceWrapper) UnverifyUserEmail(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// UnverifyUserOrganization operation middleware -func (siw *ServerInterfaceWrapper) UnverifyUserOrganization(w http.ResponseWriter, r *http.Request) { +// GetProduct operation middleware +func (siw *ServerInterfaceWrapper) GetProduct(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15787,25 +19003,25 @@ func (siw *ServerInterfaceWrapper) UnverifyUserOrganization(w http.ResponseWrite return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + // ------------- Path parameter "product_id" ------------- + var productId UUID - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UnverifyUserOrganization(w, r, applicationId, userId) + siw.Handler.GetProduct(w, r, applicationId, productId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15815,8 +19031,8 @@ func (siw *ServerInterfaceWrapper) UnverifyUserOrganization(w http.ResponseWrite handler.ServeHTTP(w, r) } -// VerifyUserEmail operation middleware -func (siw *ServerInterfaceWrapper) VerifyUserEmail(w http.ResponseWriter, r *http.Request) { +// UpdateProduct operation middleware +func (siw *ServerInterfaceWrapper) UpdateProduct(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15830,25 +19046,25 @@ func (siw *ServerInterfaceWrapper) VerifyUserEmail(w http.ResponseWriter, r *htt return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + // ------------- Path parameter "product_id" ------------- + var productId UUID - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyUserEmail(w, r, applicationId, userId) + siw.Handler.UpdateProduct(w, r, applicationId, productId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15858,8 +19074,8 @@ func (siw *ServerInterfaceWrapper) VerifyUserEmail(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// VerifyUserOrganization operation middleware -func (siw *ServerInterfaceWrapper) VerifyUserOrganization(w http.ResponseWriter, r *http.Request) { +// ListPrices operation middleware +func (siw *ServerInterfaceWrapper) ListPrices(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15873,25 +19089,25 @@ func (siw *ServerInterfaceWrapper) VerifyUserOrganization(w http.ResponseWriter, return } - // ------------- Path parameter "user_id" ------------- - var userId UUID + // ------------- Path parameter "product_id" ------------- + var productId UUID - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyUserOrganization(w, r, applicationId, userId) + siw.Handler.ListPrices(w, r, applicationId, productId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15901,8 +19117,8 @@ func (siw *ServerInterfaceWrapper) VerifyUserOrganization(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// ListWebhookDeliveries operation middleware -func (siw *ServerInterfaceWrapper) ListWebhookDeliveries(w http.ResponseWriter, r *http.Request) { +// CreatePrice operation middleware +func (siw *ServerInterfaceWrapper) CreatePrice(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15916,16 +19132,25 @@ func (siw *ServerInterfaceWrapper) ListWebhookDeliveries(w http.ResponseWriter, return } + // ------------- Path parameter "product_id" ------------- + var productId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "product_id", chi.URLParam(r, "product_id"), &productId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "product_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListWebhookDeliveries(w, r, applicationId) + siw.Handler.CreatePrice(w, r, applicationId, productId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15935,8 +19160,8 @@ func (siw *ServerInterfaceWrapper) ListWebhookDeliveries(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// GetWebhookDelivery operation middleware -func (siw *ServerInterfaceWrapper) GetWebhookDelivery(w http.ResponseWriter, r *http.Request) { +// UpdatePublicApplicationConfig operation middleware +func (siw *ServerInterfaceWrapper) UpdatePublicApplicationConfig(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15950,25 +19175,16 @@ func (siw *ServerInterfaceWrapper) GetWebhookDelivery(w http.ResponseWriter, r * return } - // ------------- Path parameter "delivery_id" ------------- - var deliveryId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "delivery_id", chi.URLParam(r, "delivery_id"), &deliveryId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delivery_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetWebhookDelivery(w, r, applicationId, deliveryId) + siw.Handler.UpdatePublicApplicationConfig(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -15978,8 +19194,8 @@ func (siw *ServerInterfaceWrapper) GetWebhookDelivery(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// ReplayWebhookDelivery operation middleware -func (siw *ServerInterfaceWrapper) ReplayWebhookDelivery(w http.ResponseWriter, r *http.Request) { +// ListRoleAssignments operation middleware +func (siw *ServerInterfaceWrapper) ListRoleAssignments(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -15993,25 +19209,16 @@ func (siw *ServerInterfaceWrapper) ReplayWebhookDelivery(w http.ResponseWriter, return } - // ------------- Path parameter "delivery_id" ------------- - var deliveryId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "delivery_id", chi.URLParam(r, "delivery_id"), &deliveryId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delivery_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ReplayWebhookDelivery(w, r, applicationId, deliveryId) + siw.Handler.ListRoleAssignments(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16021,8 +19228,8 @@ func (siw *ServerInterfaceWrapper) ReplayWebhookDelivery(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// ListWebhooks operation middleware -func (siw *ServerInterfaceWrapper) ListWebhooks(w http.ResponseWriter, r *http.Request) { +// CreateRoleAssignment operation middleware +func (siw *ServerInterfaceWrapper) CreateRoleAssignment(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16038,14 +19245,14 @@ func (siw *ServerInterfaceWrapper) ListWebhooks(w http.ResponseWriter, r *http.R ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListWebhooks(w, r, applicationId) + siw.Handler.CreateRoleAssignment(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16055,8 +19262,8 @@ func (siw *ServerInterfaceWrapper) ListWebhooks(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// CreateWebhook operation middleware -func (siw *ServerInterfaceWrapper) CreateWebhook(w http.ResponseWriter, r *http.Request) { +// DeleteRoleAssignment operation middleware +func (siw *ServerInterfaceWrapper) DeleteRoleAssignment(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16070,16 +19277,25 @@ func (siw *ServerInterfaceWrapper) CreateWebhook(w http.ResponseWriter, r *http. return } + // ------------- Path parameter "assignment_id" ------------- + var assignmentId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "assignment_id", chi.URLParam(r, "assignment_id"), &assignmentId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "assignment_id", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateWebhook(w, r, applicationId) + siw.Handler.DeleteRoleAssignment(w, r, applicationId, assignmentId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16089,8 +19305,8 @@ func (siw *ServerInterfaceWrapper) CreateWebhook(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// DisableWebhook operation middleware -func (siw *ServerInterfaceWrapper) DisableWebhook(w http.ResponseWriter, r *http.Request) { +// ListRoles operation middleware +func (siw *ServerInterfaceWrapper) ListRoles(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16104,25 +19320,16 @@ func (siw *ServerInterfaceWrapper) DisableWebhook(w http.ResponseWriter, r *http return } - // ------------- Path parameter "webhook_id" ------------- - var webhookId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableWebhook(w, r, applicationId, webhookId) + siw.Handler.ListRoles(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16132,8 +19339,8 @@ func (siw *ServerInterfaceWrapper) DisableWebhook(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// GetWebhook operation middleware -func (siw *ServerInterfaceWrapper) GetWebhook(w http.ResponseWriter, r *http.Request) { +// CreateRole operation middleware +func (siw *ServerInterfaceWrapper) CreateRole(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16147,25 +19354,16 @@ func (siw *ServerInterfaceWrapper) GetWebhook(w http.ResponseWriter, r *http.Req return } - // ------------- Path parameter "webhook_id" ------------- - var webhookId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetWebhook(w, r, applicationId, webhookId) + siw.Handler.CreateRole(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16175,8 +19373,8 @@ func (siw *ServerInterfaceWrapper) GetWebhook(w http.ResponseWriter, r *http.Req handler.ServeHTTP(w, r) } -// UpdateWebhook operation middleware -func (siw *ServerInterfaceWrapper) UpdateWebhook(w http.ResponseWriter, r *http.Request) { +// DeleteRole operation middleware +func (siw *ServerInterfaceWrapper) DeleteRole(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16190,25 +19388,25 @@ func (siw *ServerInterfaceWrapper) UpdateWebhook(w http.ResponseWriter, r *http. return } - // ------------- Path parameter "webhook_id" ------------- - var webhookId UUID + // ------------- Path parameter "role_id" ------------- + var roleId UUID - err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "role_id", chi.URLParam(r, "role_id"), &roleId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "role_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateWebhook(w, r, applicationId, webhookId) + siw.Handler.DeleteRole(w, r, applicationId, roleId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16218,8 +19416,8 @@ func (siw *ServerInterfaceWrapper) UpdateWebhook(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// RotateWebhookSecret operation middleware -func (siw *ServerInterfaceWrapper) RotateWebhookSecret(w http.ResponseWriter, r *http.Request) { +// GetRole operation middleware +func (siw *ServerInterfaceWrapper) GetRole(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16233,25 +19431,25 @@ func (siw *ServerInterfaceWrapper) RotateWebhookSecret(w http.ResponseWriter, r return } - // ------------- Path parameter "webhook_id" ------------- - var webhookId UUID + // ------------- Path parameter "role_id" ------------- + var roleId UUID - err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "role_id", chi.URLParam(r, "role_id"), &roleId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "role_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RotateWebhookSecret(w, r, applicationId, webhookId) + siw.Handler.GetRole(w, r, applicationId, roleId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16261,8 +19459,8 @@ func (siw *ServerInterfaceWrapper) RotateWebhookSecret(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// TestWebhook operation middleware -func (siw *ServerInterfaceWrapper) TestWebhook(w http.ResponseWriter, r *http.Request) { +// UpdateRole operation middleware +func (siw *ServerInterfaceWrapper) UpdateRole(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16276,49 +19474,53 @@ func (siw *ServerInterfaceWrapper) TestWebhook(w http.ResponseWriter, r *http.Re return } - // ------------- Path parameter "webhook_id" ------------- - var webhookId UUID + // ------------- Path parameter "role_id" ------------- + var roleId UUID - err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "role_id", chi.URLParam(r, "role_id"), &roleId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "role_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params TestWebhookParams + var params UpdateRoleParams headers := r.Header - // ------------- Optional header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch n := len(valueList) if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) return } - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) return } - params.IdempotencyKey = &IdempotencyKey + params.IfMatch = IfMatch + } else { + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) + return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.TestWebhook(w, r, applicationId, webhookId, params) + siw.Handler.UpdateRole(w, r, applicationId, roleId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16328,8 +19530,8 @@ func (siw *ServerInterfaceWrapper) TestWebhook(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// ListWorkspaceInvitations operation middleware -func (siw *ServerInterfaceWrapper) ListWorkspaceInvitations(w http.ResponseWriter, r *http.Request) { +// ListSenderIdentities operation middleware +func (siw *ServerInterfaceWrapper) ListSenderIdentities(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16345,14 +19547,14 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceInvitations(w http.ResponseWrite ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListWorkspaceInvitations(w, r, applicationId) + siw.Handler.ListSenderIdentities(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16362,8 +19564,8 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceInvitations(w http.ResponseWrite handler.ServeHTTP(w, r) } -// CreateWorkspaceInvitation operation middleware -func (siw *ServerInterfaceWrapper) CreateWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { +// CreateSenderIdentity operation middleware +func (siw *ServerInterfaceWrapper) CreateSenderIdentity(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16379,14 +19581,14 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceInvitation(w http.ResponseWrit ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateWorkspaceInvitation(w, r, applicationId) + siw.Handler.CreateSenderIdentity(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16396,8 +19598,8 @@ func (siw *ServerInterfaceWrapper) CreateWorkspaceInvitation(w http.ResponseWrit handler.ServeHTTP(w, r) } -// RevokeWorkspaceInvitation operation middleware -func (siw *ServerInterfaceWrapper) RevokeWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { +// SetDefaultSenderIdentity operation middleware +func (siw *ServerInterfaceWrapper) SetDefaultSenderIdentity(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16411,25 +19613,25 @@ func (siw *ServerInterfaceWrapper) RevokeWorkspaceInvitation(w http.ResponseWrit return } - // ------------- Path parameter "invitation_id" ------------- - var invitationId UUID + // ------------- Path parameter "sender_id" ------------- + var senderId UUID - err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "sender_id", chi.URLParam(r, "sender_id"), &senderId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "sender_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RevokeWorkspaceInvitation(w, r, applicationId, invitationId) + siw.Handler.SetDefaultSenderIdentity(w, r, applicationId, senderId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16439,8 +19641,8 @@ func (siw *ServerInterfaceWrapper) RevokeWorkspaceInvitation(w http.ResponseWrit handler.ServeHTTP(w, r) } -// ListWorkspaces operation middleware -func (siw *ServerInterfaceWrapper) ListWorkspaces(w http.ResponseWriter, r *http.Request) { +// GetApplicationStatistics operation middleware +func (siw *ServerInterfaceWrapper) GetApplicationStatistics(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16456,14 +19658,14 @@ func (siw *ServerInterfaceWrapper) ListWorkspaces(w http.ResponseWriter, r *http ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListWorkspaces(w, r, applicationId) + siw.Handler.GetApplicationStatistics(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16473,8 +19675,8 @@ func (siw *ServerInterfaceWrapper) ListWorkspaces(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// CreateWorkspace operation middleware -func (siw *ServerInterfaceWrapper) CreateWorkspace(w http.ResponseWriter, r *http.Request) { +// ListControlApplicationStorageObjects operation middleware +func (siw *ServerInterfaceWrapper) ListControlApplicationStorageObjects(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16490,14 +19692,14 @@ func (siw *ServerInterfaceWrapper) CreateWorkspace(w http.ResponseWriter, r *htt ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateWorkspace(w, r, applicationId) + siw.Handler.ListControlApplicationStorageObjects(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16507,8 +19709,8 @@ func (siw *ServerInterfaceWrapper) CreateWorkspace(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// DeleteWorkspace operation middleware -func (siw *ServerInterfaceWrapper) DeleteWorkspace(w http.ResponseWriter, r *http.Request) { +// DeleteControlApplicationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DeleteControlApplicationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16522,25 +19724,41 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspace(w http.ResponseWriter, r *htt return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params DeleteControlApplicationStorageObjectParams + + // ------------- Optional query parameter "force" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "force", r.URL.Query(), ¶ms.Force, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "force"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "force", Err: err}) + } + return + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteWorkspace(w, r, applicationId, workspaceId) + siw.Handler.DeleteControlApplicationStorageObject(w, r, applicationId, objectId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16550,8 +19768,8 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspace(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// GetWorkspace operation middleware -func (siw *ServerInterfaceWrapper) GetWorkspace(w http.ResponseWriter, r *http.Request) { +// GetControlApplicationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) GetControlApplicationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16565,25 +19783,25 @@ func (siw *ServerInterfaceWrapper) GetWorkspace(w http.ResponseWriter, r *http.R return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetWorkspace(w, r, applicationId, workspaceId) + siw.Handler.GetControlApplicationStorageObject(w, r, applicationId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16593,8 +19811,8 @@ func (siw *ServerInterfaceWrapper) GetWorkspace(w http.ResponseWriter, r *http.R handler.ServeHTTP(w, r) } -// UpdateWorkspace operation middleware -func (siw *ServerInterfaceWrapper) UpdateWorkspace(w http.ResponseWriter, r *http.Request) { +// DownloadControlApplicationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DownloadControlApplicationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16608,25 +19826,25 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspace(w http.ResponseWriter, r *htt return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateWorkspace(w, r, applicationId, workspaceId) + siw.Handler.DownloadControlApplicationStorageObject(w, r, applicationId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16636,8 +19854,8 @@ func (siw *ServerInterfaceWrapper) UpdateWorkspace(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// ListWorkspaceMembers operation middleware -func (siw *ServerInterfaceWrapper) ListWorkspaceMembers(w http.ResponseWriter, r *http.Request) { +// ListApplicationStorageProviders operation middleware +func (siw *ServerInterfaceWrapper) ListApplicationStorageProviders(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16651,25 +19869,16 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceMembers(w http.ResponseWriter, r return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListWorkspaceMembers(w, r, applicationId, workspaceId) + siw.Handler.ListApplicationStorageProviders(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16679,8 +19888,8 @@ func (siw *ServerInterfaceWrapper) ListWorkspaceMembers(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// DeleteWorkspaceMember operation middleware -func (siw *ServerInterfaceWrapper) DeleteWorkspaceMember(w http.ResponseWriter, r *http.Request) { +// CreateApplicationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16694,34 +19903,16 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceMember(w http.ResponseWriter, return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - - // ------------- Path parameter "user_id" ------------- - var userId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteWorkspaceMember(w, r, applicationId, workspaceId, userId) + siw.Handler.CreateApplicationStorageProvider(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16731,8 +19922,8 @@ func (siw *ServerInterfaceWrapper) DeleteWorkspaceMember(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// ReplaceWorkspaceMemberRoles operation middleware -func (siw *ServerInterfaceWrapper) ReplaceWorkspaceMemberRoles(w http.ResponseWriter, r *http.Request) { +// DisableApplicationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16746,34 +19937,41 @@ func (siw *ServerInterfaceWrapper) ReplaceWorkspaceMemberRoles(w http.ResponseWr return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) - return - } - - // ------------- Path parameter "user_id" ------------- - var userId UUID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params DisableApplicationStorageProviderParams + + // ------------- Optional query parameter "confirm_affected_objects" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "confirm_affected_objects", r.URL.Query(), ¶ms.ConfirmAffectedObjects, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "confirm_affected_objects"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "confirm_affected_objects", Err: err}) + } + return + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ReplaceWorkspaceMemberRoles(w, r, applicationId, workspaceId, userId) + siw.Handler.DisableApplicationStorageProvider(w, r, applicationId, providerId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16783,8 +19981,8 @@ func (siw *ServerInterfaceWrapper) ReplaceWorkspaceMemberRoles(w http.ResponseWr handler.ServeHTTP(w, r) } -// RecoverWorkspaceOwnership operation middleware -func (siw *ServerInterfaceWrapper) RecoverWorkspaceOwnership(w http.ResponseWriter, r *http.Request) { +// GetApplicationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) GetApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -16798,25 +19996,25 @@ func (siw *ServerInterfaceWrapper) RecoverWorkspaceOwnership(w http.ResponseWrit return } - // ------------- Path parameter "workspace_id" ------------- - var workspaceId UUID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RecoverWorkspaceOwnership(w, r, applicationId, workspaceId) + siw.Handler.GetApplicationStorageProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16826,47 +20024,40 @@ func (siw *ServerInterfaceWrapper) RecoverWorkspaceOwnership(w http.ResponseWrit handler.ServeHTTP(w, r) } -// StartOperatorEmailLogin operation middleware -func (siw *ServerInterfaceWrapper) StartOperatorEmailLogin(w http.ResponseWriter, r *http.Request) { - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.StartOperatorEmailLogin(w, r) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r) -} +// UpdateApplicationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { -// VerifyOperatorEmailLogin operation middleware -func (siw *ServerInterfaceWrapper) VerifyOperatorEmailLogin(w http.ResponseWriter, r *http.Request) { + var err error + _ = err - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyOperatorEmailLogin(w, r) - })) + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return } - handler.ServeHTTP(w, r) -} + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID -// LogoutOperator operation middleware -func (siw *ServerInterfaceWrapper) LogoutOperator(w http.ResponseWriter, r *http.Request) { + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.LogoutOperator(w, r) + siw.Handler.UpdateApplicationStorageProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16876,19 +20067,40 @@ func (siw *ServerInterfaceWrapper) LogoutOperator(w http.ResponseWriter, r *http handler.ServeHTTP(w, r) } -// LogoutAllOperatorSessions operation middleware -func (siw *ServerInterfaceWrapper) LogoutAllOperatorSessions(w http.ResponseWriter, r *http.Request) { +// EnableApplicationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) EnableApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.LogoutAllOperatorSessions(w, r) + siw.Handler.EnableApplicationStorageProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16898,19 +20110,40 @@ func (siw *ServerInterfaceWrapper) LogoutAllOperatorSessions(w http.ResponseWrit handler.ServeHTTP(w, r) } -// GetOperatorAccount operation middleware -func (siw *ServerInterfaceWrapper) GetOperatorAccount(w http.ResponseWriter, r *http.Request) { +// VerifyApplicationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyApplicationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetOperatorAccount(w, r) + siw.Handler.VerifyApplicationStorageProvider(w, r, applicationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16920,19 +20153,59 @@ func (siw *ServerInterfaceWrapper) GetOperatorAccount(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// UpdateOperatorAccount operation middleware -func (siw *ServerInterfaceWrapper) UpdateOperatorAccount(w http.ResponseWriter, r *http.Request) { +// CreateControlApplicationStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CreateControlApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params CreateControlApplicationStorageUploadParams + + headers := r.Header + + // ------------- Required header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey RequiredIdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = IdempotencyKey + + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) + return + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOperatorAccount(w, r) + siw.Handler.CreateControlApplicationStorageUpload(w, r, applicationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16942,33 +20215,40 @@ func (siw *ServerInterfaceWrapper) UpdateOperatorAccount(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// LoginOperatorWithPassword operation middleware -func (siw *ServerInterfaceWrapper) LoginOperatorWithPassword(w http.ResponseWriter, r *http.Request) { +// CompleteControlApplicationStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CompleteControlApplicationStorageUpload(w http.ResponseWriter, r *http.Request) { - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.LoginOperatorWithPassword(w, r) - })) + var err error + _ = err - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return } - handler.ServeHTTP(w, r) -} + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID -// ChangeOperatorPassword operation middleware -func (siw *ServerInterfaceWrapper) ChangeOperatorPassword(w http.ResponseWriter, r *http.Request) { + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ChangeOperatorPassword(w, r) + siw.Handler.CompleteControlApplicationStorageUpload(w, r, applicationId, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -16978,19 +20258,31 @@ func (siw *ServerInterfaceWrapper) ChangeOperatorPassword(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// ListOperatorSessions operation middleware -func (siw *ServerInterfaceWrapper) ListOperatorSessions(w http.ResponseWriter, r *http.Request) { +// ListUsers operation middleware +func (siw *ServerInterfaceWrapper) ListUsers(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOperatorSessions(w, r) + siw.Handler.ListUsers(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17000,31 +20292,31 @@ func (siw *ServerInterfaceWrapper) ListOperatorSessions(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// RevokeOperatorSession operation middleware -func (siw *ServerInterfaceWrapper) RevokeOperatorSession(w http.ResponseWriter, r *http.Request) { +// CreateUser operation middleware +func (siw *ServerInterfaceWrapper) CreateUser(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "session_id" ------------- - var sessionId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "session_id", chi.URLParam(r, "session_id"), &sessionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "session_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RevokeOperatorSession(w, r, sessionId) + siw.Handler.CreateUser(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17034,41 +20326,40 @@ func (siw *ServerInterfaceWrapper) RevokeOperatorSession(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// RefreshOperatorSession operation middleware -func (siw *ServerInterfaceWrapper) RefreshOperatorSession(w http.ResponseWriter, r *http.Request) { - - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) +// GetUser operation middleware +func (siw *ServerInterfaceWrapper) GetUser(w http.ResponseWriter, r *http.Request) { - r = r.WithContext(ctx) + var err error + _ = err - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RefreshOperatorSession(w, r) - })) + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return } - handler.ServeHTTP(w, r) -} + // ------------- Path parameter "user_id" ------------- + var userId UUID -// ListInstallationAuthProviders operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationAuthProviders(w http.ResponseWriter, r *http.Request) { + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationAuthProviders(w, r) + siw.Handler.GetUser(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17078,31 +20369,40 @@ func (siw *ServerInterfaceWrapper) ListInstallationAuthProviders(w http.Response handler.ServeHTTP(w, r) } -// DisableInstallationAuthProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableInstallationAuthProvider(w http.ResponseWriter, r *http.Request) { +// UpdateUser operation middleware +func (siw *ServerInterfaceWrapper) UpdateUser(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider" ------------- - var provider string + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableInstallationAuthProvider(w, r, provider) + siw.Handler.UpdateUser(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17112,31 +20412,40 @@ func (siw *ServerInterfaceWrapper) DisableInstallationAuthProvider(w http.Respon handler.ServeHTTP(w, r) } -// UpdateInstallationAuthProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateInstallationAuthProvider(w http.ResponseWriter, r *http.Request) { +// ListUserAddresses operation middleware +func (siw *ServerInterfaceWrapper) ListUserAddresses(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider" ------------- - var provider string + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateInstallationAuthProvider(w, r, provider) + siw.Handler.ListUserAddresses(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17146,31 +20455,40 @@ func (siw *ServerInterfaceWrapper) UpdateInstallationAuthProvider(w http.Respons handler.ServeHTTP(w, r) } -// ConfigureInstallationAuthProvider operation middleware -func (siw *ServerInterfaceWrapper) ConfigureInstallationAuthProvider(w http.ResponseWriter, r *http.Request) { +// RestoreUser operation middleware +func (siw *ServerInterfaceWrapper) RestoreUser(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider" ------------- - var provider string + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ConfigureInstallationAuthProvider(w, r, provider) + siw.Handler.RestoreUser(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17180,41 +20498,40 @@ func (siw *ServerInterfaceWrapper) ConfigureInstallationAuthProvider(w http.Resp handler.ServeHTTP(w, r) } -// ListInstallationBillingProviders operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationBillingProviders(w http.ResponseWriter, r *http.Request) { - - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) +// ListUserSessions operation middleware +func (siw *ServerInterfaceWrapper) ListUserSessions(w http.ResponseWriter, r *http.Request) { - r = r.WithContext(ctx) + var err error + _ = err - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationBillingProviders(w, r) - })) + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return } - handler.ServeHTTP(w, r) -} + // ------------- Path parameter "user_id" ------------- + var userId UUID -// CreateInstallationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateInstallationBillingProvider(w, r) + siw.Handler.ListUserSessions(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17224,31 +20541,40 @@ func (siw *ServerInterfaceWrapper) CreateInstallationBillingProvider(w http.Resp handler.ServeHTTP(w, r) } -// DisableInstallationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { +// RevokeUserSessions operation middleware +func (siw *ServerInterfaceWrapper) RevokeUserSessions(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableInstallationBillingProvider(w, r, providerId) + siw.Handler.RevokeUserSessions(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17258,31 +20584,40 @@ func (siw *ServerInterfaceWrapper) DisableInstallationBillingProvider(w http.Res handler.ServeHTTP(w, r) } -// GetInstallationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) GetInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { +// SuspendUser operation middleware +func (siw *ServerInterfaceWrapper) SuspendUser(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetInstallationBillingProvider(w, r, providerId) + siw.Handler.SuspendUser(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17292,31 +20627,40 @@ func (siw *ServerInterfaceWrapper) GetInstallationBillingProvider(w http.Respons handler.ServeHTTP(w, r) } -// UpdateInstallationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { +// UnverifyUserEmail operation middleware +func (siw *ServerInterfaceWrapper) UnverifyUserEmail(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateInstallationBillingProvider(w, r, providerId) + siw.Handler.UnverifyUserEmail(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17326,31 +20670,40 @@ func (siw *ServerInterfaceWrapper) UpdateInstallationBillingProvider(w http.Resp handler.ServeHTTP(w, r) } -// VerifyInstallationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { +// UnverifyUserOrganization operation middleware +func (siw *ServerInterfaceWrapper) UnverifyUserOrganization(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyInstallationBillingProvider(w, r, providerId) + siw.Handler.UnverifyUserOrganization(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17360,19 +20713,40 @@ func (siw *ServerInterfaceWrapper) VerifyInstallationBillingProvider(w http.Resp handler.ServeHTTP(w, r) } -// GetManagementAPIStatus operation middleware -func (siw *ServerInterfaceWrapper) GetManagementAPIStatus(w http.ResponseWriter, r *http.Request) { +// VerifyUserEmail operation middleware +func (siw *ServerInterfaceWrapper) VerifyUserEmail(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetManagementAPIStatus(w, r) + siw.Handler.VerifyUserEmail(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17382,19 +20756,40 @@ func (siw *ServerInterfaceWrapper) GetManagementAPIStatus(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// UpdateManagementAPIStatus operation middleware -func (siw *ServerInterfaceWrapper) UpdateManagementAPIStatus(w http.ResponseWriter, r *http.Request) { +// VerifyUserOrganization operation middleware +func (siw *ServerInterfaceWrapper) VerifyUserOrganization(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateManagementAPIStatus(w, r) + siw.Handler.VerifyUserOrganization(w, r, applicationId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17404,19 +20799,31 @@ func (siw *ServerInterfaceWrapper) UpdateManagementAPIStatus(w http.ResponseWrit handler.ServeHTTP(w, r) } -// ListManagementClients operation middleware -func (siw *ServerInterfaceWrapper) ListManagementClients(w http.ResponseWriter, r *http.Request) { +// ListWebhookDeliveries operation middleware +func (siw *ServerInterfaceWrapper) ListWebhookDeliveries(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListManagementClients(w, r) + siw.Handler.ListWebhookDeliveries(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17426,19 +20833,40 @@ func (siw *ServerInterfaceWrapper) ListManagementClients(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// CreateManagementClient operation middleware -func (siw *ServerInterfaceWrapper) CreateManagementClient(w http.ResponseWriter, r *http.Request) { +// GetWebhookDelivery operation middleware +func (siw *ServerInterfaceWrapper) GetWebhookDelivery(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "delivery_id" ------------- + var deliveryId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "delivery_id", chi.URLParam(r, "delivery_id"), &deliveryId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delivery_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateManagementClient(w, r) + siw.Handler.GetWebhookDelivery(w, r, applicationId, deliveryId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17448,31 +20876,40 @@ func (siw *ServerInterfaceWrapper) CreateManagementClient(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// DisableManagementClient operation middleware -func (siw *ServerInterfaceWrapper) DisableManagementClient(w http.ResponseWriter, r *http.Request) { +// ReplayWebhookDelivery operation middleware +func (siw *ServerInterfaceWrapper) ReplayWebhookDelivery(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "management_client_id" ------------- - var managementClientId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "management_client_id", chi.URLParam(r, "management_client_id"), &managementClientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "management_client_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "delivery_id" ------------- + var deliveryId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "delivery_id", chi.URLParam(r, "delivery_id"), &deliveryId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "delivery_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableManagementClient(w, r, managementClientId) + siw.Handler.ReplayWebhookDelivery(w, r, applicationId, deliveryId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17482,31 +20919,31 @@ func (siw *ServerInterfaceWrapper) DisableManagementClient(w http.ResponseWriter handler.ServeHTTP(w, r) } -// RotateManagementClientSecret operation middleware -func (siw *ServerInterfaceWrapper) RotateManagementClientSecret(w http.ResponseWriter, r *http.Request) { +// ListWebhooks operation middleware +func (siw *ServerInterfaceWrapper) ListWebhooks(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "management_client_id" ------------- - var managementClientId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "management_client_id", chi.URLParam(r, "management_client_id"), &managementClientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "management_client_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RotateManagementClientSecret(w, r, managementClientId) + siw.Handler.ListWebhooks(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17516,19 +20953,31 @@ func (siw *ServerInterfaceWrapper) RotateManagementClientSecret(w http.ResponseW handler.ServeHTTP(w, r) } -// ListInstallationNotificationProviders operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationNotificationProviders(w http.ResponseWriter, r *http.Request) { +// CreateWebhook operation middleware +func (siw *ServerInterfaceWrapper) CreateWebhook(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationNotificationProviders(w, r) + siw.Handler.CreateWebhook(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17538,19 +20987,40 @@ func (siw *ServerInterfaceWrapper) ListInstallationNotificationProviders(w http. handler.ServeHTTP(w, r) } -// CreateInstallationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// DisableWebhook operation middleware +func (siw *ServerInterfaceWrapper) DisableWebhook(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "webhook_id" ------------- + var webhookId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateInstallationNotificationProvider(w, r) + siw.Handler.DisableWebhook(w, r, applicationId, webhookId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17560,31 +21030,40 @@ func (siw *ServerInterfaceWrapper) CreateInstallationNotificationProvider(w http handler.ServeHTTP(w, r) } -// DisableInstallationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// GetWebhook operation middleware +func (siw *ServerInterfaceWrapper) GetWebhook(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "webhook_id" ------------- + var webhookId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableInstallationNotificationProvider(w, r, providerId) + siw.Handler.GetWebhook(w, r, applicationId, webhookId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17594,31 +21073,40 @@ func (siw *ServerInterfaceWrapper) DisableInstallationNotificationProvider(w htt handler.ServeHTTP(w, r) } -// GetInstallationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) GetInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// UpdateWebhook operation middleware +func (siw *ServerInterfaceWrapper) UpdateWebhook(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "webhook_id" ------------- + var webhookId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetInstallationNotificationProvider(w, r, providerId) + siw.Handler.UpdateWebhook(w, r, applicationId, webhookId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17628,31 +21116,40 @@ func (siw *ServerInterfaceWrapper) GetInstallationNotificationProvider(w http.Re handler.ServeHTTP(w, r) } -// UpdateInstallationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// RotateWebhookSecret operation middleware +func (siw *ServerInterfaceWrapper) RotateWebhookSecret(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "webhook_id" ------------- + var webhookId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateInstallationNotificationProvider(w, r, providerId) + siw.Handler.RotateWebhookSecret(w, r, applicationId, webhookId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17662,31 +21159,40 @@ func (siw *ServerInterfaceWrapper) UpdateInstallationNotificationProvider(w http handler.ServeHTTP(w, r) } -// TestInstallationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) TestInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// TestWebhook operation middleware +func (siw *ServerInterfaceWrapper) TestWebhook(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "webhook_id" ------------- + var webhookId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "webhook_id", chi.URLParam(r, "webhook_id"), &webhookId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "webhook_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params TestInstallationNotificationProviderParams + var params TestWebhookParams headers := r.Header @@ -17710,7 +21216,7 @@ func (siw *ServerInterfaceWrapper) TestInstallationNotificationProvider(w http.R } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.TestInstallationNotificationProvider(w, r, providerId, params) + siw.Handler.TestWebhook(w, r, applicationId, webhookId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17720,31 +21226,31 @@ func (siw *ServerInterfaceWrapper) TestInstallationNotificationProvider(w http.R handler.ServeHTTP(w, r) } -// VerifyInstallationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// ListWorkspaces operation middleware +func (siw *ServerInterfaceWrapper) ListWorkspaces(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyInstallationNotificationProvider(w, r, providerId) + siw.Handler.ListWorkspaces(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17754,19 +21260,31 @@ func (siw *ServerInterfaceWrapper) VerifyInstallationNotificationProvider(w http handler.ServeHTTP(w, r) } -// ListInstallationNotificationTemplateVariables operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationNotificationTemplateVariables(w http.ResponseWriter, r *http.Request) { +// CreateWorkspace operation middleware +func (siw *ServerInterfaceWrapper) CreateWorkspace(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationNotificationTemplateVariables(w, r) + siw.Handler.CreateWorkspace(w, r, applicationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17776,19 +21294,40 @@ func (siw *ServerInterfaceWrapper) ListInstallationNotificationTemplateVariables handler.ServeHTTP(w, r) } -// ListInstallationNotificationTemplates operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationNotificationTemplates(w http.ResponseWriter, r *http.Request) { +// DeleteWorkspace operation middleware +func (siw *ServerInterfaceWrapper) DeleteWorkspace(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationNotificationTemplates(w, r) + siw.Handler.DeleteWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17798,19 +21337,40 @@ func (siw *ServerInterfaceWrapper) ListInstallationNotificationTemplates(w http. handler.ServeHTTP(w, r) } -// CreateInstallationNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) CreateInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// GetWorkspace operation middleware +func (siw *ServerInterfaceWrapper) GetWorkspace(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID + + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateInstallationNotificationTemplate(w, r) + siw.Handler.GetWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17820,31 +21380,40 @@ func (siw *ServerInterfaceWrapper) CreateInstallationNotificationTemplate(w http handler.ServeHTTP(w, r) } -// GetInstallationNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) GetInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// UpdateWorkspace operation middleware +func (siw *ServerInterfaceWrapper) UpdateWorkspace(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetInstallationNotificationTemplate(w, r, templateId) + siw.Handler.UpdateWorkspace(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17854,31 +21423,40 @@ func (siw *ServerInterfaceWrapper) GetInstallationNotificationTemplate(w http.Re handler.ServeHTTP(w, r) } -// UpdateInstallationNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) UpdateInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// ListWorkspaceMembers operation middleware +func (siw *ServerInterfaceWrapper) ListWorkspaceMembers(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateInstallationNotificationTemplate(w, r, templateId) + siw.Handler.ListWorkspaceMembers(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17888,31 +21466,49 @@ func (siw *ServerInterfaceWrapper) UpdateInstallationNotificationTemplate(w http handler.ServeHTTP(w, r) } -// ArchiveInstallationNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) ArchiveInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// DeleteWorkspaceMember operation middleware +func (siw *ServerInterfaceWrapper) DeleteWorkspaceMember(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ArchiveInstallationNotificationTemplate(w, r, templateId) + siw.Handler.DeleteWorkspaceMember(w, r, applicationId, workspaceId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17922,31 +21518,49 @@ func (siw *ServerInterfaceWrapper) ArchiveInstallationNotificationTemplate(w htt handler.ServeHTTP(w, r) } -// PreviewInstallationNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) PreviewInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// ReplaceWorkspaceMemberRoles operation middleware +func (siw *ServerInterfaceWrapper) ReplaceWorkspaceMemberRoles(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) + return + } + + // ------------- Path parameter "user_id" ------------- + var userId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "user_id", chi.URLParam(r, "user_id"), &userId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PreviewInstallationNotificationTemplate(w, r, templateId) + siw.Handler.ReplaceWorkspaceMemberRoles(w, r, applicationId, workspaceId, userId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17956,31 +21570,40 @@ func (siw *ServerInterfaceWrapper) PreviewInstallationNotificationTemplate(w htt handler.ServeHTTP(w, r) } -// PublishInstallationNotificationTemplate operation middleware -func (siw *ServerInterfaceWrapper) PublishInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { +// RecoverWorkspaceOwnership operation middleware +func (siw *ServerInterfaceWrapper) RecoverWorkspaceOwnership(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "template_id" ------------- - var templateId UUID + // ------------- Path parameter "application_id" ------------- + var applicationId ApplicationID - err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "application_id", chi.URLParam(r, "application_id"), &applicationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_id", Err: err}) + return + } + + // ------------- Path parameter "workspace_id" ------------- + var workspaceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "workspace_id", chi.URLParam(r, "workspace_id"), &workspaceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "workspace_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.PublishInstallationNotificationTemplate(w, r, templateId) + siw.Handler.RecoverWorkspaceOwnership(w, r, applicationId, workspaceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -17990,19 +21613,11 @@ func (siw *ServerInterfaceWrapper) PublishInstallationNotificationTemplate(w htt handler.ServeHTTP(w, r) } -// ListInstallationOperators operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationOperators(w http.ResponseWriter, r *http.Request) { - - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) +// StartControlUserEmailLogin operation middleware +func (siw *ServerInterfaceWrapper) StartControlUserEmailLogin(w http.ResponseWriter, r *http.Request) { handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationOperators(w, r) + siw.Handler.StartControlUserEmailLogin(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18012,19 +21627,11 @@ func (siw *ServerInterfaceWrapper) ListInstallationOperators(w http.ResponseWrit handler.ServeHTTP(w, r) } -// CreateInstallationOperator operation middleware -func (siw *ServerInterfaceWrapper) CreateInstallationOperator(w http.ResponseWriter, r *http.Request) { - - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) +// VerifyControlUserEmailLogin operation middleware +func (siw *ServerInterfaceWrapper) VerifyControlUserEmailLogin(w http.ResponseWriter, r *http.Request) { handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateInstallationOperator(w, r) + siw.Handler.VerifyControlUserEmailLogin(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18034,31 +21641,31 @@ func (siw *ServerInterfaceWrapper) CreateInstallationOperator(w http.ResponseWri handler.ServeHTTP(w, r) } -// DeleteInstallationOperator operation middleware -func (siw *ServerInterfaceWrapper) DeleteInstallationOperator(w http.ResponseWriter, r *http.Request) { +// UnlinkControlExternalIdentity operation middleware +func (siw *ServerInterfaceWrapper) UnlinkControlExternalIdentity(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "operator_id" ------------- - var operatorId UUID + // ------------- Path parameter "identity_id" ------------- + var identityId UUID - err = runtime.BindStyledParameterWithOptions("simple", "operator_id", chi.URLParam(r, "operator_id"), &operatorId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "identity_id", chi.URLParam(r, "identity_id"), &identityId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "operator_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "identity_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteInstallationOperator(w, r, operatorId) + siw.Handler.UnlinkControlExternalIdentity(w, r, identityId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18068,31 +21675,19 @@ func (siw *ServerInterfaceWrapper) DeleteInstallationOperator(w http.ResponseWri handler.ServeHTTP(w, r) } -// UpdateInstallationOperator operation middleware -func (siw *ServerInterfaceWrapper) UpdateInstallationOperator(w http.ResponseWriter, r *http.Request) { +// LogoutControlUser operation middleware +func (siw *ServerInterfaceWrapper) LogoutControlUser(w http.ResponseWriter, r *http.Request) { - var err error - _ = err + ctx := r.Context() - // ------------- Path parameter "operator_id" ------------- - var operatorId UUID + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - err = runtime.BindStyledParameterWithOptions("simple", "operator_id", chi.URLParam(r, "operator_id"), &operatorId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "operator_id", Err: err}) - return - } - - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateInstallationOperator(w, r, operatorId) + siw.Handler.LogoutControlUser(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18102,59 +21697,41 @@ func (siw *ServerInterfaceWrapper) UpdateInstallationOperator(w http.ResponseWri handler.ServeHTTP(w, r) } -// UpdateOrganizationPolicy operation middleware -func (siw *ServerInterfaceWrapper) UpdateOrganizationPolicy(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// LogoutAllControlUserSessions operation middleware +func (siw *ServerInterfaceWrapper) LogoutAllControlUserSessions(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params UpdateOrganizationPolicyParams + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.LogoutAllControlUserSessions(w, r) + })) - headers := r.Header + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } - // ------------- Required header parameter "If-Match" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { - var IfMatch IfMatch - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) - return - } + handler.ServeHTTP(w, r) +} - err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) - return - } +// GetControlUserAccount operation middleware +func (siw *ServerInterfaceWrapper) GetControlUserAccount(w http.ResponseWriter, r *http.Request) { - params.IfMatch = IfMatch + ctx := r.Context() - } else { - err := fmt.Errorf("Header parameter If-Match is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) - return - } + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOrganizationPolicy(w, r, organizationId, params) + siw.Handler.GetControlUserAccount(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18164,19 +21741,19 @@ func (siw *ServerInterfaceWrapper) UpdateOrganizationPolicy(w http.ResponseWrite handler.ServeHTTP(w, r) } -// ListSigningKeys operation middleware -func (siw *ServerInterfaceWrapper) ListSigningKeys(w http.ResponseWriter, r *http.Request) { +// UpdateControlUserAccount operation middleware +func (siw *ServerInterfaceWrapper) UpdateControlUserAccount(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListSigningKeys(w, r) + siw.Handler.UpdateControlUserAccount(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18186,19 +21763,25 @@ func (siw *ServerInterfaceWrapper) ListSigningKeys(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// RotateSigningKey operation middleware -func (siw *ServerInterfaceWrapper) RotateSigningKey(w http.ResponseWriter, r *http.Request) { +// GetControlAuthMethods operation middleware +func (siw *ServerInterfaceWrapper) GetControlAuthMethods(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetControlAuthMethods(w, r) + })) - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + handler.ServeHTTP(w, r) +} - r = r.WithContext(ctx) +// LoginControlUserWithPassword operation middleware +func (siw *ServerInterfaceWrapper) LoginControlUserWithPassword(w http.ResponseWriter, r *http.Request) { handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RotateSigningKey(w, r) + siw.Handler.LoginControlUserWithPassword(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18208,19 +21791,19 @@ func (siw *ServerInterfaceWrapper) RotateSigningKey(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// ListInstallationStorageObjects operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationStorageObjects(w http.ResponseWriter, r *http.Request) { +// ChangeControlUserPassword operation middleware +func (siw *ServerInterfaceWrapper) ChangeControlUserPassword(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationStorageObjects(w, r) + siw.Handler.ChangeControlUserPassword(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18230,47 +21813,31 @@ func (siw *ServerInterfaceWrapper) ListInstallationStorageObjects(w http.Respons handler.ServeHTTP(w, r) } -// DeleteInstallationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DeleteInstallationStorageObject(w http.ResponseWriter, r *http.Request) { +// LinkControlExternalIdentity operation middleware +func (siw *ServerInterfaceWrapper) LinkControlExternalIdentity(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "provider" ------------- + var provider string - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params DeleteInstallationStorageObjectParams - - // ------------- Optional query parameter "force" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "force", r.URL.Query(), ¶ms.Force, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "force"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "force", Err: err}) - } - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteInstallationStorageObject(w, r, objectId, params) + siw.Handler.LinkControlExternalIdentity(w, r, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18280,31 +21847,45 @@ func (siw *ServerInterfaceWrapper) DeleteInstallationStorageObject(w http.Respon handler.ServeHTTP(w, r) } -// GetInstallationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) GetInstallationStorageObject(w http.ResponseWriter, r *http.Request) { +// StartControlExternalLogin operation middleware +func (siw *ServerInterfaceWrapper) StartControlExternalLogin(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "provider" ------------- + var provider string - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) return } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.StartControlExternalLogin(w, r, provider) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ListControlUserSessions operation middleware +func (siw *ServerInterfaceWrapper) ListControlUserSessions(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetInstallationStorageObject(w, r, objectId) + siw.Handler.ListControlUserSessions(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18314,31 +21895,31 @@ func (siw *ServerInterfaceWrapper) GetInstallationStorageObject(w http.ResponseW handler.ServeHTTP(w, r) } -// DownloadInstallationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DownloadInstallationStorageObject(w http.ResponseWriter, r *http.Request) { +// RevokeControlUserSession operation middleware +func (siw *ServerInterfaceWrapper) RevokeControlUserSession(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "session_id" ------------- + var sessionId UUID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "session_id", chi.URLParam(r, "session_id"), &sessionId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "session_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DownloadInstallationStorageObject(w, r, objectId) + siw.Handler.RevokeControlUserSession(w, r, sessionId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18348,19 +21929,19 @@ func (siw *ServerInterfaceWrapper) DownloadInstallationStorageObject(w http.Resp handler.ServeHTTP(w, r) } -// ListInstallationStorageProviders operation middleware -func (siw *ServerInterfaceWrapper) ListInstallationStorageProviders(w http.ResponseWriter, r *http.Request) { +// RefreshControlUserSession operation middleware +func (siw *ServerInterfaceWrapper) RefreshControlUserSession(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListInstallationStorageProviders(w, r) + siw.Handler.RefreshControlUserSession(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18370,19 +21951,19 @@ func (siw *ServerInterfaceWrapper) ListInstallationStorageProviders(w http.Respo handler.ServeHTTP(w, r) } -// CreateInstallationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { +// GetControlAuthPolicy operation middleware +func (siw *ServerInterfaceWrapper) GetControlAuthPolicy(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateInstallationStorageProvider(w, r) + siw.Handler.GetControlAuthPolicy(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18392,47 +21973,19 @@ func (siw *ServerInterfaceWrapper) CreateInstallationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// DisableInstallationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } +// UpdateControlAuthPolicy operation middleware +func (siw *ServerInterfaceWrapper) UpdateControlAuthPolicy(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params DisableInstallationStorageProviderParams - - // ------------- Optional query parameter "confirm_affected_objects" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "confirm_affected_objects", r.URL.Query(), ¶ms.ConfirmAffectedObjects, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "confirm_affected_objects"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "confirm_affected_objects", Err: err}) - } - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableInstallationStorageProvider(w, r, providerId, params) + siw.Handler.UpdateControlAuthPolicy(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18442,31 +21995,19 @@ func (siw *ServerInterfaceWrapper) DisableInstallationStorageProvider(w http.Res handler.ServeHTTP(w, r) } -// GetInstallationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) GetInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } +// ListInstallationAuthProviders operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationAuthProviders(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetInstallationStorageProvider(w, r, providerId) + siw.Handler.ListInstallationAuthProviders(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18476,31 +22017,31 @@ func (siw *ServerInterfaceWrapper) GetInstallationStorageProvider(w http.Respons handler.ServeHTTP(w, r) } -// UpdateInstallationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { +// DisableInstallationAuthProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableInstallationAuthProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "provider" ------------- + var provider string - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateInstallationStorageProvider(w, r, providerId) + siw.Handler.DisableInstallationAuthProvider(w, r, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18510,31 +22051,31 @@ func (siw *ServerInterfaceWrapper) UpdateInstallationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// EnableInstallationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) EnableInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { +// UpdateInstallationAuthProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateInstallationAuthProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "provider" ------------- + var provider string - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.EnableInstallationStorageProvider(w, r, providerId) + siw.Handler.UpdateInstallationAuthProvider(w, r, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18544,31 +22085,31 @@ func (siw *ServerInterfaceWrapper) EnableInstallationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// VerifyInstallationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { +// ConfigureInstallationAuthProvider operation middleware +func (siw *ServerInterfaceWrapper) ConfigureInstallationAuthProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "provider" ------------- + var provider string - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyInstallationStorageProvider(w, r, providerId) + siw.Handler.ConfigureInstallationAuthProvider(w, r, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18578,50 +22119,19 @@ func (siw *ServerInterfaceWrapper) VerifyInstallationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// CreateInstallationStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CreateInstallationStorageUpload(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err +// ListInstallationBillingProviders operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationBillingProviders(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params CreateInstallationStorageUploadParams - - headers := r.Header - - // ------------- Required header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey RequiredIdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return - } - - params.IdempotencyKey = IdempotencyKey - - } else { - err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateInstallationStorageUpload(w, r, params) + siw.Handler.ListInstallationBillingProviders(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18631,45 +22141,19 @@ func (siw *ServerInterfaceWrapper) CreateInstallationStorageUpload(w http.Respon handler.ServeHTTP(w, r) } -// CompleteInstallationStorageUpload operation middleware -func (siw *ServerInterfaceWrapper) CompleteInstallationStorageUpload(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID - - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) - return - } +// CreateInstallationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CompleteInstallationStorageUpload(w, r, objectId) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r) -} - -// AcceptOrganizationInvitation operation middleware -func (siw *ServerInterfaceWrapper) AcceptOrganizationInvitation(w http.ResponseWriter, r *http.Request) { - - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.AcceptOrganizationInvitation(w, r) + siw.Handler.CreateInstallationBillingProvider(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18679,60 +22163,31 @@ func (siw *ServerInterfaceWrapper) AcceptOrganizationInvitation(w http.ResponseW handler.ServeHTTP(w, r) } -// ListOrganizations operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizations(w http.ResponseWriter, r *http.Request) { +// DisableInstallationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) - - r = r.WithContext(ctx) - - // Parameter object where we will unmarshal all parameters from the context - var params ListOrganizationsParams - - // ------------- Optional query parameter "include_retired" ------------- + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindQueryParameterWithOptions("form", true, false, "include_retired", r.URL.Query(), ¶ms.IncludeRetired, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "include_retired"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "include_retired", Err: err}) - } + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizations(w, r, params) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } - - handler.ServeHTTP(w, r) -} - -// CreateOrganization operation middleware -func (siw *ServerInterfaceWrapper) CreateOrganization(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateOrganization(w, r) + siw.Handler.DisableInstallationBillingProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18742,31 +22197,31 @@ func (siw *ServerInterfaceWrapper) CreateOrganization(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// RetireOrganization operation middleware -func (siw *ServerInterfaceWrapper) RetireOrganization(w http.ResponseWriter, r *http.Request) { +// GetInstallationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) GetInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RetireOrganization(w, r, organizationId) + siw.Handler.GetInstallationBillingProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18776,31 +22231,31 @@ func (siw *ServerInterfaceWrapper) RetireOrganization(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// GetOrganization operation middleware -func (siw *ServerInterfaceWrapper) GetOrganization(w http.ResponseWriter, r *http.Request) { +// UpdateInstallationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetOrganization(w, r, organizationId) + siw.Handler.UpdateInstallationBillingProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18810,31 +22265,31 @@ func (siw *ServerInterfaceWrapper) GetOrganization(w http.ResponseWriter, r *htt handler.ServeHTTP(w, r) } -// UpdateOrganization operation middleware -func (siw *ServerInterfaceWrapper) UpdateOrganization(w http.ResponseWriter, r *http.Request) { +// VerifyInstallationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyInstallationBillingProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOrganization(w, r, organizationId) + siw.Handler.VerifyInstallationBillingProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18844,47 +22299,19 @@ func (siw *ServerInterfaceWrapper) UpdateOrganization(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// ListApplications operation middleware -func (siw *ServerInterfaceWrapper) ListApplications(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// ListInstallationControlUserInvitations operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationControlUserInvitations(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params ListApplicationsParams - - // ------------- Optional query parameter "include_retired" ------------- - - err = runtime.BindQueryParameterWithOptions("form", true, false, "include_retired", r.URL.Query(), ¶ms.IncludeRetired, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "include_retired"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "include_retired", Err: err}) - } - return - } - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListApplications(w, r, organizationId, params) + siw.Handler.ListInstallationControlUserInvitations(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18894,31 +22321,19 @@ func (siw *ServerInterfaceWrapper) ListApplications(w http.ResponseWriter, r *ht handler.ServeHTTP(w, r) } -// CreateApplication operation middleware -func (siw *ServerInterfaceWrapper) CreateApplication(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// CreateInstallationControlUserInvitation operation middleware +func (siw *ServerInterfaceWrapper) CreateInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateApplication(w, r, organizationId) + siw.Handler.CreateInstallationControlUserInvitation(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18928,40 +22343,31 @@ func (siw *ServerInterfaceWrapper) CreateApplication(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// RetireApplication operation middleware -func (siw *ServerInterfaceWrapper) RetireApplication(w http.ResponseWriter, r *http.Request) { +// RevokeInstallationControlUserInvitation operation middleware +func (siw *ServerInterfaceWrapper) RevokeInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "application_resource_id" ------------- - var applicationResourceId UUID + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "application_resource_id", chi.URLParam(r, "application_resource_id"), &applicationResourceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_resource_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RetireApplication(w, r, organizationId, applicationResourceId) + siw.Handler.RevokeInstallationControlUserInvitation(w, r, invitationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -18971,40 +22377,31 @@ func (siw *ServerInterfaceWrapper) RetireApplication(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// UpdateApplication operation middleware -func (siw *ServerInterfaceWrapper) UpdateApplication(w http.ResponseWriter, r *http.Request) { +// ResendInstallationControlUserInvitation operation middleware +func (siw *ServerInterfaceWrapper) ResendInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "application_resource_id" ------------- - var applicationResourceId UUID + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID - err = runtime.BindStyledParameterWithOptions("simple", "application_resource_id", chi.URLParam(r, "application_resource_id"), &applicationResourceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_resource_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateApplication(w, r, organizationId, applicationResourceId) + siw.Handler.ResendInstallationControlUserInvitation(w, r, invitationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19014,40 +22411,19 @@ func (siw *ServerInterfaceWrapper) UpdateApplication(w http.ResponseWriter, r *h handler.ServeHTTP(w, r) } -// RestoreApplication operation middleware -func (siw *ServerInterfaceWrapper) RestoreApplication(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "application_resource_id" ------------- - var applicationResourceId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "application_resource_id", chi.URLParam(r, "application_resource_id"), &applicationResourceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_resource_id", Err: err}) - return - } +// GetManagementAPIStatus operation middleware +func (siw *ServerInterfaceWrapper) GetManagementAPIStatus(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RestoreApplication(w, r, organizationId, applicationResourceId) + siw.Handler.GetManagementAPIStatus(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19057,31 +22433,19 @@ func (siw *ServerInterfaceWrapper) RestoreApplication(w http.ResponseWriter, r * handler.ServeHTTP(w, r) } -// ListOrganizationAuditLogs operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationAuditLogs(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// UpdateManagementAPIStatus operation middleware +func (siw *ServerInterfaceWrapper) UpdateManagementAPIStatus(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationAuditLogs(w, r, organizationId) + siw.Handler.UpdateManagementAPIStatus(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19091,31 +22455,19 @@ func (siw *ServerInterfaceWrapper) ListOrganizationAuditLogs(w http.ResponseWrit handler.ServeHTTP(w, r) } -// ListOrganizationAuthProviders operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationAuthProviders(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// ListManagementClients operation middleware +func (siw *ServerInterfaceWrapper) ListManagementClients(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationAuthProviders(w, r, organizationId) + siw.Handler.ListManagementClients(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19125,40 +22477,19 @@ func (siw *ServerInterfaceWrapper) ListOrganizationAuthProviders(w http.Response handler.ServeHTTP(w, r) } -// DisableOrganizationAuthProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableOrganizationAuthProvider(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "provider" ------------- - var provider string - - err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) - return - } +// CreateManagementClient operation middleware +func (siw *ServerInterfaceWrapper) CreateManagementClient(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableOrganizationAuthProvider(w, r, organizationId, provider) + siw.Handler.CreateManagementClient(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19168,40 +22499,31 @@ func (siw *ServerInterfaceWrapper) DisableOrganizationAuthProvider(w http.Respon handler.ServeHTTP(w, r) } -// UpdateOrganizationAuthProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateOrganizationAuthProvider(w http.ResponseWriter, r *http.Request) { +// DisableManagementClient operation middleware +func (siw *ServerInterfaceWrapper) DisableManagementClient(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "provider" ------------- - var provider string + // ------------- Path parameter "management_client_id" ------------- + var managementClientId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "management_client_id", chi.URLParam(r, "management_client_id"), &managementClientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "management_client_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOrganizationAuthProvider(w, r, organizationId, provider) + siw.Handler.DisableManagementClient(w, r, managementClientId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19211,40 +22533,31 @@ func (siw *ServerInterfaceWrapper) UpdateOrganizationAuthProvider(w http.Respons handler.ServeHTTP(w, r) } -// ConfigureOrganizationAuthProvider operation middleware -func (siw *ServerInterfaceWrapper) ConfigureOrganizationAuthProvider(w http.ResponseWriter, r *http.Request) { +// RotateManagementClientSecret operation middleware +func (siw *ServerInterfaceWrapper) RotateManagementClientSecret(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "provider" ------------- - var provider string + // ------------- Path parameter "management_client_id" ------------- + var managementClientId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + err = runtime.BindStyledParameterWithOptions("simple", "management_client_id", chi.URLParam(r, "management_client_id"), &managementClientId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "management_client_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ConfigureOrganizationAuthProvider(w, r, organizationId, provider) + siw.Handler.RotateManagementClientSecret(w, r, managementClientId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19254,31 +22567,19 @@ func (siw *ServerInterfaceWrapper) ConfigureOrganizationAuthProvider(w http.Resp handler.ServeHTTP(w, r) } -// ListOrganizationBillingProviders operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationBillingProviders(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// ListInstallationNotificationProviders operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationNotificationProviders(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationBillingProviders(w, r, organizationId) + siw.Handler.ListInstallationNotificationProviders(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19288,31 +22589,19 @@ func (siw *ServerInterfaceWrapper) ListOrganizationBillingProviders(w http.Respo handler.ServeHTTP(w, r) } -// CreateOrganizationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// CreateInstallationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateOrganizationBillingProvider(w, r, organizationId) + siw.Handler.CreateInstallationNotificationProvider(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19322,23 +22611,14 @@ func (siw *ServerInterfaceWrapper) CreateOrganizationBillingProvider(w http.Resp handler.ServeHTTP(w, r) } -// DisableOrganizationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { +// DisableInstallationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + var providerId UUID err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -19348,14 +22628,14 @@ func (siw *ServerInterfaceWrapper) DisableOrganizationBillingProvider(w http.Res ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableOrganizationBillingProvider(w, r, organizationId, providerId) + siw.Handler.DisableInstallationNotificationProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19365,23 +22645,14 @@ func (siw *ServerInterfaceWrapper) DisableOrganizationBillingProvider(w http.Res handler.ServeHTTP(w, r) } -// GetOrganizationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) GetOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { +// GetInstallationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) GetInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + var providerId UUID err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -19391,14 +22662,14 @@ func (siw *ServerInterfaceWrapper) GetOrganizationBillingProvider(w http.Respons ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetOrganizationBillingProvider(w, r, organizationId, providerId) + siw.Handler.GetInstallationNotificationProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19408,23 +22679,14 @@ func (siw *ServerInterfaceWrapper) GetOrganizationBillingProvider(w http.Respons handler.ServeHTTP(w, r) } -// UpdateOrganizationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { +// UpdateInstallationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + var providerId UUID err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -19434,14 +22696,14 @@ func (siw *ServerInterfaceWrapper) UpdateOrganizationBillingProvider(w http.Resp ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOrganizationBillingProvider(w, r, organizationId, providerId) + siw.Handler.UpdateInstallationNotificationProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19451,23 +22713,14 @@ func (siw *ServerInterfaceWrapper) UpdateOrganizationBillingProvider(w http.Resp handler.ServeHTTP(w, r) } -// VerifyOrganizationBillingProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { +// TestInstallationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) TestInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + var providerId UUID err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { @@ -19477,14 +22730,38 @@ func (siw *ServerInterfaceWrapper) VerifyOrganizationBillingProvider(w http.Resp ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) + // Parameter object where we will unmarshal all parameters from the context + var params TestInstallationNotificationProviderParams + + headers := r.Header + + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = &IdempotencyKey + + } + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyOrganizationBillingProvider(w, r, organizationId, providerId) + siw.Handler.TestInstallationNotificationProvider(w, r, providerId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19494,31 +22771,31 @@ func (siw *ServerInterfaceWrapper) VerifyOrganizationBillingProvider(w http.Resp handler.ServeHTTP(w, r) } -// ListOrganizationInvitations operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationInvitations(w http.ResponseWriter, r *http.Request) { +// VerifyInstallationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyInstallationNotificationProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "provider_id" ------------- + var providerId UUID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationInvitations(w, r, organizationId) + siw.Handler.VerifyInstallationNotificationProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19528,31 +22805,19 @@ func (siw *ServerInterfaceWrapper) ListOrganizationInvitations(w http.ResponseWr handler.ServeHTTP(w, r) } -// CreateOrganizationInvitation operation middleware -func (siw *ServerInterfaceWrapper) CreateOrganizationInvitation(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// ListInstallationNotificationTemplateVariables operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationNotificationTemplateVariables(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateOrganizationInvitation(w, r, organizationId) + siw.Handler.ListInstallationNotificationTemplateVariables(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19562,40 +22827,19 @@ func (siw *ServerInterfaceWrapper) CreateOrganizationInvitation(w http.ResponseW handler.ServeHTTP(w, r) } -// RevokeOrganizationInvitation operation middleware -func (siw *ServerInterfaceWrapper) RevokeOrganizationInvitation(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "invitation_id" ------------- - var invitationId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) - return - } +// ListInstallationNotificationTemplates operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationNotificationTemplates(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RevokeOrganizationInvitation(w, r, organizationId, invitationId) + siw.Handler.ListInstallationNotificationTemplates(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19605,40 +22849,19 @@ func (siw *ServerInterfaceWrapper) RevokeOrganizationInvitation(w http.ResponseW handler.ServeHTTP(w, r) } -// ResendOrganizationInvitation operation middleware -func (siw *ServerInterfaceWrapper) ResendOrganizationInvitation(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "invitation_id" ------------- - var invitationId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) - return - } +// CreateInstallationNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) CreateInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ResendOrganizationInvitation(w, r, organizationId, invitationId) + siw.Handler.CreateInstallationNotificationTemplate(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19648,31 +22871,31 @@ func (siw *ServerInterfaceWrapper) ResendOrganizationInvitation(w http.ResponseW handler.ServeHTTP(w, r) } -// ListOrganizationMembers operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationMembers(w http.ResponseWriter, r *http.Request) { +// GetInstallationNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) GetInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationMembers(w, r, organizationId) + siw.Handler.GetInstallationNotificationTemplate(w, r, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19682,40 +22905,31 @@ func (siw *ServerInterfaceWrapper) ListOrganizationMembers(w http.ResponseWriter handler.ServeHTTP(w, r) } -// DeleteOrganizationMember operation middleware -func (siw *ServerInterfaceWrapper) DeleteOrganizationMember(w http.ResponseWriter, r *http.Request) { +// UpdateInstallationNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) UpdateInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "member_id" ------------- - var memberId UUID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "member_id", chi.URLParam(r, "member_id"), &memberId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "member_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteOrganizationMember(w, r, organizationId, memberId) + siw.Handler.UpdateInstallationNotificationTemplate(w, r, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19725,40 +22939,31 @@ func (siw *ServerInterfaceWrapper) DeleteOrganizationMember(w http.ResponseWrite handler.ServeHTTP(w, r) } -// UpdateOrganizationMember operation middleware -func (siw *ServerInterfaceWrapper) UpdateOrganizationMember(w http.ResponseWriter, r *http.Request) { +// ArchiveInstallationNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) ArchiveInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "member_id" ------------- - var memberId UUID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "member_id", chi.URLParam(r, "member_id"), &memberId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "member_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOrganizationMember(w, r, organizationId, memberId) + siw.Handler.ArchiveInstallationNotificationTemplate(w, r, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19768,31 +22973,31 @@ func (siw *ServerInterfaceWrapper) UpdateOrganizationMember(w http.ResponseWrite handler.ServeHTTP(w, r) } -// ListOrganizationNotificationProviders operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationNotificationProviders(w http.ResponseWriter, r *http.Request) { +// PreviewInstallationNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) PreviewInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationNotificationProviders(w, r, organizationId) + siw.Handler.PreviewInstallationNotificationTemplate(w, r, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19802,31 +23007,31 @@ func (siw *ServerInterfaceWrapper) ListOrganizationNotificationProviders(w http. handler.ServeHTTP(w, r) } -// CreateOrganizationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// PublishInstallationNotificationTemplate operation middleware +func (siw *ServerInterfaceWrapper) PublishInstallationNotificationTemplate(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "template_id" ------------- + var templateId UUID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "template_id", chi.URLParam(r, "template_id"), &templateId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "template_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateOrganizationNotificationProvider(w, r, organizationId) + siw.Handler.PublishInstallationNotificationTemplate(w, r, templateId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19836,8 +23041,8 @@ func (siw *ServerInterfaceWrapper) CreateOrganizationNotificationProvider(w http handler.ServeHTTP(w, r) } -// DisableOrganizationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// UpdateOrganizationPolicy operation middleware +func (siw *ServerInterfaceWrapper) UpdateOrganizationPolicy(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -19851,68 +23056,66 @@ func (siw *ServerInterfaceWrapper) DisableOrganizationNotificationProvider(w htt return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableOrganizationNotificationProvider(w, r, organizationId, providerId) - })) - - for _, middleware := range siw.HandlerMiddlewares { - handler = middleware(handler) - } + // Parameter object where we will unmarshal all parameters from the context + var params UpdateOrganizationPolicyParams - handler.ServeHTTP(w, r) -} + headers := r.Header -// GetOrganizationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) GetOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) + return + } - var err error - _ = err + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) + return + } - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + params.IfMatch = IfMatch - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + } else { + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.UpdateOrganizationPolicy(w, r, organizationId, params) + })) - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) } + handler.ServeHTTP(w, r) +} + +// ListSigningKeys operation middleware +func (siw *ServerInterfaceWrapper) ListSigningKeys(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetOrganizationNotificationProvider(w, r, organizationId, providerId) + siw.Handler.ListSigningKeys(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19922,40 +23125,41 @@ func (siw *ServerInterfaceWrapper) GetOrganizationNotificationProvider(w http.Re handler.ServeHTTP(w, r) } -// UpdateOrganizationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// RotateSigningKey operation middleware +func (siw *ServerInterfaceWrapper) RotateSigningKey(w http.ResponseWriter, r *http.Request) { - var err error - _ = err + ctx := r.Context() - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + r = r.WithContext(ctx) - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.RotateSigningKey(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) } + handler.ServeHTTP(w, r) +} + +// ListInstallationStorageObjects operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationStorageObjects(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOrganizationNotificationProvider(w, r, organizationId, providerId) + siw.Handler.ListInstallationStorageObjects(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -19965,64 +23169,47 @@ func (siw *ServerInterfaceWrapper) UpdateOrganizationNotificationProvider(w http handler.ServeHTTP(w, r) } -// TestOrganizationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) TestOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// DeleteInstallationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DeleteInstallationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx := r.Context() - - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) - - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params TestOrganizationNotificationProviderParams - - headers := r.Header + var params DeleteInstallationStorageObjectParams - // ------------- Optional header parameter "Idempotency-Key" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { - var IdempotencyKey IdempotencyKey - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) - return - } + // ------------- Optional query parameter "force" ------------- - err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) - return + err = runtime.BindQueryParameterWithOptions("form", true, false, "force", r.URL.Query(), ¶ms.Force, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "force"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "force", Err: err}) } - - params.IdempotencyKey = &IdempotencyKey - + return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.TestOrganizationNotificationProvider(w, r, organizationId, providerId, params) + siw.Handler.DeleteInstallationStorageObject(w, r, objectId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20032,40 +23219,31 @@ func (siw *ServerInterfaceWrapper) TestOrganizationNotificationProvider(w http.R handler.ServeHTTP(w, r) } -// VerifyOrganizationNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { +// GetInstallationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) GetInstallationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "provider_id" ------------- - var providerId UUID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyOrganizationNotificationProvider(w, r, organizationId, providerId) + siw.Handler.GetInstallationStorageObject(w, r, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20075,31 +23253,31 @@ func (siw *ServerInterfaceWrapper) VerifyOrganizationNotificationProvider(w http handler.ServeHTTP(w, r) } -// GetOrganizationPolicy operation middleware -func (siw *ServerInterfaceWrapper) GetOrganizationPolicy(w http.ResponseWriter, r *http.Request) { +// DownloadInstallationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DownloadInstallationStorageObject(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetOrganizationPolicy(w, r, organizationId) + siw.Handler.DownloadInstallationStorageObject(w, r, objectId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20109,31 +23287,19 @@ func (siw *ServerInterfaceWrapper) GetOrganizationPolicy(w http.ResponseWriter, handler.ServeHTTP(w, r) } -// RestoreOrganization operation middleware -func (siw *ServerInterfaceWrapper) RestoreOrganization(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// ListInstallationStorageProviders operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationStorageProviders(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.RestoreOrganization(w, r, organizationId) + siw.Handler.ListInstallationStorageProviders(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20143,31 +23309,19 @@ func (siw *ServerInterfaceWrapper) RestoreOrganization(w http.ResponseWriter, r handler.ServeHTTP(w, r) } -// ListOrganizationStorageObjects operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationStorageObjects(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err - - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } +// CreateInstallationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationStorageObjects(w, r, organizationId) + siw.Handler.CreateInstallationStorageProvider(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20177,56 +23331,47 @@ func (siw *ServerInterfaceWrapper) ListOrganizationStorageObjects(w http.Respons handler.ServeHTTP(w, r) } -// DeleteOrganizationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DeleteOrganizationStorageObject(w http.ResponseWriter, r *http.Request) { +// DisableInstallationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params DeleteOrganizationStorageObjectParams + var params DisableInstallationStorageProviderParams - // ------------- Optional query parameter "force" ------------- + // ------------- Optional query parameter "confirm_affected_objects" ------------- - err = runtime.BindQueryParameterWithOptions("form", true, false, "force", r.URL.Query(), ¶ms.Force, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + err = runtime.BindQueryParameterWithOptions("form", true, false, "confirm_affected_objects", r.URL.Query(), ¶ms.ConfirmAffectedObjects, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) if err != nil { var requiredError *runtime.RequiredParameterError if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "force"}) + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "confirm_affected_objects"}) } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "force", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "confirm_affected_objects", Err: err}) } return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DeleteOrganizationStorageObject(w, r, organizationId, objectId, params) + siw.Handler.DisableInstallationStorageProvider(w, r, providerId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20236,40 +23381,31 @@ func (siw *ServerInterfaceWrapper) DeleteOrganizationStorageObject(w http.Respon handler.ServeHTTP(w, r) } -// GetOrganizationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) GetOrganizationStorageObject(w http.ResponseWriter, r *http.Request) { +// GetInstallationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) GetInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetOrganizationStorageObject(w, r, organizationId, objectId) + siw.Handler.GetInstallationStorageProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20279,40 +23415,31 @@ func (siw *ServerInterfaceWrapper) GetOrganizationStorageObject(w http.ResponseW handler.ServeHTTP(w, r) } -// DownloadOrganizationStorageObject operation middleware -func (siw *ServerInterfaceWrapper) DownloadOrganizationStorageObject(w http.ResponseWriter, r *http.Request) { +// UpdateInstallationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "object_id" ------------- - var objectId ObjectID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DownloadOrganizationStorageObject(w, r, organizationId, objectId) + siw.Handler.UpdateInstallationStorageProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20322,31 +23449,31 @@ func (siw *ServerInterfaceWrapper) DownloadOrganizationStorageObject(w http.Resp handler.ServeHTTP(w, r) } -// ListOrganizationStorageProviders operation middleware -func (siw *ServerInterfaceWrapper) ListOrganizationStorageProviders(w http.ResponseWriter, r *http.Request) { +// EnableInstallationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) EnableInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ListOrganizationStorageProviders(w, r, organizationId) + siw.Handler.EnableInstallationStorageProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20356,31 +23483,31 @@ func (siw *ServerInterfaceWrapper) ListOrganizationStorageProviders(w http.Respo handler.ServeHTTP(w, r) } -// CreateOrganizationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { +// VerifyInstallationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyInstallationStorageProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateOrganizationStorageProvider(w, r, organizationId) + siw.Handler.VerifyInstallationStorageProvider(w, r, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20390,56 +23517,50 @@ func (siw *ServerInterfaceWrapper) CreateOrganizationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// DisableOrganizationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) DisableOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { +// CreateInstallationStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CreateInstallationStorageUpload(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } - ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params DisableOrganizationStorageProviderParams + var params CreateInstallationStorageUploadParams - // ------------- Optional query parameter "confirm_affected_objects" ------------- + headers := r.Header - err = runtime.BindQueryParameterWithOptions("form", true, false, "confirm_affected_objects", r.URL.Query(), ¶ms.ConfirmAffectedObjects, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) - if err != nil { - var requiredError *runtime.RequiredParameterError - if errors.As(err, &requiredError) { - siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "confirm_affected_objects"}) - } else { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "confirm_affected_objects", Err: err}) + // ------------- Required header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey RequiredIdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return } + + params.IdempotencyKey = IdempotencyKey + + } else { + err := fmt.Errorf("Header parameter Idempotency-Key is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "Idempotency-Key", Err: err}) return } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.DisableOrganizationStorageProvider(w, r, organizationId, providerId, params) + siw.Handler.CreateInstallationStorageUpload(w, r, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20449,40 +23570,53 @@ func (siw *ServerInterfaceWrapper) DisableOrganizationStorageProvider(w http.Res handler.ServeHTTP(w, r) } -// GetOrganizationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) GetOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { +// CompleteInstallationStorageUpload operation middleware +func (siw *ServerInterfaceWrapper) CompleteInstallationStorageUpload(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) return } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + ctx := r.Context() - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CompleteInstallationStorageUpload(w, r, objectId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) } + handler.ServeHTTP(w, r) +} + +// ListInstallationControlUsers operation middleware +func (siw *ServerInterfaceWrapper) ListInstallationControlUsers(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.GetOrganizationStorageProvider(w, r, organizationId, providerId) + siw.Handler.ListInstallationControlUsers(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20492,40 +23626,31 @@ func (siw *ServerInterfaceWrapper) GetOrganizationStorageProvider(w http.Respons handler.ServeHTTP(w, r) } -// UpdateOrganizationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) UpdateOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { +// DeleteInstallationControlUser operation middleware +func (siw *ServerInterfaceWrapper) DeleteInstallationControlUser(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "control_user_id" ------------- + var controlUserId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "control_user_id", chi.URLParam(r, "control_user_id"), &controlUserId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "control_user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.UpdateOrganizationStorageProvider(w, r, organizationId, providerId) + siw.Handler.DeleteInstallationControlUser(w, r, controlUserId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20535,40 +23660,31 @@ func (siw *ServerInterfaceWrapper) UpdateOrganizationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// EnableOrganizationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) EnableOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { +// UpdateInstallationControlUser operation middleware +func (siw *ServerInterfaceWrapper) UpdateInstallationControlUser(w http.ResponseWriter, r *http.Request) { var err error _ = err - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID - - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return - } - - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID + // ------------- Path parameter "control_user_id" ------------- + var controlUserId UUID - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + err = runtime.BindStyledParameterWithOptions("simple", "control_user_id", chi.URLParam(r, "control_user_id"), &controlUserId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "control_user_id", Err: err}) return } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.EnableOrganizationStorageProvider(w, r, organizationId, providerId) + siw.Handler.UpdateInstallationControlUser(w, r, controlUserId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20578,40 +23694,37 @@ func (siw *ServerInterfaceWrapper) EnableOrganizationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// VerifyOrganizationStorageProvider operation middleware -func (siw *ServerInterfaceWrapper) VerifyOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { - - var err error - _ = err +// AcceptControlUserInvitation operation middleware +func (siw *ServerInterfaceWrapper) AcceptControlUserInvitation(w http.ResponseWriter, r *http.Request) { - // ------------- Path parameter "organization_id" ------------- - var organizationId OrganizationID + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.AcceptControlUserInvitation(w, r) + })) - err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) - return + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) } - // ------------- Path parameter "provider_id" ------------- - var providerId ProviderID - - err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) - return - } + handler.ServeHTTP(w, r) +} - ctx := r.Context() +// StartControlInvitationExternalLogin operation middleware +func (siw *ServerInterfaceWrapper) StartControlInvitationExternalLogin(w http.ResponseWriter, r *http.Request) { - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + var err error + _ = err - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + // ------------- Path parameter "provider" ------------- + var provider string - r = r.WithContext(ctx) + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + return + } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.VerifyOrganizationStorageProvider(w, r, organizationId, providerId) + siw.Handler.StartControlInvitationExternalLogin(w, r, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20621,20 +23734,22 @@ func (siw *ServerInterfaceWrapper) VerifyOrganizationStorageProvider(w http.Resp handler.ServeHTTP(w, r) } -// ManagementListOrganizations operation middleware -func (siw *ServerInterfaceWrapper) ManagementListOrganizations(w http.ResponseWriter, r *http.Request) { +// ListOrganizations operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizations(w http.ResponseWriter, r *http.Request) { var err error _ = err ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params ManagementListOrganizationsParams + var params ListOrganizationsParams // ------------- Optional query parameter "include_retired" ------------- @@ -20650,7 +23765,7 @@ func (siw *ServerInterfaceWrapper) ManagementListOrganizations(w http.ResponseWr } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementListOrganizations(w, r, params) + siw.Handler.ListOrganizations(w, r, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20660,17 +23775,19 @@ func (siw *ServerInterfaceWrapper) ManagementListOrganizations(w http.ResponseWr handler.ServeHTTP(w, r) } -// ManagementCreateOrganization operation middleware -func (siw *ServerInterfaceWrapper) ManagementCreateOrganization(w http.ResponseWriter, r *http.Request) { +// CreateOrganization operation middleware +func (siw *ServerInterfaceWrapper) CreateOrganization(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementCreateOrganization(w, r) + siw.Handler.CreateOrganization(w, r) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20680,8 +23797,8 @@ func (siw *ServerInterfaceWrapper) ManagementCreateOrganization(w http.ResponseW handler.ServeHTTP(w, r) } -// ManagementRetireOrganization operation middleware -func (siw *ServerInterfaceWrapper) ManagementRetireOrganization(w http.ResponseWriter, r *http.Request) { +// RetireOrganization operation middleware +func (siw *ServerInterfaceWrapper) RetireOrganization(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -20697,12 +23814,14 @@ func (siw *ServerInterfaceWrapper) ManagementRetireOrganization(w http.ResponseW ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementRetireOrganization(w, r, organizationId) + siw.Handler.RetireOrganization(w, r, organizationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20712,8 +23831,8 @@ func (siw *ServerInterfaceWrapper) ManagementRetireOrganization(w http.ResponseW handler.ServeHTTP(w, r) } -// ManagementGetOrganization operation middleware -func (siw *ServerInterfaceWrapper) ManagementGetOrganization(w http.ResponseWriter, r *http.Request) { +// GetOrganization operation middleware +func (siw *ServerInterfaceWrapper) GetOrganization(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -20729,12 +23848,14 @@ func (siw *ServerInterfaceWrapper) ManagementGetOrganization(w http.ResponseWrit ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementGetOrganization(w, r, organizationId) + siw.Handler.GetOrganization(w, r, organizationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20744,8 +23865,8 @@ func (siw *ServerInterfaceWrapper) ManagementGetOrganization(w http.ResponseWrit handler.ServeHTTP(w, r) } -// ManagementUpdateOrganization operation middleware -func (siw *ServerInterfaceWrapper) ManagementUpdateOrganization(w http.ResponseWriter, r *http.Request) { +// UpdateOrganization operation middleware +func (siw *ServerInterfaceWrapper) UpdateOrganization(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -20761,40 +23882,14 @@ func (siw *ServerInterfaceWrapper) ManagementUpdateOrganization(w http.ResponseW ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) - - r = r.WithContext(ctx) - - // Parameter object where we will unmarshal all parameters from the context - var params ManagementUpdateOrganizationParams - - headers := r.Header - - // ------------- Required header parameter "If-Match" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { - var IfMatch IfMatch - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) - return - } + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - params.IfMatch = IfMatch + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) - } else { - err := fmt.Errorf("Header parameter If-Match is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) - return - } + r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementUpdateOrganization(w, r, organizationId, params) + siw.Handler.UpdateOrganization(w, r, organizationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20804,8 +23899,8 @@ func (siw *ServerInterfaceWrapper) ManagementUpdateOrganization(w http.ResponseW handler.ServeHTTP(w, r) } -// ManagementListApplications operation middleware -func (siw *ServerInterfaceWrapper) ManagementListApplications(w http.ResponseWriter, r *http.Request) { +// ListApplications operation middleware +func (siw *ServerInterfaceWrapper) ListApplications(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -20821,12 +23916,14 @@ func (siw *ServerInterfaceWrapper) ManagementListApplications(w http.ResponseWri ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) // Parameter object where we will unmarshal all parameters from the context - var params ManagementListApplicationsParams + var params ListApplicationsParams // ------------- Optional query parameter "include_retired" ------------- @@ -20842,7 +23939,7 @@ func (siw *ServerInterfaceWrapper) ManagementListApplications(w http.ResponseWri } handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementListApplications(w, r, organizationId, params) + siw.Handler.ListApplications(w, r, organizationId, params) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20852,8 +23949,8 @@ func (siw *ServerInterfaceWrapper) ManagementListApplications(w http.ResponseWri handler.ServeHTTP(w, r) } -// ManagementCreateApplication operation middleware -func (siw *ServerInterfaceWrapper) ManagementCreateApplication(w http.ResponseWriter, r *http.Request) { +// CreateApplication operation middleware +func (siw *ServerInterfaceWrapper) CreateApplication(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -20869,12 +23966,14 @@ func (siw *ServerInterfaceWrapper) ManagementCreateApplication(w http.ResponseWr ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementCreateApplication(w, r, organizationId) + siw.Handler.CreateApplication(w, r, organizationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20884,8 +23983,8 @@ func (siw *ServerInterfaceWrapper) ManagementCreateApplication(w http.ResponseWr handler.ServeHTTP(w, r) } -// ManagementRetireApplication operation middleware -func (siw *ServerInterfaceWrapper) ManagementRetireApplication(w http.ResponseWriter, r *http.Request) { +// RetireApplication operation middleware +func (siw *ServerInterfaceWrapper) RetireApplication(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -20910,12 +24009,14 @@ func (siw *ServerInterfaceWrapper) ManagementRetireApplication(w http.ResponseWr ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementRetireApplication(w, r, organizationId, applicationResourceId) + siw.Handler.RetireApplication(w, r, organizationId, applicationResourceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20925,8 +24026,8 @@ func (siw *ServerInterfaceWrapper) ManagementRetireApplication(w http.ResponseWr handler.ServeHTTP(w, r) } -// ManagementUpdateApplication operation middleware -func (siw *ServerInterfaceWrapper) ManagementUpdateApplication(w http.ResponseWriter, r *http.Request) { +// UpdateApplication operation middleware +func (siw *ServerInterfaceWrapper) UpdateApplication(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -20951,40 +24052,14 @@ func (siw *ServerInterfaceWrapper) ManagementUpdateApplication(w http.ResponseWr ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) - - r = r.WithContext(ctx) - - // Parameter object where we will unmarshal all parameters from the context - var params ManagementUpdateApplicationParams - - headers := r.Header - - // ------------- Required header parameter "If-Match" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { - var IfMatch IfMatch - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) - return - } - - err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) - return - } + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - params.IfMatch = IfMatch + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) - } else { - err := fmt.Errorf("Header parameter If-Match is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) - return - } + r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementUpdateApplication(w, r, organizationId, applicationResourceId, params) + siw.Handler.UpdateApplication(w, r, organizationId, applicationResourceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -20994,8 +24069,8 @@ func (siw *ServerInterfaceWrapper) ManagementUpdateApplication(w http.ResponseWr handler.ServeHTTP(w, r) } -// ManagementRestoreApplication operation middleware -func (siw *ServerInterfaceWrapper) ManagementRestoreApplication(w http.ResponseWriter, r *http.Request) { +// RestoreApplication operation middleware +func (siw *ServerInterfaceWrapper) RestoreApplication(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -21020,12 +24095,14 @@ func (siw *ServerInterfaceWrapper) ManagementRestoreApplication(w http.ResponseW ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementRestoreApplication(w, r, organizationId, applicationResourceId) + siw.Handler.RestoreApplication(w, r, organizationId, applicationResourceId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21035,8 +24112,8 @@ func (siw *ServerInterfaceWrapper) ManagementRestoreApplication(w http.ResponseW handler.ServeHTTP(w, r) } -// ManagementGetOrganizationPolicy operation middleware -func (siw *ServerInterfaceWrapper) ManagementGetOrganizationPolicy(w http.ResponseWriter, r *http.Request) { +// ListOrganizationAuditLogs operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationAuditLogs(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -21052,12 +24129,14 @@ func (siw *ServerInterfaceWrapper) ManagementGetOrganizationPolicy(w http.Respon ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementGetOrganizationPolicy(w, r, organizationId) + siw.Handler.ListOrganizationAuditLogs(w, r, organizationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21067,8 +24146,8 @@ func (siw *ServerInterfaceWrapper) ManagementGetOrganizationPolicy(w http.Respon handler.ServeHTTP(w, r) } -// ManagementUpdateOrganizationPolicy operation middleware -func (siw *ServerInterfaceWrapper) ManagementUpdateOrganizationPolicy(w http.ResponseWriter, r *http.Request) { +// ListOrganizationAuthProviders operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationAuthProviders(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -21084,40 +24163,57 @@ func (siw *ServerInterfaceWrapper) ManagementUpdateOrganizationPolicy(w http.Res ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) - // Parameter object where we will unmarshal all parameters from the context - var params ManagementUpdateOrganizationPolicyParams + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListOrganizationAuthProviders(w, r, organizationId) + })) - headers := r.Header + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } - // ------------- Required header parameter "If-Match" ------------- - if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { - var IfMatch IfMatch - n := len(valueList) - if n != 1 { - siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) - return - } + handler.ServeHTTP(w, r) +} - err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) - if err != nil { - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) - return - } +// DisableOrganizationAuthProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableOrganizationAuthProvider(w http.ResponseWriter, r *http.Request) { - params.IfMatch = IfMatch + var err error + _ = err - } else { - err := fmt.Errorf("Header parameter If-Match is required, but not found") - siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider" ------------- + var provider string + + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) return } + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementUpdateOrganizationPolicy(w, r, organizationId, params) + siw.Handler.DisableOrganizationAuthProvider(w, r, organizationId, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21127,8 +24223,8 @@ func (siw *ServerInterfaceWrapper) ManagementUpdateOrganizationPolicy(w http.Res handler.ServeHTTP(w, r) } -// ManagementRestoreOrganization operation middleware -func (siw *ServerInterfaceWrapper) ManagementRestoreOrganization(w http.ResponseWriter, r *http.Request) { +// UpdateOrganizationAuthProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateOrganizationAuthProvider(w http.ResponseWriter, r *http.Request) { var err error _ = err @@ -21142,14 +24238,25 @@ func (siw *ServerInterfaceWrapper) ManagementRestoreOrganization(w http.Response return } + // ------------- Path parameter "provider" ------------- + var provider string + + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + return + } + ctx := r.Context() - ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.ManagementRestoreOrganization(w, r, organizationId) + siw.Handler.UpdateOrganizationAuthProvider(w, r, organizationId, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21159,11 +24266,40 @@ func (siw *ServerInterfaceWrapper) ManagementRestoreOrganization(w http.Response handler.ServeHTTP(w, r) } -// Bootstrap operation middleware -func (siw *ServerInterfaceWrapper) Bootstrap(w http.ResponseWriter, r *http.Request) { +// ConfigureOrganizationAuthProvider operation middleware +func (siw *ServerInterfaceWrapper) ConfigureOrganizationAuthProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider" ------------- + var provider string + + err = runtime.BindStyledParameterWithOptions("simple", "provider", chi.URLParam(r, "provider"), &provider, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.Bootstrap(w, r) + siw.Handler.ConfigureOrganizationAuthProvider(w, r, organizationId, provider) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21173,19 +24309,31 @@ func (siw *ServerInterfaceWrapper) Bootstrap(w http.ResponseWriter, r *http.Requ handler.ServeHTTP(w, r) } -// CompleteSetup operation middleware -func (siw *ServerInterfaceWrapper) CompleteSetup(w http.ResponseWriter, r *http.Request) { +// ListOrganizationBillingProviders operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationBillingProviders(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CompleteSetup(w, r) + siw.Handler.ListOrganizationBillingProviders(w, r, organizationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21195,19 +24343,31 @@ func (siw *ServerInterfaceWrapper) CompleteSetup(w http.ResponseWriter, r *http. handler.ServeHTTP(w, r) } -// CreateSetupNotificationProvider operation middleware -func (siw *ServerInterfaceWrapper) CreateSetupNotificationProvider(w http.ResponseWriter, r *http.Request) { +// CreateOrganizationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } ctx := r.Context() - ctx = context.WithValue(ctx, OperatorBearerScopes, []string{}) + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) - ctx = context.WithValue(ctx, OperatorCookieScopes, []string{}) + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.CreateSetupNotificationProvider(w, r) + siw.Handler.CreateOrganizationBillingProvider(w, r, organizationId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21217,11 +24377,40 @@ func (siw *ServerInterfaceWrapper) CreateSetupNotificationProvider(w http.Respon handler.ServeHTTP(w, r) } -// SetupStatus operation middleware -func (siw *ServerInterfaceWrapper) SetupStatus(w http.ResponseWriter, r *http.Request) { +// DisableOrganizationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.SetupStatus(w, r) + siw.Handler.DisableOrganizationBillingProvider(w, r, organizationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21231,11 +24420,40 @@ func (siw *ServerInterfaceWrapper) SetupStatus(w http.ResponseWriter, r *http.Re handler.ServeHTTP(w, r) } -// Version operation middleware -func (siw *ServerInterfaceWrapper) Version(w http.ResponseWriter, r *http.Request) { +// GetOrganizationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) GetOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - siw.Handler.Version(w, r) + siw.Handler.GetOrganizationBillingProvider(w, r, organizationId, providerId) })) for _, middleware := range siw.HandlerMiddlewares { @@ -21245,130 +24463,1967 @@ func (siw *ServerInterfaceWrapper) Version(w http.ResponseWriter, r *http.Reques handler.ServeHTTP(w, r) } -type UnescapedCookieParamError struct { - ParamName string - Err error -} +// UpdateOrganizationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { -func (e *UnescapedCookieParamError) Error() string { - return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) -} + var err error + _ = err -func (e *UnescapedCookieParamError) Unwrap() error { - return e.Err -} + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID -type UnmarshalingParamError struct { - ParamName string - Err error -} + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } -func (e *UnmarshalingParamError) Error() string { - return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) -} + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID -func (e *UnmarshalingParamError) Unwrap() error { - return e.Err -} + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } -type RequiredParamError struct { - ParamName string -} + ctx := r.Context() -func (e *RequiredParamError) Error() string { - return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) -} + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) -type RequiredHeaderError struct { - ParamName string - Err error -} + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) -func (e *RequiredHeaderError) Error() string { - return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) -} + r = r.WithContext(ctx) -func (e *RequiredHeaderError) Unwrap() error { - return e.Err -} + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.UpdateOrganizationBillingProvider(w, r, organizationId, providerId) + })) -type InvalidParamFormatError struct { - ParamName string - Err error -} + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } -func (e *InvalidParamFormatError) Error() string { - return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) + handler.ServeHTTP(w, r) } -func (e *InvalidParamFormatError) Unwrap() error { - return e.Err -} +// VerifyOrganizationBillingProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyOrganizationBillingProvider(w http.ResponseWriter, r *http.Request) { -type TooManyValuesForParamError struct { - ParamName string - Count int -} + var err error + _ = err -func (e *TooManyValuesForParamError) Error() string { - return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) -} + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID -// Handler creates http.Handler with routing matching OpenAPI spec. -func Handler(si ServerInterface) http.Handler { - return HandlerWithOptions(si, ChiServerOptions{}) + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.VerifyOrganizationBillingProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) } -type ChiServerOptions struct { - BaseURL string - BaseRouter chi.Router - Middlewares []MiddlewareFunc - ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +// ListOrganizationInvitations operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationInvitations(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListOrganizationInvitations(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) } -// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. -func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler { - return HandlerWithOptions(si, ChiServerOptions{ - BaseRouter: r, - }) +// CreateOrganizationInvitation operation middleware +func (siw *ServerInterfaceWrapper) CreateOrganizationInvitation(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CreateOrganizationInvitation(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) } -func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { - return HandlerWithOptions(si, ChiServerOptions{ - BaseURL: baseURL, - BaseRouter: r, - }) +// RevokeOrganizationInvitation operation middleware +func (siw *ServerInterfaceWrapper) RevokeOrganizationInvitation(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.RevokeOrganizationInvitation(w, r, organizationId, invitationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) } -// HandlerWithOptions creates http.Handler with additional options -func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { - r := options.BaseRouter +// ResendOrganizationInvitation operation middleware +func (siw *ServerInterfaceWrapper) ResendOrganizationInvitation(w http.ResponseWriter, r *http.Request) { - if r == nil { - r = chi.NewRouter() + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return } - if options.ErrorHandlerFunc == nil { - options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { - http.Error(w, err.Error(), http.StatusBadRequest) - } + + // ------------- Path parameter "invitation_id" ------------- + var invitationId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "invitation_id", chi.URLParam(r, "invitation_id"), &invitationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "invitation_id", Err: err}) + return } - wrapper := ServerInterfaceWrapper{ - Handler: si, - HandlerMiddlewares: options.Middlewares, - ErrorHandlerFunc: options.ErrorHandlerFunc, + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ResendOrganizationInvitation(w, r, organizationId, invitationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) } - r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/healthz", wrapper.Health) - }) - r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/oidc/.well-known/openid-configuration", wrapper.OidcDiscovery) - }) - r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/oidc/authorize", wrapper.BeginOIDCAuthorization) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/oidc/authorize", wrapper.DecideOIDCAuthorization) + handler.ServeHTTP(w, r) +} + +// ListOrganizationMembers operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationMembers(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListOrganizationMembers(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// DeleteOrganizationMember operation middleware +func (siw *ServerInterfaceWrapper) DeleteOrganizationMember(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "member_id" ------------- + var memberId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "member_id", chi.URLParam(r, "member_id"), &memberId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "member_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.DeleteOrganizationMember(w, r, organizationId, memberId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// UpdateOrganizationMember operation middleware +func (siw *ServerInterfaceWrapper) UpdateOrganizationMember(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "member_id" ------------- + var memberId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "member_id", chi.URLParam(r, "member_id"), &memberId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "member_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.UpdateOrganizationMember(w, r, organizationId, memberId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ListOrganizationNotificationProviders operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationNotificationProviders(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListOrganizationNotificationProviders(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// CreateOrganizationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CreateOrganizationNotificationProvider(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// DisableOrganizationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.DisableOrganizationNotificationProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetOrganizationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) GetOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetOrganizationNotificationProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// UpdateOrganizationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.UpdateOrganizationNotificationProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// TestOrganizationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) TestOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params TestOrganizationNotificationProviderParams + + headers := r.Header + + // ------------- Optional header parameter "Idempotency-Key" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("Idempotency-Key")]; found { + var IdempotencyKey IdempotencyKey + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "Idempotency-Key", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "Idempotency-Key", valueList[0], &IdempotencyKey, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: false, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "Idempotency-Key", Err: err}) + return + } + + params.IdempotencyKey = &IdempotencyKey + + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.TestOrganizationNotificationProvider(w, r, organizationId, providerId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// VerifyOrganizationNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyOrganizationNotificationProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.VerifyOrganizationNotificationProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetOrganizationPolicy operation middleware +func (siw *ServerInterfaceWrapper) GetOrganizationPolicy(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetOrganizationPolicy(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// RestoreOrganization operation middleware +func (siw *ServerInterfaceWrapper) RestoreOrganization(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.RestoreOrganization(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ListOrganizationStorageObjects operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationStorageObjects(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListOrganizationStorageObjects(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// DeleteOrganizationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DeleteOrganizationStorageObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID + + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params DeleteOrganizationStorageObjectParams + + // ------------- Optional query parameter "force" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "force", r.URL.Query(), ¶ms.Force, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "force"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "force", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.DeleteOrganizationStorageObject(w, r, organizationId, objectId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetOrganizationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) GetOrganizationStorageObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID + + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetOrganizationStorageObject(w, r, organizationId, objectId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// DownloadOrganizationStorageObject operation middleware +func (siw *ServerInterfaceWrapper) DownloadOrganizationStorageObject(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "object_id" ------------- + var objectId ObjectID + + err = runtime.BindStyledParameterWithOptions("simple", "object_id", chi.URLParam(r, "object_id"), &objectId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "object_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.DownloadOrganizationStorageObject(w, r, organizationId, objectId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ListOrganizationStorageProviders operation middleware +func (siw *ServerInterfaceWrapper) ListOrganizationStorageProviders(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ListOrganizationStorageProviders(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// CreateOrganizationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CreateOrganizationStorageProvider(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// DisableOrganizationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) DisableOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params DisableOrganizationStorageProviderParams + + // ------------- Optional query parameter "confirm_affected_objects" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "confirm_affected_objects", r.URL.Query(), ¶ms.ConfirmAffectedObjects, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "confirm_affected_objects"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "confirm_affected_objects", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.DisableOrganizationStorageProvider(w, r, organizationId, providerId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// GetOrganizationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) GetOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.GetOrganizationStorageProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// UpdateOrganizationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) UpdateOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.UpdateOrganizationStorageProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// EnableOrganizationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) EnableOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.EnableOrganizationStorageProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// VerifyOrganizationStorageProvider operation middleware +func (siw *ServerInterfaceWrapper) VerifyOrganizationStorageProvider(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "provider_id" ------------- + var providerId ProviderID + + err = runtime.BindStyledParameterWithOptions("simple", "provider_id", chi.URLParam(r, "provider_id"), &providerId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "provider_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.VerifyOrganizationStorageProvider(w, r, organizationId, providerId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementListOrganizations operation middleware +func (siw *ServerInterfaceWrapper) ManagementListOrganizations(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params ManagementListOrganizationsParams + + // ------------- Optional query parameter "include_retired" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "include_retired", r.URL.Query(), ¶ms.IncludeRetired, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "include_retired"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "include_retired", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementListOrganizations(w, r, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementCreateOrganization operation middleware +func (siw *ServerInterfaceWrapper) ManagementCreateOrganization(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementCreateOrganization(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementRetireOrganization operation middleware +func (siw *ServerInterfaceWrapper) ManagementRetireOrganization(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementRetireOrganization(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementGetOrganization operation middleware +func (siw *ServerInterfaceWrapper) ManagementGetOrganization(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementGetOrganization(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementUpdateOrganization operation middleware +func (siw *ServerInterfaceWrapper) ManagementUpdateOrganization(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params ManagementUpdateOrganizationParams + + headers := r.Header + + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) + return + } + + params.IfMatch = IfMatch + + } else { + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementUpdateOrganization(w, r, organizationId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementListApplications operation middleware +func (siw *ServerInterfaceWrapper) ManagementListApplications(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params ManagementListApplicationsParams + + // ------------- Optional query parameter "include_retired" ------------- + + err = runtime.BindQueryParameterWithOptions("form", true, false, "include_retired", r.URL.Query(), ¶ms.IncludeRetired, runtime.BindQueryParameterOptions{Type: "boolean", Format: ""}) + if err != nil { + var requiredError *runtime.RequiredParameterError + if errors.As(err, &requiredError) { + siw.ErrorHandlerFunc(w, r, &RequiredParamError{ParamName: "include_retired"}) + } else { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "include_retired", Err: err}) + } + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementListApplications(w, r, organizationId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementCreateApplication operation middleware +func (siw *ServerInterfaceWrapper) ManagementCreateApplication(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementCreateApplication(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementRetireApplication operation middleware +func (siw *ServerInterfaceWrapper) ManagementRetireApplication(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "application_resource_id" ------------- + var applicationResourceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "application_resource_id", chi.URLParam(r, "application_resource_id"), &applicationResourceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_resource_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementRetireApplication(w, r, organizationId, applicationResourceId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementUpdateApplication operation middleware +func (siw *ServerInterfaceWrapper) ManagementUpdateApplication(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "application_resource_id" ------------- + var applicationResourceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "application_resource_id", chi.URLParam(r, "application_resource_id"), &applicationResourceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_resource_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params ManagementUpdateApplicationParams + + headers := r.Header + + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) + return + } + + params.IfMatch = IfMatch + + } else { + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementUpdateApplication(w, r, organizationId, applicationResourceId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementRestoreApplication operation middleware +func (siw *ServerInterfaceWrapper) ManagementRestoreApplication(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + // ------------- Path parameter "application_resource_id" ------------- + var applicationResourceId UUID + + err = runtime.BindStyledParameterWithOptions("simple", "application_resource_id", chi.URLParam(r, "application_resource_id"), &applicationResourceId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "application_resource_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementRestoreApplication(w, r, organizationId, applicationResourceId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementGetOrganizationPolicy operation middleware +func (siw *ServerInterfaceWrapper) ManagementGetOrganizationPolicy(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementGetOrganizationPolicy(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementUpdateOrganizationPolicy operation middleware +func (siw *ServerInterfaceWrapper) ManagementUpdateOrganizationPolicy(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + // Parameter object where we will unmarshal all parameters from the context + var params ManagementUpdateOrganizationPolicyParams + + headers := r.Header + + // ------------- Required header parameter "If-Match" ------------- + if valueList, found := headers[http.CanonicalHeaderKey("If-Match")]; found { + var IfMatch IfMatch + n := len(valueList) + if n != 1 { + siw.ErrorHandlerFunc(w, r, &TooManyValuesForParamError{ParamName: "If-Match", Count: n}) + return + } + + err = runtime.BindStyledParameterWithOptions("simple", "If-Match", valueList[0], &IfMatch, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true, Type: "string", Format: ""}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "If-Match", Err: err}) + return + } + + params.IfMatch = IfMatch + + } else { + err := fmt.Errorf("Header parameter If-Match is required, but not found") + siw.ErrorHandlerFunc(w, r, &RequiredHeaderError{ParamName: "If-Match", Err: err}) + return + } + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementUpdateOrganizationPolicy(w, r, organizationId, params) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// ManagementRestoreOrganization operation middleware +func (siw *ServerInterfaceWrapper) ManagementRestoreOrganization(w http.ResponseWriter, r *http.Request) { + + var err error + _ = err + + // ------------- Path parameter "organization_id" ------------- + var organizationId OrganizationID + + err = runtime.BindStyledParameterWithOptions("simple", "organization_id", chi.URLParam(r, "organization_id"), &organizationId, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true, Type: "string", Format: "uuid"}) + if err != nil { + siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "organization_id", Err: err}) + return + } + + ctx := r.Context() + + ctx = context.WithValue(ctx, ManagementBearerScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.ManagementRestoreOrganization(w, r, organizationId) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// Bootstrap operation middleware +func (siw *ServerInterfaceWrapper) Bootstrap(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.Bootstrap(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// CompleteSetup operation middleware +func (siw *ServerInterfaceWrapper) CompleteSetup(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CompleteSetup(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// CreateSetupNotificationProvider operation middleware +func (siw *ServerInterfaceWrapper) CreateSetupNotificationProvider(w http.ResponseWriter, r *http.Request) { + + ctx := r.Context() + + ctx = context.WithValue(ctx, ControlBearerScopes, []string{}) + + ctx = context.WithValue(ctx, ControlCookieScopes, []string{}) + + r = r.WithContext(ctx) + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.CreateSetupNotificationProvider(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// SetupStatus operation middleware +func (siw *ServerInterfaceWrapper) SetupStatus(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.SetupStatus(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +// Version operation middleware +func (siw *ServerInterfaceWrapper) Version(w http.ResponseWriter, r *http.Request) { + + handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.Version(w, r) + })) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r) +} + +type UnescapedCookieParamError struct { + ParamName string + Err error +} + +func (e *UnescapedCookieParamError) Error() string { + return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) +} + +func (e *UnescapedCookieParamError) Unwrap() error { + return e.Err +} + +type UnmarshalingParamError struct { + ParamName string + Err error +} + +func (e *UnmarshalingParamError) Error() string { + return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) +} + +func (e *UnmarshalingParamError) Unwrap() error { + return e.Err +} + +type RequiredParamError struct { + ParamName string +} + +func (e *RequiredParamError) Error() string { + return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) +} + +type RequiredHeaderError struct { + ParamName string + Err error +} + +func (e *RequiredHeaderError) Error() string { + return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) +} + +func (e *RequiredHeaderError) Unwrap() error { + return e.Err +} + +type InvalidParamFormatError struct { + ParamName string + Err error +} + +func (e *InvalidParamFormatError) Error() string { + return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) +} + +func (e *InvalidParamFormatError) Unwrap() error { + return e.Err +} + +type TooManyValuesForParamError struct { + ParamName string + Count int +} + +func (e *TooManyValuesForParamError) Error() string { + return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) +} + +// Handler creates http.Handler with routing matching OpenAPI spec. +func Handler(si ServerInterface) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + Middlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. +func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + if options.ErrorHandlerFunc == nil { + options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.Middlewares, + ErrorHandlerFunc: options.ErrorHandlerFunc, + } + + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/healthz", wrapper.Health) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/oidc/.well-known/openid-configuration", wrapper.OidcDiscovery) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/oidc/authorize", wrapper.BeginOIDCAuthorization) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/oidc/authorize", wrapper.DecideOIDCAuthorization) }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/oidc/introspect", wrapper.IntrospectOIDCToken) @@ -21397,6 +26452,12 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/email/verify", wrapper.EmailVerify) }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/invitations/exchange", wrapper.ExchangeApplicationInvitation) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/invitations/token", wrapper.RedeemApplicationInvitation) + }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/logout", wrapper.LogoutCurrentSession) }) @@ -21427,18 +26488,12 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/applications/{application_id}/auth/providers", wrapper.ListAuthProviders) }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/providers/apple/callback", wrapper.AppleAuthCallback) - }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/providers/apple/exchange", wrapper.ExchangeAppleAuth) }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/providers/apple/start", wrapper.StartAppleAuth) }) - r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/v1/applications/{application_id}/auth/providers/google/callback", wrapper.GoogleAuthCallback) - }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/auth/providers/google/exchange", wrapper.ExchangeGoogleAuth) }) @@ -21466,6 +26521,21 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/events", wrapper.PublishCustomEvent) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/invitations", wrapper.ListApplicationInvitations) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/invitations", wrapper.CreateApplicationInvitationMachine) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/applications/{application_id}/invitations/{invitation_id}", wrapper.RevokeApplicationInvitation) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/invitations/{invitation_id}", wrapper.GetApplicationInvitation) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/invitations/{invitation_id}/resend", wrapper.ResendApplicationInvitation) + }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/local-entitlement-checkouts", wrapper.LocalEntitlementCheckout) }) @@ -21629,10 +26699,7 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Get(options.BaseURL+"/v1/applications/{application_id}/me/subscriptions", wrapper.ListMySubscriptions) }) r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/v1/applications/{application_id}/me/workspace-invitations", wrapper.ListMyWorkspaceInvitations) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept", wrapper.AcceptMyWorkspaceInvitation) + r.Get(options.BaseURL+"/v1/applications/{application_id}/me/workspace-invitations", wrapper.ListMyPendingInvitations) }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/applications/{application_id}/me/workspaces", wrapper.ListMyWorkspaces) @@ -21640,9 +26707,33 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/me/workspaces", wrapper.CreateMyWorkspace) }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/notifications", wrapper.SendMachineNotification) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/permission-grants", wrapper.ListPermissionGrants) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/permission-grants", wrapper.CreatePermissionGrant) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/permission-grants/effective", wrapper.GetEffectiveAccess) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/applications/{application_id}/permission-grants/{grant_id}", wrapper.RevokePermissionGrant) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/permission-grants/{grant_id}", wrapper.GetPermissionGrant) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/applications/{application_id}/public-config", wrapper.PublicConfig) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/service/workspaces/{workspace_id}", wrapper.ServiceGetApplicationWorkspace) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/service/workspaces/{workspace_id}/access", wrapper.ServiceListApplicationWorkspaceAccess) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/applications/{application_id}/storage/objects", wrapper.ListApplicationStorageObjects) }) @@ -21661,6 +26752,21 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/storage/uploads/{object_id}/complete", wrapper.CompleteApplicationStorageUpload) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing", wrapper.ServiceGetSubjectBilling) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements", wrapper.ServiceGetSubjectEntitlements) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/users", wrapper.ServiceListApplicationUsers) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/users/{user_id}", wrapper.ServiceGetApplicationUser) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces", wrapper.ServiceListApplicationWorkspaces) + }) r.Group(func(r chi.Router) { r.Delete(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}", wrapper.ArchiveMyWorkspace) }) @@ -21670,6 +26776,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Patch(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}", wrapper.UpdateMyWorkspace) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/access", wrapper.ListMyWorkspaceAccess) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/addresses", wrapper.ListWorkspaceAddresses) }) @@ -21691,9 +26800,18 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Patch(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/billing-profile", wrapper.UpdateWorkspaceBillingProfile) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/invitations", wrapper.ListMyWorkspaceInvitations) + }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/invitations", wrapper.CreateMyWorkspaceInvitation) }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}", wrapper.RevokeMyWorkspaceInvitation) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend", wrapper.ResendMyWorkspaceInvitation) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/members", wrapper.ListMyWorkspaceMembers) }) @@ -21709,6 +26827,18 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/owner-transfer", wrapper.TransferMyWorkspaceOwnership) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants", wrapper.ListWorkspacePermissionGrants) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants", wrapper.CreateWorkspacePermissionGrant) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}", wrapper.RevokeWorkspacePermissionGrant) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}", wrapper.GetWorkspacePermissionGrant) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects", wrapper.ListWorkspaceStorageObjects) }) @@ -21727,6 +26857,12 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/applications/{application_id}/workspaces/{workspace_id}/storage/uploads/{object_id}/complete", wrapper.CompleteWorkspaceStorageUpload) }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/auth/providers/apple/callback", wrapper.AppleAuthCallback) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/auth/providers/google/callback", wrapper.GoogleAuthCallback) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/applications/{application_id}", wrapper.GetApplication) }) @@ -21844,6 +26980,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Delete(options.BaseURL+"/v1/control/applications/{application_id}/clients/{client_id}", wrapper.DisableClient) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/applications/{application_id}/clients/{client_id}", wrapper.GetClient) + }) r.Group(func(r chi.Router) { r.Patch(options.BaseURL+"/v1/control/applications/{application_id}/clients/{client_id}", wrapper.UpdateClient) }) @@ -21883,6 +27022,9 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/applications/{application_id}/entitlements/{entitlement_id}", wrapper.GetEntitlement) }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust", wrapper.AdjustEntitlement) + }) r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/control/applications/{application_id}/entitlements/{entitlement_id}/restore", wrapper.RestoreEntitlement) }) @@ -21919,6 +27061,21 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Patch(options.BaseURL+"/v1/control/applications/{application_id}/internal-config", wrapper.UpdateInternalApplicationConfig) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/applications/{application_id}/invitations", wrapper.ListApplicationInvitationsControl) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/applications/{application_id}/invitations", wrapper.CreateApplicationInvitationControl) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/control/applications/{application_id}/invitations/{invitation_id}", wrapper.RevokeApplicationInvitationControl) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/applications/{application_id}/invitations/{invitation_id}", wrapper.GetApplicationInvitationControl) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/applications/{application_id}/invitations/{invitation_id}/resend", wrapper.ResendApplicationInvitationControl) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/applications/{application_id}/local-entitlement-requests", wrapper.ListLocalEntitlementRequests) }) @@ -21982,9 +27139,6 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/applications/{application_id}/notifications", wrapper.ListNotifications) }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/applications/{application_id}/notifications", wrapper.QueueNotification) - }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/applications/{application_id}/notifications/statistics", wrapper.GetNotificationStatistics) }) @@ -22000,6 +27154,21 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/control/applications/{application_id}/oauth-consents/{user_id}/{client_id}/revoke", wrapper.RevokeOAuthConsent) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/applications/{application_id}/permission-grants", wrapper.ListControlPermissionGrants) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/applications/{application_id}/permission-grants", wrapper.CreateControlPermissionGrant) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/applications/{application_id}/permission-grants/effective", wrapper.GetControlEffectiveAccess) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/control/applications/{application_id}/permission-grants/{grant_id}", wrapper.RevokeControlPermissionGrant) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/applications/{application_id}/permission-grants/{grant_id}", wrapper.GetControlPermissionGrant) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/applications/{application_id}/products", wrapper.ListProducts) }) @@ -22165,15 +27334,6 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/control/applications/{application_id}/webhooks/{webhook_id}/test", wrapper.TestWebhook) }) - r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/v1/control/applications/{application_id}/workspace-invitations", wrapper.ListWorkspaceInvitations) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/applications/{application_id}/workspace-invitations", wrapper.CreateWorkspaceInvitation) - }) - r.Group(func(r chi.Router) { - r.Delete(options.BaseURL+"/v1/control/applications/{application_id}/workspace-invitations/{invitation_id}", wrapper.RevokeWorkspaceInvitation) - }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/applications/{application_id}/workspaces", wrapper.ListWorkspaces) }) @@ -22202,37 +27362,55 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Post(options.BaseURL+"/v1/control/applications/{application_id}/workspaces/{workspace_id}/owner-transfer", wrapper.RecoverWorkspaceOwnership) }) r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/auth/email/start", wrapper.StartOperatorEmailLogin) + r.Post(options.BaseURL+"/v1/control/auth/email/start", wrapper.StartControlUserEmailLogin) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/auth/email/verify", wrapper.VerifyControlUserEmailLogin) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/control/auth/identities/{identity_id}", wrapper.UnlinkControlExternalIdentity) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/auth/logout", wrapper.LogoutControlUser) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/auth/logout-all", wrapper.LogoutAllControlUserSessions) + }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/auth/me", wrapper.GetControlUserAccount) + }) + r.Group(func(r chi.Router) { + r.Patch(options.BaseURL+"/v1/control/auth/me", wrapper.UpdateControlUserAccount) }) r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/auth/email/verify", wrapper.VerifyOperatorEmailLogin) + r.Get(options.BaseURL+"/v1/control/auth/methods", wrapper.GetControlAuthMethods) }) r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/auth/logout", wrapper.LogoutOperator) + r.Post(options.BaseURL+"/v1/control/auth/password", wrapper.LoginControlUserWithPassword) }) r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/auth/logout-all", wrapper.LogoutAllOperatorSessions) + r.Put(options.BaseURL+"/v1/control/auth/password", wrapper.ChangeControlUserPassword) }) r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/v1/control/auth/me", wrapper.GetOperatorAccount) + r.Post(options.BaseURL+"/v1/control/auth/providers/{provider}/link", wrapper.LinkControlExternalIdentity) }) r.Group(func(r chi.Router) { - r.Patch(options.BaseURL+"/v1/control/auth/me", wrapper.UpdateOperatorAccount) + r.Post(options.BaseURL+"/v1/control/auth/providers/{provider}/start", wrapper.StartControlExternalLogin) }) r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/auth/password", wrapper.LoginOperatorWithPassword) + r.Get(options.BaseURL+"/v1/control/auth/sessions", wrapper.ListControlUserSessions) }) r.Group(func(r chi.Router) { - r.Put(options.BaseURL+"/v1/control/auth/password", wrapper.ChangeOperatorPassword) + r.Delete(options.BaseURL+"/v1/control/auth/sessions/{session_id}", wrapper.RevokeControlUserSession) }) r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/v1/control/auth/sessions", wrapper.ListOperatorSessions) + r.Post(options.BaseURL+"/v1/control/auth/token/refresh", wrapper.RefreshControlUserSession) }) r.Group(func(r chi.Router) { - r.Delete(options.BaseURL+"/v1/control/auth/sessions/{session_id}", wrapper.RevokeOperatorSession) + r.Get(options.BaseURL+"/v1/control/installation/auth-policy", wrapper.GetControlAuthPolicy) }) r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/auth/token/refresh", wrapper.RefreshOperatorSession) + r.Patch(options.BaseURL+"/v1/control/installation/auth-policy", wrapper.UpdateControlAuthPolicy) }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/installation/auth/providers", wrapper.ListInstallationAuthProviders) @@ -22264,6 +27442,18 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/control/installation/billing/providers/{provider_id}/verify", wrapper.VerifyInstallationBillingProvider) }) + r.Group(func(r chi.Router) { + r.Get(options.BaseURL+"/v1/control/installation/invitations", wrapper.ListInstallationControlUserInvitations) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/installation/invitations", wrapper.CreateInstallationControlUserInvitation) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/control/installation/invitations/{invitation_id}", wrapper.RevokeInstallationControlUserInvitation) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/installation/invitations/{invitation_id}/resend", wrapper.ResendInstallationControlUserInvitation) + }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/installation/management-api", wrapper.GetManagementAPIStatus) }) @@ -22327,18 +27517,6 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Group(func(r chi.Router) { r.Post(options.BaseURL+"/v1/control/installation/notification-templates/{template_id}/publish", wrapper.PublishInstallationNotificationTemplate) }) - r.Group(func(r chi.Router) { - r.Get(options.BaseURL+"/v1/control/installation/operators", wrapper.ListInstallationOperators) - }) - r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/installation/operators", wrapper.CreateInstallationOperator) - }) - r.Group(func(r chi.Router) { - r.Delete(options.BaseURL+"/v1/control/installation/operators/{operator_id}", wrapper.DeleteInstallationOperator) - }) - r.Group(func(r chi.Router) { - r.Patch(options.BaseURL+"/v1/control/installation/operators/{operator_id}", wrapper.UpdateInstallationOperator) - }) r.Group(func(r chi.Router) { r.Put(options.BaseURL+"/v1/control/installation/organizations/{organization_id}/policy", wrapper.UpdateOrganizationPolicy) }) @@ -22388,7 +27566,19 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Post(options.BaseURL+"/v1/control/installation/storage/uploads/{object_id}/complete", wrapper.CompleteInstallationStorageUpload) }) r.Group(func(r chi.Router) { - r.Post(options.BaseURL+"/v1/control/organization-invitations/accept", wrapper.AcceptOrganizationInvitation) + r.Get(options.BaseURL+"/v1/control/installation/users", wrapper.ListInstallationControlUsers) + }) + r.Group(func(r chi.Router) { + r.Delete(options.BaseURL+"/v1/control/installation/users/{control_user_id}", wrapper.DeleteInstallationControlUser) + }) + r.Group(func(r chi.Router) { + r.Patch(options.BaseURL+"/v1/control/installation/users/{control_user_id}", wrapper.UpdateInstallationControlUser) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/invitations/accept", wrapper.AcceptControlUserInvitation) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/v1/control/invitations/providers/{provider}/start", wrapper.StartControlInvitationExternalLogin) }) r.Group(func(r chi.Router) { r.Get(options.BaseURL+"/v1/control/organizations", wrapper.ListOrganizations) @@ -22589,403 +27779,1235 @@ func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handl r.Get(options.BaseURL+"/version", wrapper.Version) }) - return r + return r +} + +type OwnershipTransferResultJSONResponse OwnershipTransferResult + +type ProblemApplicationProblemPlusJSONResponse Problem + +type TokensJSONResponse TokenResponse + +type HealthRequestObject struct { +} + +type HealthResponseObject interface { + VisitHealthResponse(w http.ResponseWriter) error +} + +type Health200JSONResponse HealthStatus + +func (response Health200JSONResponse) VisitHealthResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type OidcDiscoveryRequestObject struct { +} + +type OidcDiscoveryResponseObject interface { + VisitOidcDiscoveryResponse(w http.ResponseWriter) error +} + +type OidcDiscovery200JSONResponse OIDCDiscovery + +func (response OidcDiscovery200JSONResponse) VisitOidcDiscoveryResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type BeginOIDCAuthorizationRequestObject struct { + Params BeginOIDCAuthorizationParams +} + +type BeginOIDCAuthorizationResponseObject interface { + VisitBeginOIDCAuthorizationResponse(w http.ResponseWriter) error +} + +type BeginOIDCAuthorization200JSONResponse AuthorizationRedirect + +func (response BeginOIDCAuthorization200JSONResponse) VisitBeginOIDCAuthorizationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type BeginOIDCAuthorization302Response struct { +} + +func (response BeginOIDCAuthorization302Response) VisitBeginOIDCAuthorizationResponse(w http.ResponseWriter) error { + w.WriteHeader(302) + return nil +} + +type DecideOIDCAuthorizationRequestObject struct { + Body *DecideOIDCAuthorizationFormdataRequestBody +} + +type DecideOIDCAuthorizationResponseObject interface { + VisitDecideOIDCAuthorizationResponse(w http.ResponseWriter) error +} + +type DecideOIDCAuthorization200JSONResponse AuthorizationRedirect + +func (response DecideOIDCAuthorization200JSONResponse) VisitDecideOIDCAuthorizationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type DecideOIDCAuthorization302Response struct { +} + +func (response DecideOIDCAuthorization302Response) VisitDecideOIDCAuthorizationResponse(w http.ResponseWriter) error { + w.WriteHeader(302) + return nil +} + +type IntrospectOIDCTokenRequestObject struct { + Body *IntrospectOIDCTokenFormdataRequestBody +} + +type IntrospectOIDCTokenResponseObject interface { + VisitIntrospectOIDCTokenResponse(w http.ResponseWriter) error +} + +type IntrospectOIDCToken200JSONResponse TokenIntrospection + +func (response IntrospectOIDCToken200JSONResponse) VisitIntrospectOIDCTokenResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type OidcJWKSRequestObject struct { +} + +type OidcJWKSResponseObject interface { + VisitOidcJWKSResponse(w http.ResponseWriter) error +} + +type OidcJWKS200JSONResponse JWKS + +func (response OidcJWKS200JSONResponse) VisitOidcJWKSResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type RevokeOIDCTokenRequestObject struct { + Body *RevokeOIDCTokenFormdataRequestBody +} + +type RevokeOIDCTokenResponseObject interface { + VisitRevokeOIDCTokenResponse(w http.ResponseWriter) error +} + +type RevokeOIDCToken200JSONResponse EmptyResponse + +func (response RevokeOIDCToken200JSONResponse) VisitRevokeOIDCTokenResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type ExchangeOIDCTokenRequestObject struct { + Body *ExchangeOIDCTokenFormdataRequestBody +} + +type ExchangeOIDCTokenResponseObject interface { + VisitExchangeOIDCTokenResponse(w http.ResponseWriter) error +} + +type ExchangeOIDCToken200JSONResponse TokenResponse + +func (response ExchangeOIDCToken200JSONResponse) VisitExchangeOIDCTokenResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type ExchangeOIDCToken400Response struct { +} + +func (response ExchangeOIDCToken400Response) VisitExchangeOIDCTokenResponse(w http.ResponseWriter) error { + w.WriteHeader(400) + return nil +} + +type OidcUserinfoRequestObject struct { +} + +type OidcUserinfoResponseObject interface { + VisitOidcUserinfoResponse(w http.ResponseWriter) error +} + +type OidcUserinfo200JSONResponse UserInfo + +func (response OidcUserinfo200JSONResponse) VisitOidcUserinfoResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type OidcUserinfo401ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response OidcUserinfo401ApplicationProblemPlusJSONResponse) VisitOidcUserinfoResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(401) + _, err := buf.WriteTo(w) + return err +} + +type StripeWebhookRequestObject struct { + ConnectionPublicId string `json:"connection_public_id"` + Params StripeWebhookParams + Body *StripeWebhookJSONRequestBody +} + +type StripeWebhookResponseObject interface { + VisitStripeWebhookResponse(w http.ResponseWriter) error +} + +type StripeWebhook200JSONResponse WebhookAcknowledgement + +func (response StripeWebhook200JSONResponse) VisitStripeWebhookResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type StripeWebhook400ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response StripeWebhook400ApplicationProblemPlusJSONResponse) VisitStripeWebhookResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(400) + _, err := buf.WriteTo(w) + return err +} + +type ReadinessRequestObject struct { +} + +type ReadinessResponseObject interface { + VisitReadinessResponse(w http.ResponseWriter) error +} + +type Readiness200JSONResponse HealthStatus + +func (response Readiness200JSONResponse) VisitReadinessResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type Readiness503ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response Readiness503ApplicationProblemPlusJSONResponse) VisitReadinessResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(503) + _, err := buf.WriteTo(w) + return err +} + +type EmailStartRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *EmailStartJSONRequestBody +} + +type EmailStartResponseObject interface { + VisitEmailStartResponse(w http.ResponseWriter) error +} + +type EmailStart202JSONResponse ChallengeAccepted + +func (response EmailStart202JSONResponse) VisitEmailStartResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) + _, err := buf.WriteTo(w) + return err +} + +type EmailVerifyRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *EmailVerifyJSONRequestBody +} + +type EmailVerifyResponseObject interface { + VisitEmailVerifyResponse(w http.ResponseWriter) error +} + +type EmailVerify200JSONResponse struct{ TokensJSONResponse } + +func (response EmailVerify200JSONResponse) VisitEmailVerifyResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type ExchangeApplicationInvitationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *ExchangeApplicationInvitationJSONRequestBody +} + +type ExchangeApplicationInvitationResponseObject interface { + VisitExchangeApplicationInvitationResponse(w http.ResponseWriter) error +} + +type ExchangeApplicationInvitation200JSONResponse InvitationExchangeResult + +func (response ExchangeApplicationInvitation200JSONResponse) VisitExchangeApplicationInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type ExchangeApplicationInvitation401ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response ExchangeApplicationInvitation401ApplicationProblemPlusJSONResponse) VisitExchangeApplicationInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(401) + _, err := buf.WriteTo(w) + return err +} + +type RedeemApplicationInvitationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *RedeemApplicationInvitationJSONRequestBody +} + +type RedeemApplicationInvitationResponseObject interface { + VisitRedeemApplicationInvitationResponse(w http.ResponseWriter) error +} + +type RedeemApplicationInvitation200JSONResponse TokenResponse + +func (response RedeemApplicationInvitation200JSONResponse) VisitRedeemApplicationInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type RedeemApplicationInvitation401ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response RedeemApplicationInvitation401ApplicationProblemPlusJSONResponse) VisitRedeemApplicationInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(401) + _, err := buf.WriteTo(w) + return err +} + +type LogoutCurrentSessionRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` +} + +type LogoutCurrentSessionResponseObject interface { + VisitLogoutCurrentSessionResponse(w http.ResponseWriter) error +} + +type LogoutCurrentSession204Response struct { +} + +func (response LogoutCurrentSession204Response) VisitLogoutCurrentSessionResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type AuthMethodsRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` +} + +type AuthMethodsResponseObject interface { + VisitAuthMethodsResponse(w http.ResponseWriter) error +} + +type AuthMethods200JSONResponse AuthMethods + +func (response AuthMethods200JSONResponse) VisitAuthMethodsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type VerifyMFARequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *VerifyMFAJSONRequestBody +} + +type VerifyMFAResponseObject interface { + VisitVerifyMFAResponse(w http.ResponseWriter) error +} + +type VerifyMFA200JSONResponse struct{ TokensJSONResponse } + +func (response VerifyMFA200JSONResponse) VisitVerifyMFAResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type VerifyMFA401ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response VerifyMFA401ApplicationProblemPlusJSONResponse) VisitVerifyMFAResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(401) + _, err := buf.WriteTo(w) + return err +} + +type BeginWebAuthnAuthenticationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *BeginWebAuthnAuthenticationJSONRequestBody +} + +type BeginWebAuthnAuthenticationResponseObject interface { + VisitBeginWebAuthnAuthenticationResponse(w http.ResponseWriter) error +} + +type BeginWebAuthnAuthentication201JSONResponse WebAuthnChallenge + +func (response BeginWebAuthnAuthentication201JSONResponse) VisitBeginWebAuthnAuthenticationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type FinishWebAuthnAuthenticationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *FinishWebAuthnAuthenticationJSONRequestBody +} + +type FinishWebAuthnAuthenticationResponseObject interface { + VisitFinishWebAuthnAuthenticationResponse(w http.ResponseWriter) error +} + +type FinishWebAuthnAuthentication200JSONResponse struct{ TokensJSONResponse } + +func (response FinishWebAuthnAuthentication200JSONResponse) VisitFinishWebAuthnAuthenticationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type FinishWebAuthnAuthentication401ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response FinishWebAuthnAuthentication401ApplicationProblemPlusJSONResponse) VisitFinishWebAuthnAuthenticationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(401) + _, err := buf.WriteTo(w) + return err } -type OwnershipTransferResultJSONResponse OwnershipTransferResult +type PasswordResetStartRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *PasswordResetStartJSONRequestBody +} -type PageJSONResponse Page +type PasswordResetStartResponseObject interface { + VisitPasswordResetStartResponse(w http.ResponseWriter) error +} -type ProblemApplicationProblemPlusJSONResponse Problem +type PasswordResetStart202JSONResponse ChallengeAccepted -type TokensJSONResponse TokenResponse +func (response PasswordResetStart202JSONResponse) VisitPasswordResetStartResponse(w http.ResponseWriter) error { -type HealthRequestObject struct { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) + _, err := buf.WriteTo(w) + return err } -type HealthResponseObject interface { - VisitHealthResponse(w http.ResponseWriter) error +type PasswordResetVerifyRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *PasswordResetVerifyJSONRequestBody } -type Health200Response struct { +type PasswordResetVerifyResponseObject interface { + VisitPasswordResetVerifyResponse(w http.ResponseWriter) error } -func (response Health200Response) VisitHealthResponse(w http.ResponseWriter) error { +type PasswordResetVerify200JSONResponse struct{ TokensJSONResponse } + +func (response PasswordResetVerify200JSONResponse) VisitPasswordResetVerifyResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type OidcDiscoveryRequestObject struct { +type PasswordSignInRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *PasswordSignInJSONRequestBody } -type OidcDiscoveryResponseObject interface { - VisitOidcDiscoveryResponse(w http.ResponseWriter) error +type PasswordSignInResponseObject interface { + VisitPasswordSignInResponse(w http.ResponseWriter) error } -type OidcDiscovery200Response struct { -} +type PasswordSignIn200JSONResponse struct{ TokensJSONResponse } + +func (response PasswordSignIn200JSONResponse) VisitPasswordSignInResponse(w http.ResponseWriter) error { -func (response OidcDiscovery200Response) VisitOidcDiscoveryResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type BeginOIDCAuthorizationRequestObject struct { - Params BeginOIDCAuthorizationParams +type PasswordSignIn401ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type BeginOIDCAuthorizationResponseObject interface { - VisitBeginOIDCAuthorizationResponse(w http.ResponseWriter) error +func (response PasswordSignIn401ApplicationProblemPlusJSONResponse) VisitPasswordSignInResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(401) + _, err := buf.WriteTo(w) + return err } -type BeginOIDCAuthorization200Response struct { +type PasswordSignUpRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *PasswordSignUpJSONRequestBody } -func (response BeginOIDCAuthorization200Response) VisitBeginOIDCAuthorizationResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil +type PasswordSignUpResponseObject interface { + VisitPasswordSignUpResponse(w http.ResponseWriter) error } -type BeginOIDCAuthorization302Response struct { +type PasswordSignUp200JSONResponse struct{ TokensJSONResponse } + +func (response PasswordSignUp200JSONResponse) VisitPasswordSignUpResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -func (response BeginOIDCAuthorization302Response) VisitBeginOIDCAuthorizationResponse(w http.ResponseWriter) error { - w.WriteHeader(302) - return nil +type PasswordSignUp403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type DecideOIDCAuthorizationRequestObject struct { - Body *DecideOIDCAuthorizationFormdataRequestBody +func (response PasswordSignUp403ApplicationProblemPlusJSONResponse) VisitPasswordSignUpResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type DecideOIDCAuthorizationResponseObject interface { - VisitDecideOIDCAuthorizationResponse(w http.ResponseWriter) error +type ListAuthProvidersRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` } -type DecideOIDCAuthorization200Response struct { +type ListAuthProvidersResponseObject interface { + VisitListAuthProvidersResponse(w http.ResponseWriter) error } -func (response DecideOIDCAuthorization200Response) VisitDecideOIDCAuthorizationResponse(w http.ResponseWriter) error { +type ListAuthProviders200JSONResponse AuthProviderPage + +func (response ListAuthProviders200JSONResponse) VisitListAuthProvidersResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type DecideOIDCAuthorization302Response struct { +type ExchangeAppleAuthRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *ExchangeAppleAuthJSONRequestBody } -func (response DecideOIDCAuthorization302Response) VisitDecideOIDCAuthorizationResponse(w http.ResponseWriter) error { - w.WriteHeader(302) - return nil +type ExchangeAppleAuthResponseObject interface { + VisitExchangeAppleAuthResponse(w http.ResponseWriter) error } -type IntrospectOIDCTokenRequestObject struct { - Body *IntrospectOIDCTokenFormdataRequestBody -} +type ExchangeAppleAuth200JSONResponse struct{ TokensJSONResponse } -type IntrospectOIDCTokenResponseObject interface { - VisitIntrospectOIDCTokenResponse(w http.ResponseWriter) error +func (response ExchangeAppleAuth200JSONResponse) VisitExchangeAppleAuthResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type IntrospectOIDCToken200Response struct { +type StartAppleAuthRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *StartAppleAuthJSONRequestBody } -func (response IntrospectOIDCToken200Response) VisitIntrospectOIDCTokenResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil +type StartAppleAuthResponseObject interface { + VisitStartAppleAuthResponse(w http.ResponseWriter) error } -type OidcJWKSRequestObject struct { +type StartAppleAuth201JSONResponse ExternalAuthStart + +func (response StartAppleAuth201JSONResponse) VisitStartAppleAuthResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err } -type OidcJWKSResponseObject interface { - VisitOidcJWKSResponse(w http.ResponseWriter) error +type ExchangeGoogleAuthRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *ExchangeGoogleAuthJSONRequestBody } -type OidcJWKS200Response struct { +type ExchangeGoogleAuthResponseObject interface { + VisitExchangeGoogleAuthResponse(w http.ResponseWriter) error } -func (response OidcJWKS200Response) VisitOidcJWKSResponse(w http.ResponseWriter) error { +type ExchangeGoogleAuth200JSONResponse struct{ TokensJSONResponse } + +func (response ExchangeGoogleAuth200JSONResponse) VisitExchangeGoogleAuthResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type RevokeOIDCTokenRequestObject struct { - Body *RevokeOIDCTokenFormdataRequestBody +type StartGoogleAuthRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *StartGoogleAuthJSONRequestBody } -type RevokeOIDCTokenResponseObject interface { - VisitRevokeOIDCTokenResponse(w http.ResponseWriter) error +type StartGoogleAuthResponseObject interface { + VisitStartGoogleAuthResponse(w http.ResponseWriter) error } -type RevokeOIDCToken200Response struct { -} +type StartGoogleAuth201JSONResponse ExternalAuthStart -func (response RevokeOIDCToken200Response) VisitRevokeOIDCTokenResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil -} +func (response StartGoogleAuth201JSONResponse) VisitStartGoogleAuthResponse(w http.ResponseWriter) error { -type ExchangeOIDCTokenRequestObject struct { - Body *ExchangeOIDCTokenFormdataRequestBody + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err } -type ExchangeOIDCTokenResponseObject interface { - VisitExchangeOIDCTokenResponse(w http.ResponseWriter) error +type RefreshRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *RefreshJSONRequestBody } -type ExchangeOIDCToken200Response struct { +type RefreshResponseObject interface { + VisitRefreshResponse(w http.ResponseWriter) error } -func (response ExchangeOIDCToken200Response) VisitExchangeOIDCTokenResponse(w http.ResponseWriter) error { +type Refresh200JSONResponse struct{ TokensJSONResponse } + +func (response Refresh200JSONResponse) VisitRefreshResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type ExchangeOIDCToken400Response struct { +type CreateCheckoutSessionRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Params CreateCheckoutSessionParams + Body *CreateCheckoutSessionJSONRequestBody } -func (response ExchangeOIDCToken400Response) VisitExchangeOIDCTokenResponse(w http.ResponseWriter) error { - w.WriteHeader(400) - return nil +type CreateCheckoutSessionResponseObject interface { + VisitCreateCheckoutSessionResponse(w http.ResponseWriter) error } -type OidcUserinfoRequestObject struct { +type CreateCheckoutSession201JSONResponse CheckoutSession + +func (response CreateCheckoutSession201JSONResponse) VisitCreateCheckoutSessionResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err } -type OidcUserinfoResponseObject interface { - VisitOidcUserinfoResponse(w http.ResponseWriter) error +type GetCheckoutSessionRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + SessionId SessionID `json:"session_id"` } -type OidcUserinfo200Response struct { +type GetCheckoutSessionResponseObject interface { + VisitGetCheckoutSessionResponse(w http.ResponseWriter) error } -func (response OidcUserinfo200Response) VisitOidcUserinfoResponse(w http.ResponseWriter) error { +type GetCheckoutSession200JSONResponse CheckoutSession + +func (response GetCheckoutSession200JSONResponse) VisitGetCheckoutSessionResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type OidcUserinfo401ApplicationProblemPlusJSONResponse struct { - ProblemApplicationProblemPlusJSONResponse +type CreateBillingPortalSessionRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Params CreateBillingPortalSessionParams + Body *CreateBillingPortalSessionJSONRequestBody } -func (response OidcUserinfo401ApplicationProblemPlusJSONResponse) VisitOidcUserinfoResponse(w http.ResponseWriter) error { +type CreateBillingPortalSessionResponseObject interface { + VisitCreateBillingPortalSessionResponse(w http.ResponseWriter) error +} + +type CreateBillingPortalSession201JSONResponse PortalSession + +func (response CreateBillingPortalSession201JSONResponse) VisitCreateBillingPortalSessionResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(401) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type StripeWebhookRequestObject struct { - ConnectionPublicId string `json:"connection_public_id"` - Params StripeWebhookParams - Body *StripeWebhookJSONRequestBody +type PublicCatalogRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` } -type StripeWebhookResponseObject interface { - VisitStripeWebhookResponse(w http.ResponseWriter) error +type PublicCatalogResponseObject interface { + VisitPublicCatalogResponse(w http.ResponseWriter) error } -type StripeWebhook200Response struct { -} +type PublicCatalog200JSONResponse ProductPage -func (response StripeWebhook200Response) VisitStripeWebhookResponse(w http.ResponseWriter) error { +func (response PublicCatalog200JSONResponse) VisitPublicCatalogResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type StripeWebhook400ApplicationProblemPlusJSONResponse struct { - ProblemApplicationProblemPlusJSONResponse +type ExchangeDelegationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + DelegationId UUID `json:"delegation_id"` + Body *ExchangeDelegationJSONRequestBody } -func (response StripeWebhook400ApplicationProblemPlusJSONResponse) VisitStripeWebhookResponse(w http.ResponseWriter) error { +type ExchangeDelegationResponseObject interface { + VisitExchangeDelegationResponse(w http.ResponseWriter) error +} + +type ExchangeDelegation200JSONResponse TokenResponse + +func (response ExchangeDelegation200JSONResponse) VisitExchangeDelegationResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(400) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) _, err := buf.WriteTo(w) return err } -type ReadinessRequestObject struct { +type PublishCustomEventRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Params PublishCustomEventParams + Body *PublishCustomEventJSONRequestBody } -type ReadinessResponseObject interface { - VisitReadinessResponse(w http.ResponseWriter) error +type PublishCustomEventResponseObject interface { + VisitPublishCustomEventResponse(w http.ResponseWriter) error } -type Readiness200Response struct { -} +type PublishCustomEvent202JSONResponse EventEnvelope -func (response Readiness200Response) VisitReadinessResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil +func (response PublishCustomEvent202JSONResponse) VisitPublishCustomEventResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) + _, err := buf.WriteTo(w) + return err } -type Readiness503ApplicationProblemPlusJSONResponse struct { +type PublishCustomEvent403ApplicationProblemPlusJSONResponse struct { ProblemApplicationProblemPlusJSONResponse } -func (response Readiness503ApplicationProblemPlusJSONResponse) VisitReadinessResponse(w http.ResponseWriter) error { +func (response PublishCustomEvent403ApplicationProblemPlusJSONResponse) VisitPublishCustomEventResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(503) + w.WriteHeader(403) _, err := buf.WriteTo(w) return err } -type EmailStartRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - Body *EmailStartJSONRequestBody +type PublishCustomEvent422ApplicationProblemPlusJSONResponse Problem + +func (response PublishCustomEvent422ApplicationProblemPlusJSONResponse) VisitPublishCustomEventResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(422) + _, err := buf.WriteTo(w) + return err } -type EmailStartResponseObject interface { - VisitEmailStartResponse(w http.ResponseWriter) error +type ListApplicationInvitationsRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` } -type EmailStart202Response struct { +type ListApplicationInvitationsResponseObject interface { + VisitListApplicationInvitationsResponse(w http.ResponseWriter) error } -func (response EmailStart202Response) VisitEmailStartResponse(w http.ResponseWriter) error { - w.WriteHeader(202) - return nil +type ListApplicationInvitations200JSONResponse ApplicationInvitationPage + +func (response ListApplicationInvitations200JSONResponse) VisitListApplicationInvitationsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type EmailVerifyRequestObject struct { +type CreateApplicationInvitationMachineRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *EmailVerifyJSONRequestBody + Body *CreateApplicationInvitationMachineJSONRequestBody } -type EmailVerifyResponseObject interface { - VisitEmailVerifyResponse(w http.ResponseWriter) error +type CreateApplicationInvitationMachineResponseObject interface { + VisitCreateApplicationInvitationMachineResponse(w http.ResponseWriter) error } -type EmailVerify200JSONResponse struct{ TokensJSONResponse } +type CreateApplicationInvitationMachine201JSONResponse ApplicationInvitation -func (response EmailVerify200JSONResponse) VisitEmailVerifyResponse(w http.ResponseWriter) error { +func (response CreateApplicationInvitationMachine201JSONResponse) VisitCreateApplicationInvitationMachineResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type LogoutCurrentSessionRequestObject struct { +type RevokeApplicationInvitationRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + InvitationId UUID `json:"invitation_id"` } -type LogoutCurrentSessionResponseObject interface { - VisitLogoutCurrentSessionResponse(w http.ResponseWriter) error +type RevokeApplicationInvitationResponseObject interface { + VisitRevokeApplicationInvitationResponse(w http.ResponseWriter) error } -type LogoutCurrentSession204Response struct { +type RevokeApplicationInvitation204Response struct { } -func (response LogoutCurrentSession204Response) VisitLogoutCurrentSessionResponse(w http.ResponseWriter) error { +func (response RevokeApplicationInvitation204Response) VisitRevokeApplicationInvitationResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type AuthMethodsRequestObject struct { +type GetApplicationInvitationRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *AuthMethodsJSONRequestBody + InvitationId UUID `json:"invitation_id"` } -type AuthMethodsResponseObject interface { - VisitAuthMethodsResponse(w http.ResponseWriter) error +type GetApplicationInvitationResponseObject interface { + VisitGetApplicationInvitationResponse(w http.ResponseWriter) error } -type AuthMethods200Response struct { -} +type GetApplicationInvitation200JSONResponse ApplicationInvitation -func (response AuthMethods200Response) VisitAuthMethodsResponse(w http.ResponseWriter) error { +func (response GetApplicationInvitation200JSONResponse) VisitGetApplicationInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type VerifyMFARequestObject struct { +type ResendApplicationInvitationRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *VerifyMFAJSONRequestBody + InvitationId UUID `json:"invitation_id"` } -type VerifyMFAResponseObject interface { - VisitVerifyMFAResponse(w http.ResponseWriter) error +type ResendApplicationInvitationResponseObject interface { + VisitResendApplicationInvitationResponse(w http.ResponseWriter) error } -type VerifyMFA200JSONResponse struct{ TokensJSONResponse } +type ResendApplicationInvitation202JSONResponse InvitationResent -func (response VerifyMFA200JSONResponse) VisitVerifyMFAResponse(w http.ResponseWriter) error { +func (response ResendApplicationInvitation202JSONResponse) VisitResendApplicationInvitationResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(202) _, err := buf.WriteTo(w) return err } -type VerifyMFA401ApplicationProblemPlusJSONResponse struct { +type ResendApplicationInvitation429ApplicationProblemPlusJSONResponse struct { ProblemApplicationProblemPlusJSONResponse } -func (response VerifyMFA401ApplicationProblemPlusJSONResponse) VisitVerifyMFAResponse(w http.ResponseWriter) error { +func (response ResendApplicationInvitation429ApplicationProblemPlusJSONResponse) VisitResendApplicationInvitationResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(401) + w.WriteHeader(429) _, err := buf.WriteTo(w) return err } -type BeginWebAuthnAuthenticationRequestObject struct { +type LocalEntitlementCheckoutRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *BeginWebAuthnAuthenticationJSONRequestBody + Params LocalEntitlementCheckoutParams + Body *LocalEntitlementCheckoutJSONRequestBody } -type BeginWebAuthnAuthenticationResponseObject interface { - VisitBeginWebAuthnAuthenticationResponse(w http.ResponseWriter) error +type LocalEntitlementCheckoutResponseObject interface { + VisitLocalEntitlementCheckoutResponse(w http.ResponseWriter) error } -type BeginWebAuthnAuthentication201Response struct { -} +type LocalEntitlementCheckout201JSONResponse LocalEntitlementRequest + +func (response LocalEntitlementCheckout201JSONResponse) VisitLocalEntitlementCheckoutResponse(w http.ResponseWriter) error { -func (response BeginWebAuthnAuthentication201Response) VisitBeginWebAuthnAuthenticationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type DeleteMyAccountRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` +} + +type DeleteMyAccountResponseObject interface { + VisitDeleteMyAccountResponse(w http.ResponseWriter) error +} + +type DeleteMyAccount204Response struct { +} + +func (response DeleteMyAccount204Response) VisitDeleteMyAccountResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type FinishWebAuthnAuthenticationRequestObject struct { +type GetCurrentUserRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *FinishWebAuthnAuthenticationJSONRequestBody } -type FinishWebAuthnAuthenticationResponseObject interface { - VisitFinishWebAuthnAuthenticationResponse(w http.ResponseWriter) error +type GetCurrentUserResponseObject interface { + VisitGetCurrentUserResponse(w http.ResponseWriter) error +} + +type GetCurrentUser200JSONResponse User + +func (response GetCurrentUser200JSONResponse) VisitGetCurrentUserResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type UpdateCurrentUserRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *UpdateCurrentUserJSONRequestBody +} + +type UpdateCurrentUserResponseObject interface { + VisitUpdateCurrentUserResponse(w http.ResponseWriter) error +} + +type UpdateCurrentUser204Response struct { +} + +func (response UpdateCurrentUser204Response) VisitUpdateCurrentUserResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type ListMyAddressesRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` +} + +type ListMyAddressesResponseObject interface { + VisitListMyAddressesResponse(w http.ResponseWriter) error } -type FinishWebAuthnAuthentication200JSONResponse struct{ TokensJSONResponse } +type ListMyAddresses200JSONResponse AddressPage -func (response FinishWebAuthnAuthentication200JSONResponse) VisitFinishWebAuthnAuthenticationResponse(w http.ResponseWriter) error { +func (response ListMyAddresses200JSONResponse) VisitListMyAddressesResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -22997,113 +29019,108 @@ func (response FinishWebAuthnAuthentication200JSONResponse) VisitFinishWebAuthnA return err } -type FinishWebAuthnAuthentication401ApplicationProblemPlusJSONResponse struct { - ProblemApplicationProblemPlusJSONResponse +type CreateMyAddressRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *CreateMyAddressJSONRequestBody } -func (response FinishWebAuthnAuthentication401ApplicationProblemPlusJSONResponse) VisitFinishWebAuthnAuthenticationResponse(w http.ResponseWriter) error { +type CreateMyAddressResponseObject interface { + VisitCreateMyAddressResponse(w http.ResponseWriter) error +} + +type CreateMyAddress201JSONResponse Address + +func (response CreateMyAddress201JSONResponse) VisitCreateMyAddressResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(401) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type PasswordResetStartRequestObject struct { +type DeleteMyAddressRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *PasswordResetStartJSONRequestBody + AddressId UUID `json:"address_id"` } -type PasswordResetStartResponseObject interface { - VisitPasswordResetStartResponse(w http.ResponseWriter) error +type DeleteMyAddressResponseObject interface { + VisitDeleteMyAddressResponse(w http.ResponseWriter) error } -type PasswordResetStart202Response struct { +type DeleteMyAddress204Response struct { } -func (response PasswordResetStart202Response) VisitPasswordResetStartResponse(w http.ResponseWriter) error { - w.WriteHeader(202) +func (response DeleteMyAddress204Response) VisitDeleteMyAddressResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type PasswordResetVerifyRequestObject struct { +type UpdateMyAddressRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *PasswordResetVerifyJSONRequestBody + AddressId UUID `json:"address_id"` + Body *UpdateMyAddressJSONRequestBody } -type PasswordResetVerifyResponseObject interface { - VisitPasswordResetVerifyResponse(w http.ResponseWriter) error +type UpdateMyAddressResponseObject interface { + VisitUpdateMyAddressResponse(w http.ResponseWriter) error } -type PasswordResetVerify200JSONResponse struct{ TokensJSONResponse } - -func (response PasswordResetVerify200JSONResponse) VisitPasswordResetVerifyResponse(w http.ResponseWriter) error { +type UpdateMyAddress204Response struct { +} - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(response); err != nil { - return err - } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - _, err := buf.WriteTo(w) - return err +func (response UpdateMyAddress204Response) VisitUpdateMyAddressResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil } -type PasswordSignInRequestObject struct { +type ActivateMyAddressRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *PasswordSignInJSONRequestBody + AddressId UUID `json:"address_id"` } -type PasswordSignInResponseObject interface { - VisitPasswordSignInResponse(w http.ResponseWriter) error +type ActivateMyAddressResponseObject interface { + VisitActivateMyAddressResponse(w http.ResponseWriter) error } -type PasswordSignIn200JSONResponse struct{ TokensJSONResponse } +type ActivateMyAddress204Response struct { +} -func (response PasswordSignIn200JSONResponse) VisitPasswordSignInResponse(w http.ResponseWriter) error { +func (response ActivateMyAddress204Response) VisitActivateMyAddressResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(response); err != nil { - return err - } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - _, err := buf.WriteTo(w) - return err +type AnonymizeMyAccountRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` } -type PasswordSignIn401ApplicationProblemPlusJSONResponse struct { - ProblemApplicationProblemPlusJSONResponse +type AnonymizeMyAccountResponseObject interface { + VisitAnonymizeMyAccountResponse(w http.ResponseWriter) error } -func (response PasswordSignIn401ApplicationProblemPlusJSONResponse) VisitPasswordSignInResponse(w http.ResponseWriter) error { +type AnonymizeMyAccount204Response struct { +} - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(response); err != nil { - return err - } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(401) - _, err := buf.WriteTo(w) - return err +func (response AnonymizeMyAccount204Response) VisitAnonymizeMyAccountResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil } -type PasswordSignUpRequestObject struct { +type ListPersonalAPIKeysRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *PasswordSignUpJSONRequestBody } -type PasswordSignUpResponseObject interface { - VisitPasswordSignUpResponse(w http.ResponseWriter) error +type ListPersonalAPIKeysResponseObject interface { + VisitListPersonalAPIKeysResponse(w http.ResponseWriter) error } -type PasswordSignUp200JSONResponse struct{ TokensJSONResponse } +type ListPersonalAPIKeys200JSONResponse PersonalAPIKeyPage -func (response PasswordSignUp200JSONResponse) VisitPasswordSignUpResponse(w http.ResponseWriter) error { +func (response ListPersonalAPIKeys200JSONResponse) VisitListPersonalAPIKeysResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23115,11 +29132,11 @@ func (response PasswordSignUp200JSONResponse) VisitPasswordSignUpResponse(w http return err } -type PasswordSignUp403ApplicationProblemPlusJSONResponse struct { +type ListPersonalAPIKeys403ApplicationProblemPlusJSONResponse struct { ProblemApplicationProblemPlusJSONResponse } -func (response PasswordSignUp403ApplicationProblemPlusJSONResponse) VisitPasswordSignUpResponse(w http.ResponseWriter) error { +func (response ListPersonalAPIKeys403ApplicationProblemPlusJSONResponse) VisitListPersonalAPIKeysResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23131,57 +29148,57 @@ func (response PasswordSignUp403ApplicationProblemPlusJSONResponse) VisitPasswor return err } -type ListAuthProvidersRequestObject struct { +type CreatePersonalAPIKeyRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + Body *CreatePersonalAPIKeyJSONRequestBody } -type ListAuthProvidersResponseObject interface { - VisitListAuthProvidersResponse(w http.ResponseWriter) error +type CreatePersonalAPIKeyResponseObject interface { + VisitCreatePersonalAPIKeyResponse(w http.ResponseWriter) error } -type ListAuthProviders200JSONResponse struct{ PageJSONResponse } +type CreatePersonalAPIKey201JSONResponse PersonalAPIKeyCreated -func (response ListAuthProviders200JSONResponse) VisitListAuthProvidersResponse(w http.ResponseWriter) error { +func (response CreatePersonalAPIKey201JSONResponse) VisitCreatePersonalAPIKeyResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type AppleAuthCallbackRequestObject struct { +type RevokePersonalAPIKeyRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *AppleAuthCallbackFormdataRequestBody + KeyId UUID `json:"key_id"` } -type AppleAuthCallbackResponseObject interface { - VisitAppleAuthCallbackResponse(w http.ResponseWriter) error +type RevokePersonalAPIKeyResponseObject interface { + VisitRevokePersonalAPIKeyResponse(w http.ResponseWriter) error } -type AppleAuthCallback302Response struct { +type RevokePersonalAPIKey204Response struct { } -func (response AppleAuthCallback302Response) VisitAppleAuthCallbackResponse(w http.ResponseWriter) error { - w.WriteHeader(302) +func (response RevokePersonalAPIKey204Response) VisitRevokePersonalAPIKeyResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type ExchangeAppleAuthRequestObject struct { +type ListMyIdentitiesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *ExchangeAppleAuthJSONRequestBody } -type ExchangeAppleAuthResponseObject interface { - VisitExchangeAppleAuthResponse(w http.ResponseWriter) error +type ListMyIdentitiesResponseObject interface { + VisitListMyIdentitiesResponse(w http.ResponseWriter) error } -type ExchangeAppleAuth200JSONResponse struct{ TokensJSONResponse } +type ListMyIdentities200JSONResponse ExternalIdentityPage -func (response ExchangeAppleAuth200JSONResponse) VisitExchangeAppleAuthResponse(w http.ResponseWriter) error { +func (response ListMyIdentities200JSONResponse) VisitListMyIdentitiesResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23193,91 +29210,102 @@ func (response ExchangeAppleAuth200JSONResponse) VisitExchangeAppleAuthResponse( return err } -type StartAppleAuthRequestObject struct { +type UnlinkMyIdentityRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *StartAppleAuthJSONRequestBody + IdentityId UUID `json:"identity_id"` } -type StartAppleAuthResponseObject interface { - VisitStartAppleAuthResponse(w http.ResponseWriter) error +type UnlinkMyIdentityResponseObject interface { + VisitUnlinkMyIdentityResponse(w http.ResponseWriter) error } -type StartAppleAuth201Response struct { +type UnlinkMyIdentity204Response struct { } -func (response StartAppleAuth201Response) VisitStartAppleAuthResponse(w http.ResponseWriter) error { - w.WriteHeader(201) +func (response UnlinkMyIdentity204Response) VisitUnlinkMyIdentityResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type GoogleAuthCallbackRequestObject struct { +type StartAppleLinkRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + Body *StartAppleLinkJSONRequestBody } -type GoogleAuthCallbackResponseObject interface { - VisitGoogleAuthCallbackResponse(w http.ResponseWriter) error +type StartAppleLinkResponseObject interface { + VisitStartAppleLinkResponse(w http.ResponseWriter) error } -type GoogleAuthCallback302Response struct { -} +type StartAppleLink201JSONResponse ExternalAuthStart -func (response GoogleAuthCallback302Response) VisitGoogleAuthCallbackResponse(w http.ResponseWriter) error { - w.WriteHeader(302) - return nil +func (response StartAppleLink201JSONResponse) VisitStartAppleLinkResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err } -type ExchangeGoogleAuthRequestObject struct { +type StartGoogleLinkRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *ExchangeGoogleAuthJSONRequestBody + Body *StartGoogleLinkJSONRequestBody } -type ExchangeGoogleAuthResponseObject interface { - VisitExchangeGoogleAuthResponse(w http.ResponseWriter) error +type StartGoogleLinkResponseObject interface { + VisitStartGoogleLinkResponse(w http.ResponseWriter) error } -type ExchangeGoogleAuth200JSONResponse struct{ TokensJSONResponse } +type StartGoogleLink201JSONResponse ExternalAuthStart -func (response ExchangeGoogleAuth200JSONResponse) VisitExchangeGoogleAuthResponse(w http.ResponseWriter) error { +func (response StartGoogleLink201JSONResponse) VisitStartGoogleLinkResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type StartGoogleAuthRequestObject struct { +type GetMyBillingSummaryRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *StartGoogleAuthJSONRequestBody } -type StartGoogleAuthResponseObject interface { - VisitStartGoogleAuthResponse(w http.ResponseWriter) error +type GetMyBillingSummaryResponseObject interface { + VisitGetMyBillingSummaryResponse(w http.ResponseWriter) error } -type StartGoogleAuth201Response struct { -} +type GetMyBillingSummary200JSONResponse BillingSummary -func (response StartGoogleAuth201Response) VisitStartGoogleAuthResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil +func (response GetMyBillingSummary200JSONResponse) VisitGetMyBillingSummaryResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type RefreshRequestObject struct { +type GetMyBillingProfileRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *RefreshJSONRequestBody } -type RefreshResponseObject interface { - VisitRefreshResponse(w http.ResponseWriter) error +type GetMyBillingProfileResponseObject interface { + VisitGetMyBillingProfileResponse(w http.ResponseWriter) error } -type Refresh200JSONResponse struct{ TokensJSONResponse } +type GetMyBillingProfile200JSONResponse BillingProfile -func (response Refresh200JSONResponse) VisitRefreshResponse(w http.ResponseWriter) error { +func (response GetMyBillingProfile200JSONResponse) VisitGetMyBillingProfileResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23289,198 +29317,180 @@ func (response Refresh200JSONResponse) VisitRefreshResponse(w http.ResponseWrite return err } -type CreateCheckoutSessionRequestObject struct { +type UpdateMyBillingProfileRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params CreateCheckoutSessionParams - Body *CreateCheckoutSessionJSONRequestBody + Body *UpdateMyBillingProfileJSONRequestBody } -type CreateCheckoutSessionResponseObject interface { - VisitCreateCheckoutSessionResponse(w http.ResponseWriter) error +type UpdateMyBillingProfileResponseObject interface { + VisitUpdateMyBillingProfileResponse(w http.ResponseWriter) error } -type CreateCheckoutSession201Response struct { +type UpdateMyBillingProfile204Response struct { } -func (response CreateCheckoutSession201Response) VisitCreateCheckoutSessionResponse(w http.ResponseWriter) error { - w.WriteHeader(201) +func (response UpdateMyBillingProfile204Response) VisitUpdateMyBillingProfileResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type GetCheckoutSessionRequestObject struct { +type EmailChangeStartRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - SessionId SessionID `json:"session_id"` + Body *EmailChangeStartJSONRequestBody } -type GetCheckoutSessionResponseObject interface { - VisitGetCheckoutSessionResponse(w http.ResponseWriter) error +type EmailChangeStartResponseObject interface { + VisitEmailChangeStartResponse(w http.ResponseWriter) error } -type GetCheckoutSession200Response struct { -} +type EmailChangeStart202JSONResponse ChallengeAccepted -func (response GetCheckoutSession200Response) VisitGetCheckoutSessionResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil +func (response EmailChangeStart202JSONResponse) VisitEmailChangeStartResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) + _, err := buf.WriteTo(w) + return err } -type CreateBillingPortalSessionRequestObject struct { +type EmailChangeVerifyRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params CreateBillingPortalSessionParams - Body *CreateBillingPortalSessionJSONRequestBody + Body *EmailChangeVerifyJSONRequestBody } -type CreateBillingPortalSessionResponseObject interface { - VisitCreateBillingPortalSessionResponse(w http.ResponseWriter) error +type EmailChangeVerifyResponseObject interface { + VisitEmailChangeVerifyResponse(w http.ResponseWriter) error } -type CreateBillingPortalSession201Response struct { +type EmailChangeVerify204Response struct { } -func (response CreateBillingPortalSession201Response) VisitCreateBillingPortalSessionResponse(w http.ResponseWriter) error { - w.WriteHeader(201) +func (response EmailChangeVerify204Response) VisitEmailChangeVerifyResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type PublicCatalogRequestObject struct { +type EmailVerificationStartRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type PublicCatalogResponseObject interface { - VisitPublicCatalogResponse(w http.ResponseWriter) error +type EmailVerificationStartResponseObject interface { + VisitEmailVerificationStartResponse(w http.ResponseWriter) error } -type PublicCatalog200JSONResponse struct{ PageJSONResponse } +type EmailVerificationStart202JSONResponse ChallengeAccepted -func (response PublicCatalog200JSONResponse) VisitPublicCatalogResponse(w http.ResponseWriter) error { +func (response EmailVerificationStart202JSONResponse) VisitEmailVerificationStartResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(202) _, err := buf.WriteTo(w) return err } -type ExchangeDelegationRequestObject struct { +type EmailVerificationVerifyRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - DelegationId UUID `json:"delegation_id"` - Body *ExchangeDelegationJSONRequestBody + Body *EmailVerificationVerifyJSONRequestBody } -type ExchangeDelegationResponseObject interface { - VisitExchangeDelegationResponse(w http.ResponseWriter) error +type EmailVerificationVerifyResponseObject interface { + VisitEmailVerificationVerifyResponse(w http.ResponseWriter) error } -type ExchangeDelegation200Response struct { +type EmailVerificationVerify204Response struct { } -func (response ExchangeDelegation200Response) VisitExchangeDelegationResponse(w http.ResponseWriter) error { - w.WriteHeader(200) +func (response EmailVerificationVerify204Response) VisitEmailVerificationVerifyResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type PublishCustomEventRequestObject struct { +type ListMyEntitlementsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params PublishCustomEventParams - Body *PublishCustomEventJSONRequestBody + Params ListMyEntitlementsParams } -type PublishCustomEventResponseObject interface { - VisitPublishCustomEventResponse(w http.ResponseWriter) error +type ListMyEntitlementsResponseObject interface { + VisitListMyEntitlementsResponse(w http.ResponseWriter) error } -type PublishCustomEvent202JSONResponse EventEnvelope +type ListMyEntitlements200JSONResponse EffectiveEntitlements -func (response PublishCustomEvent202JSONResponse) VisitPublishCustomEventResponse(w http.ResponseWriter) error { +func (response ListMyEntitlements200JSONResponse) VisitListMyEntitlementsResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(202) + w.WriteHeader(200) _, err := buf.WriteTo(w) return err } -type PublishCustomEvent403ApplicationProblemPlusJSONResponse struct { - ProblemApplicationProblemPlusJSONResponse +type ExportMyAccountRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` } -func (response PublishCustomEvent403ApplicationProblemPlusJSONResponse) VisitPublishCustomEventResponse(w http.ResponseWriter) error { - - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(response); err != nil { - return err - } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(403) - _, err := buf.WriteTo(w) - return err +type ExportMyAccountResponseObject interface { + VisitExportMyAccountResponse(w http.ResponseWriter) error } -type PublishCustomEvent422ApplicationProblemPlusJSONResponse Problem +type ExportMyAccount200JSONResponse AccountExport -func (response PublishCustomEvent422ApplicationProblemPlusJSONResponse) VisitPublishCustomEventResponse(w http.ResponseWriter) error { +func (response ExportMyAccount200JSONResponse) VisitExportMyAccountResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(422) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) _, err := buf.WriteTo(w) return err } -type LocalEntitlementCheckoutRequestObject struct { +type ListMyInvoicesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params LocalEntitlementCheckoutParams - Body *LocalEntitlementCheckoutJSONRequestBody -} - -type LocalEntitlementCheckoutResponseObject interface { - VisitLocalEntitlementCheckoutResponse(w http.ResponseWriter) error -} - -type LocalEntitlementCheckout201Response struct { -} - -func (response LocalEntitlementCheckout201Response) VisitLocalEntitlementCheckoutResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil } -type DeleteMyAccountRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` +type ListMyInvoicesResponseObject interface { + VisitListMyInvoicesResponse(w http.ResponseWriter) error } -type DeleteMyAccountResponseObject interface { - VisitDeleteMyAccountResponse(w http.ResponseWriter) error -} +type ListMyInvoices200JSONResponse InvoicePage -type DeleteMyAccount204Response struct { -} +func (response ListMyInvoices200JSONResponse) VisitListMyInvoicesResponse(w http.ResponseWriter) error { -func (response DeleteMyAccount204Response) VisitDeleteMyAccountResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type GetCurrentUserRequestObject struct { +type ListMyLocalEntitlementRequestsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type GetCurrentUserResponseObject interface { - VisitGetCurrentUserResponse(w http.ResponseWriter) error +type ListMyLocalEntitlementRequestsResponseObject interface { + VisitListMyLocalEntitlementRequestsResponse(w http.ResponseWriter) error } -type GetCurrentUser200JSONResponse User +type ListMyLocalEntitlementRequests200JSONResponse LocalEntitlementRequestPage -func (response GetCurrentUser200JSONResponse) VisitGetCurrentUserResponse(w http.ResponseWriter) error { +func (response ListMyLocalEntitlementRequests200JSONResponse) VisitListMyLocalEntitlementRequestsResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23492,34 +29502,18 @@ func (response GetCurrentUser200JSONResponse) VisitGetCurrentUserResponse(w http return err } -type UpdateCurrentUserRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - Body *UpdateCurrentUserJSONRequestBody -} - -type UpdateCurrentUserResponseObject interface { - VisitUpdateCurrentUserResponse(w http.ResponseWriter) error -} - -type UpdateCurrentUser204Response struct { -} - -func (response UpdateCurrentUser204Response) VisitUpdateCurrentUserResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil -} - -type ListMyAddressesRequestObject struct { +type GetMyLocalEntitlementRequestRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + RequestId RequestID `json:"request_id"` } -type ListMyAddressesResponseObject interface { - VisitListMyAddressesResponse(w http.ResponseWriter) error +type GetMyLocalEntitlementRequestResponseObject interface { + VisitGetMyLocalEntitlementRequestResponse(w http.ResponseWriter) error } -type ListMyAddresses200JSONResponse struct{ PageJSONResponse } +type GetMyLocalEntitlementRequest200JSONResponse LocalEntitlementRequest -func (response ListMyAddresses200JSONResponse) VisitListMyAddressesResponse(w http.ResponseWriter) error { +func (response GetMyLocalEntitlementRequest200JSONResponse) VisitGetMyLocalEntitlementRequestResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23531,174 +29525,204 @@ func (response ListMyAddresses200JSONResponse) VisitListMyAddressesResponse(w ht return err } -type CreateMyAddressRequestObject struct { +type CancelMyLocalEntitlementRequestRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *CreateMyAddressJSONRequestBody + RequestId RequestID `json:"request_id"` } -type CreateMyAddressResponseObject interface { - VisitCreateMyAddressResponse(w http.ResponseWriter) error +type CancelMyLocalEntitlementRequestResponseObject interface { + VisitCancelMyLocalEntitlementRequestResponse(w http.ResponseWriter) error } -type CreateMyAddress201Response struct { +type CancelMyLocalEntitlementRequest204Response struct { } -func (response CreateMyAddress201Response) VisitCreateMyAddressResponse(w http.ResponseWriter) error { - w.WriteHeader(201) +func (response CancelMyLocalEntitlementRequest204Response) VisitCancelMyLocalEntitlementRequestResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type DeleteMyAddressRequestObject struct { +type LogoutAllRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - AddressId UUID `json:"address_id"` } -type DeleteMyAddressResponseObject interface { - VisitDeleteMyAddressResponse(w http.ResponseWriter) error +type LogoutAllResponseObject interface { + VisitLogoutAllResponse(w http.ResponseWriter) error } -type DeleteMyAddress204Response struct { +type LogoutAll204Response struct { } -func (response DeleteMyAddress204Response) VisitDeleteMyAddressResponse(w http.ResponseWriter) error { +func (response LogoutAll204Response) VisitLogoutAllResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type UpdateMyAddressRequestObject struct { +type ListMyMFAMethodsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - AddressId UUID `json:"address_id"` - Body *UpdateMyAddressJSONRequestBody } -type UpdateMyAddressResponseObject interface { - VisitUpdateMyAddressResponse(w http.ResponseWriter) error +type ListMyMFAMethodsResponseObject interface { + VisitListMyMFAMethodsResponse(w http.ResponseWriter) error } -type UpdateMyAddress204Response struct { -} +type ListMyMFAMethods200JSONResponse MFAMethodPage -func (response UpdateMyAddress204Response) VisitUpdateMyAddressResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response ListMyMFAMethods200JSONResponse) VisitListMyMFAMethodsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type ActivateMyAddressRequestObject struct { +type DisableMFAMethodRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - AddressId UUID `json:"address_id"` + MethodId UUID `json:"method_id"` } -type ActivateMyAddressResponseObject interface { - VisitActivateMyAddressResponse(w http.ResponseWriter) error +type DisableMFAMethodResponseObject interface { + VisitDisableMFAMethodResponse(w http.ResponseWriter) error } -type ActivateMyAddress204Response struct { +type DisableMFAMethod204Response struct { } -func (response ActivateMyAddress204Response) VisitActivateMyAddressResponse(w http.ResponseWriter) error { +func (response DisableMFAMethod204Response) VisitDisableMFAMethodResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type AnonymizeMyAccountRequestObject struct { +type RegenerateRecoveryCodesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type AnonymizeMyAccountResponseObject interface { - VisitAnonymizeMyAccountResponse(w http.ResponseWriter) error +type RegenerateRecoveryCodesResponseObject interface { + VisitRegenerateRecoveryCodesResponse(w http.ResponseWriter) error } -type AnonymizeMyAccount204Response struct { -} +type RegenerateRecoveryCodes200JSONResponse RecoveryCodes -func (response AnonymizeMyAccount204Response) VisitAnonymizeMyAccountResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response RegenerateRecoveryCodes200JSONResponse) VisitRegenerateRecoveryCodesResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type ListPersonalAPIKeysRequestObject struct { +type StartTOTPEnrollmentRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + Body *StartTOTPEnrollmentJSONRequestBody } -type ListPersonalAPIKeysResponseObject interface { - VisitListPersonalAPIKeysResponse(w http.ResponseWriter) error +type StartTOTPEnrollmentResponseObject interface { + VisitStartTOTPEnrollmentResponse(w http.ResponseWriter) error } -type ListPersonalAPIKeys200JSONResponse struct{ PageJSONResponse } +type StartTOTPEnrollment201JSONResponse MFAEnrollment -func (response ListPersonalAPIKeys200JSONResponse) VisitListPersonalAPIKeysResponse(w http.ResponseWriter) error { +func (response StartTOTPEnrollment201JSONResponse) VisitStartTOTPEnrollmentResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type ListPersonalAPIKeys403ApplicationProblemPlusJSONResponse struct { - ProblemApplicationProblemPlusJSONResponse +type ActivateTOTPEnrollmentRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + MethodId UUID `json:"method_id"` + Body *ActivateTOTPEnrollmentJSONRequestBody } -func (response ListPersonalAPIKeys403ApplicationProblemPlusJSONResponse) VisitListPersonalAPIKeysResponse(w http.ResponseWriter) error { +type ActivateTOTPEnrollmentResponseObject interface { + VisitActivateTOTPEnrollmentResponse(w http.ResponseWriter) error +} + +type ActivateTOTPEnrollment200JSONResponse MFAActivation + +func (response ActivateTOTPEnrollment200JSONResponse) VisitActivateTOTPEnrollmentResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(403) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) _, err := buf.WriteTo(w) return err } -type CreatePersonalAPIKeyRequestObject struct { +type BeginWebAuthnRegistrationRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *CreatePersonalAPIKeyJSONRequestBody + Body *BeginWebAuthnRegistrationJSONRequestBody } -type CreatePersonalAPIKeyResponseObject interface { - VisitCreatePersonalAPIKeyResponse(w http.ResponseWriter) error +type BeginWebAuthnRegistrationResponseObject interface { + VisitBeginWebAuthnRegistrationResponse(w http.ResponseWriter) error } -type CreatePersonalAPIKey201Response struct { -} +type BeginWebAuthnRegistration201JSONResponse WebAuthnChallenge -func (response CreatePersonalAPIKey201Response) VisitCreatePersonalAPIKeyResponse(w http.ResponseWriter) error { +func (response BeginWebAuthnRegistration201JSONResponse) VisitBeginWebAuthnRegistrationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } -type RevokePersonalAPIKeyRequestObject struct { +type FinishWebAuthnRegistrationRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - KeyId UUID `json:"key_id"` + Body *FinishWebAuthnRegistrationJSONRequestBody } -type RevokePersonalAPIKeyResponseObject interface { - VisitRevokePersonalAPIKeyResponse(w http.ResponseWriter) error +type FinishWebAuthnRegistrationResponseObject interface { + VisitFinishWebAuthnRegistrationResponse(w http.ResponseWriter) error } -type RevokePersonalAPIKey204Response struct { -} +type FinishWebAuthnRegistration200JSONResponse MFAActivation -func (response RevokePersonalAPIKey204Response) VisitRevokePersonalAPIKeyResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response FinishWebAuthnRegistration200JSONResponse) VisitFinishWebAuthnRegistrationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type ListMyIdentitiesRequestObject struct { +type ListMyNotificationPreferencesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type ListMyIdentitiesResponseObject interface { - VisitListMyIdentitiesResponse(w http.ResponseWriter) error +type ListMyNotificationPreferencesResponseObject interface { + VisitListMyNotificationPreferencesResponse(w http.ResponseWriter) error } -type ListMyIdentities200JSONResponse struct{ PageJSONResponse } +type ListMyNotificationPreferences200JSONResponse NotificationPreferencePage -func (response ListMyIdentities200JSONResponse) VisitListMyIdentitiesResponse(w http.ResponseWriter) error { +func (response ListMyNotificationPreferences200JSONResponse) VisitListMyNotificationPreferencesResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23710,239 +29734,285 @@ func (response ListMyIdentities200JSONResponse) VisitListMyIdentitiesResponse(w return err } -type UnlinkMyIdentityRequestObject struct { +type UpdateMyNotificationPreferenceRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - IdentityId UUID `json:"identity_id"` + Category interface{} `json:"category"` + Body *UpdateMyNotificationPreferenceJSONRequestBody } -type UnlinkMyIdentityResponseObject interface { - VisitUnlinkMyIdentityResponse(w http.ResponseWriter) error +type UpdateMyNotificationPreferenceResponseObject interface { + VisitUpdateMyNotificationPreferenceResponse(w http.ResponseWriter) error } -type UnlinkMyIdentity204Response struct { +type UpdateMyNotificationPreference204Response struct { } -func (response UnlinkMyIdentity204Response) VisitUnlinkMyIdentityResponse(w http.ResponseWriter) error { +func (response UpdateMyNotificationPreference204Response) VisitUpdateMyNotificationPreferenceResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type StartAppleLinkRequestObject struct { +type ListMyOAuthConsentsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *StartAppleLinkJSONRequestBody } -type StartAppleLinkResponseObject interface { - VisitStartAppleLinkResponse(w http.ResponseWriter) error +type ListMyOAuthConsentsResponseObject interface { + VisitListMyOAuthConsentsResponse(w http.ResponseWriter) error } -type StartAppleLink201Response struct { -} +type ListMyOAuthConsents200JSONResponse OAuthConsentPage -func (response StartAppleLink201Response) VisitStartAppleLinkResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil +func (response ListMyOAuthConsents200JSONResponse) VisitListMyOAuthConsentsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type StartGoogleLinkRequestObject struct { +type RevokeMyOAuthConsentRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *StartGoogleLinkJSONRequestBody + ClientId UUID `json:"client_id"` } -type StartGoogleLinkResponseObject interface { - VisitStartGoogleLinkResponse(w http.ResponseWriter) error +type RevokeMyOAuthConsentResponseObject interface { + VisitRevokeMyOAuthConsentResponse(w http.ResponseWriter) error } -type StartGoogleLink201Response struct { +type RevokeMyOAuthConsent204Response struct { } -func (response StartGoogleLink201Response) VisitStartGoogleLinkResponse(w http.ResponseWriter) error { - w.WriteHeader(201) +func (response RevokeMyOAuthConsent204Response) VisitRevokeMyOAuthConsentResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type GetMyBillingSummaryRequestObject struct { +type PasswordChangeRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + Body *PasswordChangeJSONRequestBody } -type GetMyBillingSummaryResponseObject interface { - VisitGetMyBillingSummaryResponse(w http.ResponseWriter) error +type PasswordChangeResponseObject interface { + VisitPasswordChangeResponse(w http.ResponseWriter) error } -type GetMyBillingSummary200Response struct { +type PasswordChange204Response struct { } -func (response GetMyBillingSummary200Response) VisitGetMyBillingSummaryResponse(w http.ResponseWriter) error { - w.WriteHeader(200) +func (response PasswordChange204Response) VisitPasswordChangeResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type GetMyBillingProfileRequestObject struct { +type ListMyPaymentsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type GetMyBillingProfileResponseObject interface { - VisitGetMyBillingProfileResponse(w http.ResponseWriter) error +type ListMyPaymentsResponseObject interface { + VisitListMyPaymentsResponse(w http.ResponseWriter) error } -type GetMyBillingProfile200Response struct { -} +type ListMyPayments200JSONResponse PaymentPage + +func (response ListMyPayments200JSONResponse) VisitListMyPaymentsResponse(w http.ResponseWriter) error { -func (response GetMyBillingProfile200Response) VisitGetMyBillingProfileResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type UpdateMyBillingProfileRequestObject struct { +type CheckMyPermissionsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *UpdateMyBillingProfileJSONRequestBody + Body *CheckMyPermissionsJSONRequestBody } -type UpdateMyBillingProfileResponseObject interface { - VisitUpdateMyBillingProfileResponse(w http.ResponseWriter) error +type CheckMyPermissionsResponseObject interface { + VisitCheckMyPermissionsResponse(w http.ResponseWriter) error } -type UpdateMyBillingProfile204Response struct { -} +type CheckMyPermissions200JSONResponse PermissionCheckResult -func (response UpdateMyBillingProfile204Response) VisitUpdateMyBillingProfileResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response CheckMyPermissions200JSONResponse) VisitCheckMyPermissionsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type EmailChangeStartRequestObject struct { +type ListMySessionsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *EmailChangeStartJSONRequestBody } -type EmailChangeStartResponseObject interface { - VisitEmailChangeStartResponse(w http.ResponseWriter) error +type ListMySessionsResponseObject interface { + VisitListMySessionsResponse(w http.ResponseWriter) error } -type EmailChangeStart202Response struct { -} +type ListMySessions200JSONResponse SessionPage -func (response EmailChangeStart202Response) VisitEmailChangeStartResponse(w http.ResponseWriter) error { - w.WriteHeader(202) - return nil +func (response ListMySessions200JSONResponse) VisitListMySessionsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type EmailChangeVerifyRequestObject struct { +type RevokeMySessionRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *EmailChangeVerifyJSONRequestBody + SessionId UUID `json:"session_id"` } -type EmailChangeVerifyResponseObject interface { - VisitEmailChangeVerifyResponse(w http.ResponseWriter) error +type RevokeMySessionResponseObject interface { + VisitRevokeMySessionResponse(w http.ResponseWriter) error } -type EmailChangeVerify204Response struct { +type RevokeMySession204Response struct { } -func (response EmailChangeVerify204Response) VisitEmailChangeVerifyResponse(w http.ResponseWriter) error { +func (response RevokeMySession204Response) VisitRevokeMySessionResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type EmailVerificationStartRequestObject struct { +type ListMyStorageObjectsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type EmailVerificationStartResponseObject interface { - VisitEmailVerificationStartResponse(w http.ResponseWriter) error +type ListMyStorageObjectsResponseObject interface { + VisitListMyStorageObjectsResponse(w http.ResponseWriter) error } -type EmailVerificationStart202Response struct { -} +type ListMyStorageObjects200JSONResponse StorageObjectPage -func (response EmailVerificationStart202Response) VisitEmailVerificationStartResponse(w http.ResponseWriter) error { - w.WriteHeader(202) - return nil +func (response ListMyStorageObjects200JSONResponse) VisitListMyStorageObjectsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type EmailVerificationVerifyRequestObject struct { +type DeleteMyStorageObjectRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *EmailVerificationVerifyJSONRequestBody + ObjectId ObjectID `json:"object_id"` } -type EmailVerificationVerifyResponseObject interface { - VisitEmailVerificationVerifyResponse(w http.ResponseWriter) error +type DeleteMyStorageObjectResponseObject interface { + VisitDeleteMyStorageObjectResponse(w http.ResponseWriter) error } -type EmailVerificationVerify204Response struct { +type DeleteMyStorageObject204Response struct { } -func (response EmailVerificationVerify204Response) VisitEmailVerificationVerifyResponse(w http.ResponseWriter) error { +func (response DeleteMyStorageObject204Response) VisitDeleteMyStorageObjectResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type ListMyEntitlementsRequestObject struct { +type GetMyStorageObjectRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params ListMyEntitlementsParams + ObjectId ObjectID `json:"object_id"` } -type ListMyEntitlementsResponseObject interface { - VisitListMyEntitlementsResponse(w http.ResponseWriter) error +type GetMyStorageObjectResponseObject interface { + VisitGetMyStorageObjectResponse(w http.ResponseWriter) error } -type ListMyEntitlements200Response struct { -} +type GetMyStorageObject200JSONResponse StorageObject -func (response ListMyEntitlements200Response) VisitListMyEntitlementsResponse(w http.ResponseWriter) error { +func (response GetMyStorageObject200JSONResponse) VisitGetMyStorageObjectResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type ExportMyAccountRequestObject struct { +type DownloadMyStorageObjectRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + ObjectId ObjectID `json:"object_id"` } -type ExportMyAccountResponseObject interface { - VisitExportMyAccountResponse(w http.ResponseWriter) error +type DownloadMyStorageObjectResponseObject interface { + VisitDownloadMyStorageObjectResponse(w http.ResponseWriter) error } -type ExportMyAccount200Response struct { -} +type DownloadMyStorageObject200JSONResponse StorageDownload + +func (response DownloadMyStorageObject200JSONResponse) VisitDownloadMyStorageObjectResponse(w http.ResponseWriter) error { -func (response ExportMyAccount200Response) VisitExportMyAccountResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type ListMyInvoicesRequestObject struct { +type CreateMyStorageUploadRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + Params CreateMyStorageUploadParams + Body *CreateMyStorageUploadJSONRequestBody } -type ListMyInvoicesResponseObject interface { - VisitListMyInvoicesResponse(w http.ResponseWriter) error +type CreateMyStorageUploadResponseObject interface { + VisitCreateMyStorageUploadResponse(w http.ResponseWriter) error } -type ListMyInvoices200JSONResponse struct{ PageJSONResponse } +type CreateMyStorageUpload201JSONResponse StorageUploadAuthorization -func (response ListMyInvoices200JSONResponse) VisitListMyInvoicesResponse(w http.ResponseWriter) error { +func (response CreateMyStorageUpload201JSONResponse) VisitCreateMyStorageUploadResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type ListMyLocalEntitlementRequestsRequestObject struct { +type CompleteMyStorageUploadRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + ObjectId ObjectID `json:"object_id"` } -type ListMyLocalEntitlementRequestsResponseObject interface { - VisitListMyLocalEntitlementRequestsResponse(w http.ResponseWriter) error +type CompleteMyStorageUploadResponseObject interface { + VisitCompleteMyStorageUploadResponse(w http.ResponseWriter) error } -type ListMyLocalEntitlementRequests200JSONResponse struct{ PageJSONResponse } +type CompleteMyStorageUpload200JSONResponse StorageObject -func (response ListMyLocalEntitlementRequests200JSONResponse) VisitListMyLocalEntitlementRequestsResponse(w http.ResponseWriter) error { +func (response CompleteMyStorageUpload200JSONResponse) VisitCompleteMyStorageUploadResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -23954,191 +30024,240 @@ func (response ListMyLocalEntitlementRequests200JSONResponse) VisitListMyLocalEn return err } -type GetMyLocalEntitlementRequestRequestObject struct { +type ListMySubscriptionsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - RequestId RequestID `json:"request_id"` } -type GetMyLocalEntitlementRequestResponseObject interface { - VisitGetMyLocalEntitlementRequestResponse(w http.ResponseWriter) error +type ListMySubscriptionsResponseObject interface { + VisitListMySubscriptionsResponse(w http.ResponseWriter) error } -type GetMyLocalEntitlementRequest200Response struct { -} +type ListMySubscriptions200JSONResponse SubscriptionPage + +func (response ListMySubscriptions200JSONResponse) VisitListMySubscriptionsResponse(w http.ResponseWriter) error { -func (response GetMyLocalEntitlementRequest200Response) VisitGetMyLocalEntitlementRequestResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type CancelMyLocalEntitlementRequestRequestObject struct { +type ListMyPendingInvitationsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - RequestId RequestID `json:"request_id"` } -type CancelMyLocalEntitlementRequestResponseObject interface { - VisitCancelMyLocalEntitlementRequestResponse(w http.ResponseWriter) error +type ListMyPendingInvitationsResponseObject interface { + VisitListMyPendingInvitationsResponse(w http.ResponseWriter) error } -type CancelMyLocalEntitlementRequest204Response struct { -} +type ListMyPendingInvitations200JSONResponse ApplicationInvitationPage -func (response CancelMyLocalEntitlementRequest204Response) VisitCancelMyLocalEntitlementRequestResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response ListMyPendingInvitations200JSONResponse) VisitListMyPendingInvitationsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type LogoutAllRequestObject struct { +type ListMyWorkspacesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type LogoutAllResponseObject interface { - VisitLogoutAllResponse(w http.ResponseWriter) error +type ListMyWorkspacesResponseObject interface { + VisitListMyWorkspacesResponse(w http.ResponseWriter) error } -type LogoutAll204Response struct { -} +type ListMyWorkspaces200JSONResponse WorkspacePage -func (response LogoutAll204Response) VisitLogoutAllResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response ListMyWorkspaces200JSONResponse) VisitListMyWorkspacesResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type ListMyMFAMethodsRequestObject struct { +type CreateMyWorkspaceRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + Body *CreateMyWorkspaceJSONRequestBody } -type ListMyMFAMethodsResponseObject interface { - VisitListMyMFAMethodsResponse(w http.ResponseWriter) error +type CreateMyWorkspaceResponseObject interface { + VisitCreateMyWorkspaceResponse(w http.ResponseWriter) error } -type ListMyMFAMethods200JSONResponse struct{ PageJSONResponse } +type CreateMyWorkspace201JSONResponse Workspace -func (response ListMyMFAMethods200JSONResponse) VisitListMyMFAMethodsResponse(w http.ResponseWriter) error { +func (response CreateMyWorkspace201JSONResponse) VisitCreateMyWorkspaceResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type DisableMFAMethodRequestObject struct { +type SendMachineNotificationRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - MethodId UUID `json:"method_id"` + Params SendMachineNotificationParams + Body *SendMachineNotificationJSONRequestBody } -type DisableMFAMethodResponseObject interface { - VisitDisableMFAMethodResponse(w http.ResponseWriter) error +type SendMachineNotificationResponseObject interface { + VisitSendMachineNotificationResponse(w http.ResponseWriter) error } -type DisableMFAMethod204Response struct { -} +type SendMachineNotification202JSONResponse QueuedNotification -func (response DisableMFAMethod204Response) VisitDisableMFAMethodResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil -} +func (response SendMachineNotification202JSONResponse) VisitSendMachineNotificationResponse(w http.ResponseWriter) error { -type RegenerateRecoveryCodesRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) + _, err := buf.WriteTo(w) + return err } -type RegenerateRecoveryCodesResponseObject interface { - VisitRegenerateRecoveryCodesResponse(w http.ResponseWriter) error +type SendMachineNotification403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type RegenerateRecoveryCodes200Response struct { -} +func (response SendMachineNotification403ApplicationProblemPlusJSONResponse) VisitSendMachineNotificationResponse(w http.ResponseWriter) error { -func (response RegenerateRecoveryCodes200Response) VisitRegenerateRecoveryCodesResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type StartTOTPEnrollmentRequestObject struct { +type ListPermissionGrantsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *StartTOTPEnrollmentJSONRequestBody + Params ListPermissionGrantsParams } -type StartTOTPEnrollmentResponseObject interface { - VisitStartTOTPEnrollmentResponse(w http.ResponseWriter) error +type ListPermissionGrantsResponseObject interface { + VisitListPermissionGrantsResponse(w http.ResponseWriter) error } -type StartTOTPEnrollment201Response struct { -} +type ListPermissionGrants200JSONResponse PermissionGrantPage -func (response StartTOTPEnrollment201Response) VisitStartTOTPEnrollmentResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil -} +func (response ListPermissionGrants200JSONResponse) VisitListPermissionGrantsResponse(w http.ResponseWriter) error { -type ActivateTOTPEnrollmentRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - MethodId UUID `json:"method_id"` - Body *ActivateTOTPEnrollmentJSONRequestBody + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type ActivateTOTPEnrollmentResponseObject interface { - VisitActivateTOTPEnrollmentResponse(w http.ResponseWriter) error +type ListPermissionGrants403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type ActivateTOTPEnrollment200Response struct { -} +func (response ListPermissionGrants403ApplicationProblemPlusJSONResponse) VisitListPermissionGrantsResponse(w http.ResponseWriter) error { -func (response ActivateTOTPEnrollment200Response) VisitActivateTOTPEnrollmentResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type BeginWebAuthnRegistrationRequestObject struct { +type CreatePermissionGrantRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *BeginWebAuthnRegistrationJSONRequestBody + Params CreatePermissionGrantParams + Body *CreatePermissionGrantJSONRequestBody } -type BeginWebAuthnRegistrationResponseObject interface { - VisitBeginWebAuthnRegistrationResponse(w http.ResponseWriter) error +type CreatePermissionGrantResponseObject interface { + VisitCreatePermissionGrantResponse(w http.ResponseWriter) error } -type BeginWebAuthnRegistration201Response struct { -} +type CreatePermissionGrant201JSONResponse PermissionGrant + +func (response CreatePermissionGrant201JSONResponse) VisitCreatePermissionGrantResponse(w http.ResponseWriter) error { -func (response BeginWebAuthnRegistration201Response) VisitBeginWebAuthnRegistrationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } -type FinishWebAuthnRegistrationRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - Body *FinishWebAuthnRegistrationJSONRequestBody +type CreatePermissionGrant403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type FinishWebAuthnRegistrationResponseObject interface { - VisitFinishWebAuthnRegistrationResponse(w http.ResponseWriter) error -} +func (response CreatePermissionGrant403ApplicationProblemPlusJSONResponse) VisitCreatePermissionGrantResponse(w http.ResponseWriter) error { -type FinishWebAuthnRegistration200Response struct { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -func (response FinishWebAuthnRegistration200Response) VisitFinishWebAuthnRegistrationResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil +type CreatePermissionGrant422ApplicationProblemPlusJSONResponse Problem + +func (response CreatePermissionGrant422ApplicationProblemPlusJSONResponse) VisitCreatePermissionGrantResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(422) + _, err := buf.WriteTo(w) + return err } -type ListMyNotificationPreferencesRequestObject struct { +type GetEffectiveAccessRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + Params GetEffectiveAccessParams } -type ListMyNotificationPreferencesResponseObject interface { - VisitListMyNotificationPreferencesResponse(w http.ResponseWriter) error +type GetEffectiveAccessResponseObject interface { + VisitGetEffectiveAccessResponse(w http.ResponseWriter) error } -type ListMyNotificationPreferences200JSONResponse struct{ PageJSONResponse } +type GetEffectiveAccess200JSONResponse EffectiveAccess -func (response ListMyNotificationPreferences200JSONResponse) VisitListMyNotificationPreferencesResponse(w http.ResponseWriter) error { +func (response GetEffectiveAccess200JSONResponse) VisitGetEffectiveAccessResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24150,91 +30269,113 @@ func (response ListMyNotificationPreferences200JSONResponse) VisitListMyNotifica return err } -type UpdateMyNotificationPreferenceRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - Category interface{} `json:"category"` - Body *UpdateMyNotificationPreferenceJSONRequestBody +type GetEffectiveAccess403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type UpdateMyNotificationPreferenceResponseObject interface { - VisitUpdateMyNotificationPreferenceResponse(w http.ResponseWriter) error +func (response GetEffectiveAccess403ApplicationProblemPlusJSONResponse) VisitGetEffectiveAccessResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type UpdateMyNotificationPreference204Response struct { +type RevokePermissionGrantRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + GrantId UUID `json:"grant_id"` + Params RevokePermissionGrantParams } -func (response UpdateMyNotificationPreference204Response) VisitUpdateMyNotificationPreferenceResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +type RevokePermissionGrantResponseObject interface { + VisitRevokePermissionGrantResponse(w http.ResponseWriter) error } -type ListMyOAuthConsentsRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` +type RevokePermissionGrant204Response struct { } -type ListMyOAuthConsentsResponseObject interface { - VisitListMyOAuthConsentsResponse(w http.ResponseWriter) error +func (response RevokePermissionGrant204Response) VisitRevokePermissionGrantResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil } -type ListMyOAuthConsents200JSONResponse struct{ PageJSONResponse } +type RevokePermissionGrant409ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} -func (response ListMyOAuthConsents200JSONResponse) VisitListMyOAuthConsentsResponse(w http.ResponseWriter) error { +func (response RevokePermissionGrant409ApplicationProblemPlusJSONResponse) VisitRevokePermissionGrantResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(409) _, err := buf.WriteTo(w) return err } -type RevokeMyOAuthConsentRequestObject struct { +type GetPermissionGrantRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - ClientId UUID `json:"client_id"` + GrantId UUID `json:"grant_id"` } -type RevokeMyOAuthConsentResponseObject interface { - VisitRevokeMyOAuthConsentResponse(w http.ResponseWriter) error +type GetPermissionGrantResponseObject interface { + VisitGetPermissionGrantResponse(w http.ResponseWriter) error } -type RevokeMyOAuthConsent204Response struct { -} +type GetPermissionGrant200JSONResponse PermissionGrant -func (response RevokeMyOAuthConsent204Response) VisitRevokeMyOAuthConsentResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response GetPermissionGrant200JSONResponse) VisitGetPermissionGrantResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type PasswordChangeRequestObject struct { +type PublicConfigRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Body *PasswordChangeJSONRequestBody } -type PasswordChangeResponseObject interface { - VisitPasswordChangeResponse(w http.ResponseWriter) error +type PublicConfigResponseObject interface { + VisitPublicConfigResponse(w http.ResponseWriter) error } -type PasswordChange204Response struct { -} +type PublicConfig200JSONResponse RuntimeConfig -func (response PasswordChange204Response) VisitPasswordChangeResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response PublicConfig200JSONResponse) VisitPublicConfigResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type ListMyPaymentsRequestObject struct { +type ServiceGetApplicationWorkspaceRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + WorkspaceId UUID `json:"workspace_id"` } -type ListMyPaymentsResponseObject interface { - VisitListMyPaymentsResponse(w http.ResponseWriter) error +type ServiceGetApplicationWorkspaceResponseObject interface { + VisitServiceGetApplicationWorkspaceResponse(w http.ResponseWriter) error } -type ListMyPayments200JSONResponse struct{ PageJSONResponse } +type ServiceGetApplicationWorkspace200JSONResponse Workspace -func (response ListMyPayments200JSONResponse) VisitListMyPaymentsResponse(w http.ResponseWriter) error { +func (response ServiceGetApplicationWorkspace200JSONResponse) VisitServiceGetApplicationWorkspaceResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24246,34 +30387,34 @@ func (response ListMyPayments200JSONResponse) VisitListMyPaymentsResponse(w http return err } -type CheckMyPermissionsRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - Body *CheckMyPermissionsJSONRequestBody -} - -type CheckMyPermissionsResponseObject interface { - VisitCheckMyPermissionsResponse(w http.ResponseWriter) error +type ServiceGetApplicationWorkspace403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type CheckMyPermissions200Response struct { -} +func (response ServiceGetApplicationWorkspace403ApplicationProblemPlusJSONResponse) VisitServiceGetApplicationWorkspaceResponse(w http.ResponseWriter) error { -func (response CheckMyPermissions200Response) VisitCheckMyPermissionsResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type ListMySessionsRequestObject struct { +type ServiceListApplicationWorkspaceAccessRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + WorkspaceId UUID `json:"workspace_id"` } -type ListMySessionsResponseObject interface { - VisitListMySessionsResponse(w http.ResponseWriter) error +type ServiceListApplicationWorkspaceAccessResponseObject interface { + VisitServiceListApplicationWorkspaceAccessResponse(w http.ResponseWriter) error } -type ListMySessions200JSONResponse struct{ PageJSONResponse } +type ServiceListApplicationWorkspaceAccess200JSONResponse WorkspaceAccessPage -func (response ListMySessions200JSONResponse) VisitListMySessionsResponse(w http.ResponseWriter) error { +func (response ServiceListApplicationWorkspaceAccess200JSONResponse) VisitServiceListApplicationWorkspaceAccessResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24285,34 +30426,33 @@ func (response ListMySessions200JSONResponse) VisitListMySessionsResponse(w http return err } -type RevokeMySessionRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - SessionId UUID `json:"session_id"` -} - -type RevokeMySessionResponseObject interface { - VisitRevokeMySessionResponse(w http.ResponseWriter) error +type ServiceListApplicationWorkspaceAccess403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type RevokeMySession204Response struct { -} +func (response ServiceListApplicationWorkspaceAccess403ApplicationProblemPlusJSONResponse) VisitServiceListApplicationWorkspaceAccessResponse(w http.ResponseWriter) error { -func (response RevokeMySession204Response) VisitRevokeMySessionResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type ListMyStorageObjectsRequestObject struct { +type ListApplicationStorageObjectsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type ListMyStorageObjectsResponseObject interface { - VisitListMyStorageObjectsResponse(w http.ResponseWriter) error +type ListApplicationStorageObjectsResponseObject interface { + VisitListApplicationStorageObjectsResponse(w http.ResponseWriter) error } -type ListMyStorageObjects200JSONResponse struct{ PageJSONResponse } +type ListApplicationStorageObjects200JSONResponse StorageObjectPage -func (response ListMyStorageObjects200JSONResponse) VisitListMyStorageObjectsResponse(w http.ResponseWriter) error { +func (response ListApplicationStorageObjects200JSONResponse) VisitListApplicationStorageObjectsResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24324,103 +30464,105 @@ func (response ListMyStorageObjects200JSONResponse) VisitListMyStorageObjectsRes return err } -type DeleteMyStorageObjectRequestObject struct { +type DeleteApplicationStorageObjectRequestObject struct { ApplicationId ApplicationID `json:"application_id"` ObjectId ObjectID `json:"object_id"` } -type DeleteMyStorageObjectResponseObject interface { - VisitDeleteMyStorageObjectResponse(w http.ResponseWriter) error +type DeleteApplicationStorageObjectResponseObject interface { + VisitDeleteApplicationStorageObjectResponse(w http.ResponseWriter) error } -type DeleteMyStorageObject204Response struct { +type DeleteApplicationStorageObject204Response struct { } -func (response DeleteMyStorageObject204Response) VisitDeleteMyStorageObjectResponse(w http.ResponseWriter) error { +func (response DeleteApplicationStorageObject204Response) VisitDeleteApplicationStorageObjectResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type GetMyStorageObjectRequestObject struct { +type GetApplicationStorageObjectRequestObject struct { ApplicationId ApplicationID `json:"application_id"` ObjectId ObjectID `json:"object_id"` } -type GetMyStorageObjectResponseObject interface { - VisitGetMyStorageObjectResponse(w http.ResponseWriter) error +type GetApplicationStorageObjectResponseObject interface { + VisitGetApplicationStorageObjectResponse(w http.ResponseWriter) error } -type GetMyStorageObject200Response struct { -} +type GetApplicationStorageObject200JSONResponse StorageObject + +func (response GetApplicationStorageObject200JSONResponse) VisitGetApplicationStorageObjectResponse(w http.ResponseWriter) error { -func (response GetMyStorageObject200Response) VisitGetMyStorageObjectResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type DownloadMyStorageObjectRequestObject struct { +type DownloadApplicationStorageObjectRequestObject struct { ApplicationId ApplicationID `json:"application_id"` ObjectId ObjectID `json:"object_id"` } -type DownloadMyStorageObjectResponseObject interface { - VisitDownloadMyStorageObjectResponse(w http.ResponseWriter) error +type DownloadApplicationStorageObjectResponseObject interface { + VisitDownloadApplicationStorageObjectResponse(w http.ResponseWriter) error } -type DownloadMyStorageObject200Response struct { -} +type DownloadApplicationStorageObject200JSONResponse StorageDownload + +func (response DownloadApplicationStorageObject200JSONResponse) VisitDownloadApplicationStorageObjectResponse(w http.ResponseWriter) error { -func (response DownloadMyStorageObject200Response) VisitDownloadMyStorageObjectResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type CreateMyStorageUploadRequestObject struct { +type CreateApplicationStorageUploadRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params CreateMyStorageUploadParams - Body *CreateMyStorageUploadJSONRequestBody + Params CreateApplicationStorageUploadParams + Body *CreateApplicationStorageUploadJSONRequestBody } -type CreateMyStorageUploadResponseObject interface { - VisitCreateMyStorageUploadResponse(w http.ResponseWriter) error +type CreateApplicationStorageUploadResponseObject interface { + VisitCreateApplicationStorageUploadResponse(w http.ResponseWriter) error } -type CreateMyStorageUpload201Response struct { -} +type CreateApplicationStorageUpload201JSONResponse StorageUploadAuthorization + +func (response CreateApplicationStorageUpload201JSONResponse) VisitCreateApplicationStorageUploadResponse(w http.ResponseWriter) error { -func (response CreateMyStorageUpload201Response) VisitCreateMyStorageUploadResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } -type CompleteMyStorageUploadRequestObject struct { +type CompleteApplicationStorageUploadRequestObject struct { ApplicationId ApplicationID `json:"application_id"` ObjectId ObjectID `json:"object_id"` } -type CompleteMyStorageUploadResponseObject interface { - VisitCompleteMyStorageUploadResponse(w http.ResponseWriter) error -} - -type CompleteMyStorageUpload200Response struct { -} - -func (response CompleteMyStorageUpload200Response) VisitCompleteMyStorageUploadResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil -} - -type ListMySubscriptionsRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` -} - -type ListMySubscriptionsResponseObject interface { - VisitListMySubscriptionsResponse(w http.ResponseWriter) error +type CompleteApplicationStorageUploadResponseObject interface { + VisitCompleteApplicationStorageUploadResponse(w http.ResponseWriter) error } -type ListMySubscriptions200JSONResponse struct{ PageJSONResponse } +type CompleteApplicationStorageUpload200JSONResponse StorageObject -func (response ListMySubscriptions200JSONResponse) VisitListMySubscriptionsResponse(w http.ResponseWriter) error { +func (response CompleteApplicationStorageUpload200JSONResponse) VisitCompleteApplicationStorageUploadResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24432,17 +30574,19 @@ func (response ListMySubscriptions200JSONResponse) VisitListMySubscriptionsRespo return err } -type ListMyWorkspaceInvitationsRequestObject struct { +type ServiceGetSubjectBillingRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + SubjectType interface{} `json:"subject_type"` + SubjectId UUID `json:"subject_id"` } -type ListMyWorkspaceInvitationsResponseObject interface { - VisitListMyWorkspaceInvitationsResponse(w http.ResponseWriter) error +type ServiceGetSubjectBillingResponseObject interface { + VisitServiceGetSubjectBillingResponse(w http.ResponseWriter) error } -type ListMyWorkspaceInvitations200JSONResponse struct{ PageJSONResponse } +type ServiceGetSubjectBilling200JSONResponse BillingSummary -func (response ListMyWorkspaceInvitations200JSONResponse) VisitListMyWorkspaceInvitationsResponse(w http.ResponseWriter) error { +func (response ServiceGetSubjectBilling200JSONResponse) VisitServiceGetSubjectBillingResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24454,35 +30598,35 @@ func (response ListMyWorkspaceInvitations200JSONResponse) VisitListMyWorkspaceIn return err } -type AcceptMyWorkspaceInvitationRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - InvitationId UUID `json:"invitation_id"` - Body *AcceptMyWorkspaceInvitationJSONRequestBody -} - -type AcceptMyWorkspaceInvitationResponseObject interface { - VisitAcceptMyWorkspaceInvitationResponse(w http.ResponseWriter) error +type ServiceGetSubjectBilling403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type AcceptMyWorkspaceInvitation200Response struct { -} +func (response ServiceGetSubjectBilling403ApplicationProblemPlusJSONResponse) VisitServiceGetSubjectBillingResponse(w http.ResponseWriter) error { -func (response AcceptMyWorkspaceInvitation200Response) VisitAcceptMyWorkspaceInvitationResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type ListMyWorkspacesRequestObject struct { +type ServiceGetSubjectEntitlementsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` + SubjectType interface{} `json:"subject_type"` + SubjectId UUID `json:"subject_id"` } -type ListMyWorkspacesResponseObject interface { - VisitListMyWorkspacesResponse(w http.ResponseWriter) error +type ServiceGetSubjectEntitlementsResponseObject interface { + VisitServiceGetSubjectEntitlementsResponse(w http.ResponseWriter) error } -type ListMyWorkspaces200JSONResponse struct{ PageJSONResponse } +type ServiceGetSubjectEntitlements200JSONResponse EntitlementGrantPage -func (response ListMyWorkspaces200JSONResponse) VisitListMyWorkspacesResponse(w http.ResponseWriter) error { +func (response ServiceGetSubjectEntitlements200JSONResponse) VisitServiceGetSubjectEntitlementsResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24494,34 +30638,33 @@ func (response ListMyWorkspaces200JSONResponse) VisitListMyWorkspacesResponse(w return err } -type CreateMyWorkspaceRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - Body *CreateMyWorkspaceJSONRequestBody -} - -type CreateMyWorkspaceResponseObject interface { - VisitCreateMyWorkspaceResponse(w http.ResponseWriter) error +type ServiceGetSubjectEntitlements403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type CreateMyWorkspace201Response struct { -} +func (response ServiceGetSubjectEntitlements403ApplicationProblemPlusJSONResponse) VisitServiceGetSubjectEntitlementsResponse(w http.ResponseWriter) error { -func (response CreateMyWorkspace201Response) VisitCreateMyWorkspaceResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type PublicConfigRequestObject struct { +type ServiceListApplicationUsersRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } -type PublicConfigResponseObject interface { - VisitPublicConfigResponse(w http.ResponseWriter) error +type ServiceListApplicationUsersResponseObject interface { + VisitServiceListApplicationUsersResponse(w http.ResponseWriter) error } -type PublicConfig200JSONResponse RuntimeConfig +type ServiceListApplicationUsers200JSONResponse UserPage -func (response PublicConfig200JSONResponse) VisitPublicConfigResponse(w http.ResponseWriter) error { +func (response ServiceListApplicationUsers200JSONResponse) VisitServiceListApplicationUsersResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -24533,112 +30676,97 @@ func (response PublicConfig200JSONResponse) VisitPublicConfigResponse(w http.Res return err } -type ListApplicationStorageObjectsRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` -} - -type ListApplicationStorageObjectsResponseObject interface { - VisitListApplicationStorageObjectsResponse(w http.ResponseWriter) error +type ServiceListApplicationUsers403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type ListApplicationStorageObjects200JSONResponse struct{ PageJSONResponse } - -func (response ListApplicationStorageObjects200JSONResponse) VisitListApplicationStorageObjectsResponse(w http.ResponseWriter) error { +func (response ServiceListApplicationUsers403ApplicationProblemPlusJSONResponse) VisitServiceListApplicationUsersResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) _, err := buf.WriteTo(w) return err } -type DeleteApplicationStorageObjectRequestObject struct { +type ServiceGetApplicationUserRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - ObjectId ObjectID `json:"object_id"` -} - -type DeleteApplicationStorageObjectResponseObject interface { - VisitDeleteApplicationStorageObjectResponse(w http.ResponseWriter) error -} - -type DeleteApplicationStorageObject204Response struct { -} - -func (response DeleteApplicationStorageObject204Response) VisitDeleteApplicationStorageObjectResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil + UserId UUID `json:"user_id"` } -type GetApplicationStorageObjectRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - ObjectId ObjectID `json:"object_id"` +type ServiceGetApplicationUserResponseObject interface { + VisitServiceGetApplicationUserResponse(w http.ResponseWriter) error } -type GetApplicationStorageObjectResponseObject interface { - VisitGetApplicationStorageObjectResponse(w http.ResponseWriter) error -} +type ServiceGetApplicationUser200JSONResponse User -type GetApplicationStorageObject200Response struct { -} +func (response ServiceGetApplicationUser200JSONResponse) VisitServiceGetApplicationUserResponse(w http.ResponseWriter) error { -func (response GetApplicationStorageObject200Response) VisitGetApplicationStorageObjectResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil -} - -type DownloadApplicationStorageObjectRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - ObjectId ObjectID `json:"object_id"` + _, err := buf.WriteTo(w) + return err } -type DownloadApplicationStorageObjectResponseObject interface { - VisitDownloadApplicationStorageObjectResponse(w http.ResponseWriter) error +type ServiceGetApplicationUser403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type DownloadApplicationStorageObject200Response struct { -} +func (response ServiceGetApplicationUser403ApplicationProblemPlusJSONResponse) VisitServiceGetApplicationUserResponse(w http.ResponseWriter) error { -func (response DownloadApplicationStorageObject200Response) VisitDownloadApplicationStorageObjectResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } -type CreateApplicationStorageUploadRequestObject struct { +type ServiceListApplicationWorkspacesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params CreateApplicationStorageUploadParams - Body *CreateApplicationStorageUploadJSONRequestBody } -type CreateApplicationStorageUploadResponseObject interface { - VisitCreateApplicationStorageUploadResponse(w http.ResponseWriter) error +type ServiceListApplicationWorkspacesResponseObject interface { + VisitServiceListApplicationWorkspacesResponse(w http.ResponseWriter) error } -type CreateApplicationStorageUpload201Response struct { -} +type ServiceListApplicationWorkspaces200JSONResponse WorkspacePage -func (response CreateApplicationStorageUpload201Response) VisitCreateApplicationStorageUploadResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil -} +func (response ServiceListApplicationWorkspaces200JSONResponse) VisitServiceListApplicationWorkspacesResponse(w http.ResponseWriter) error { -type CompleteApplicationStorageUploadRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - ObjectId ObjectID `json:"object_id"` + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } -type CompleteApplicationStorageUploadResponseObject interface { - VisitCompleteApplicationStorageUploadResponse(w http.ResponseWriter) error +type ServiceListApplicationWorkspaces403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type CompleteApplicationStorageUpload200Response struct { -} +func (response ServiceListApplicationWorkspaces403ApplicationProblemPlusJSONResponse) VisitServiceListApplicationWorkspacesResponse(w http.ResponseWriter) error { -func (response CompleteApplicationStorageUpload200Response) VisitCompleteApplicationStorageUploadResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err } type ArchiveMyWorkspaceRequestObject struct { @@ -24667,12 +30795,18 @@ type GetMyWorkspaceResponseObject interface { VisitGetMyWorkspaceResponse(w http.ResponseWriter) error } -type GetMyWorkspace200Response struct { -} +type GetMyWorkspace200JSONResponse Workspace -func (response GetMyWorkspace200Response) VisitGetMyWorkspaceResponse(w http.ResponseWriter) error { +func (response GetMyWorkspace200JSONResponse) VisitGetMyWorkspaceResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateMyWorkspaceRequestObject struct { @@ -24693,6 +30827,29 @@ func (response UpdateMyWorkspace204Response) VisitUpdateMyWorkspaceResponse(w ht return nil } +type ListMyWorkspaceAccessRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId UUID `json:"workspace_id"` +} + +type ListMyWorkspaceAccessResponseObject interface { + VisitListMyWorkspaceAccessResponse(w http.ResponseWriter) error +} + +type ListMyWorkspaceAccess200JSONResponse WorkspaceAccessPage + +func (response ListMyWorkspaceAccess200JSONResponse) VisitListMyWorkspaceAccessResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + type ListWorkspaceAddressesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` WorkspaceId UUID `json:"workspace_id"` @@ -24702,7 +30859,7 @@ type ListWorkspaceAddressesResponseObject interface { VisitListWorkspaceAddressesResponse(w http.ResponseWriter) error } -type ListWorkspaceAddresses200JSONResponse struct{ PageJSONResponse } +type ListWorkspaceAddresses200JSONResponse AddressPage func (response ListWorkspaceAddresses200JSONResponse) VisitListWorkspaceAddressesResponse(w http.ResponseWriter) error { @@ -24726,12 +30883,18 @@ type CreateWorkspaceAddressResponseObject interface { VisitCreateWorkspaceAddressResponse(w http.ResponseWriter) error } -type CreateWorkspaceAddress201Response struct { -} +type CreateWorkspaceAddress201JSONResponse Address -func (response CreateWorkspaceAddress201Response) VisitCreateWorkspaceAddressResponse(w http.ResponseWriter) error { +func (response CreateWorkspaceAddress201JSONResponse) VisitCreateWorkspaceAddressResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DeleteWorkspaceAddressRequestObject struct { @@ -24798,12 +30961,18 @@ type GetWorkspaceBillingProfileResponseObject interface { VisitGetWorkspaceBillingProfileResponse(w http.ResponseWriter) error } -type GetWorkspaceBillingProfile200Response struct { -} +type GetWorkspaceBillingProfile200JSONResponse BillingProfile -func (response GetWorkspaceBillingProfile200Response) VisitGetWorkspaceBillingProfileResponse(w http.ResponseWriter) error { +func (response GetWorkspaceBillingProfile200JSONResponse) VisitGetWorkspaceBillingProfileResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateWorkspaceBillingProfileRequestObject struct { @@ -24824,6 +30993,29 @@ func (response UpdateWorkspaceBillingProfile204Response) VisitUpdateWorkspaceBil return nil } +type ListMyWorkspaceInvitationsRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId UUID `json:"workspace_id"` +} + +type ListMyWorkspaceInvitationsResponseObject interface { + VisitListMyWorkspaceInvitationsResponse(w http.ResponseWriter) error +} + +type ListMyWorkspaceInvitations200JSONResponse ApplicationInvitationPage + +func (response ListMyWorkspaceInvitations200JSONResponse) VisitListMyWorkspaceInvitationsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + type CreateMyWorkspaceInvitationRequestObject struct { ApplicationId ApplicationID `json:"application_id"` WorkspaceId UUID `json:"workspace_id"` @@ -24834,14 +31026,78 @@ type CreateMyWorkspaceInvitationResponseObject interface { VisitCreateMyWorkspaceInvitationResponse(w http.ResponseWriter) error } -type CreateMyWorkspaceInvitation201Response struct { -} +type CreateMyWorkspaceInvitation201JSONResponse ApplicationInvitation -func (response CreateMyWorkspaceInvitation201Response) VisitCreateMyWorkspaceInvitationResponse(w http.ResponseWriter) error { +func (response CreateMyWorkspaceInvitation201JSONResponse) VisitCreateMyWorkspaceInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type RevokeMyWorkspaceInvitationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId UUID `json:"workspace_id"` + InvitationId UUID `json:"invitation_id"` +} + +type RevokeMyWorkspaceInvitationResponseObject interface { + VisitRevokeMyWorkspaceInvitationResponse(w http.ResponseWriter) error +} + +type RevokeMyWorkspaceInvitation204Response struct { +} + +func (response RevokeMyWorkspaceInvitation204Response) VisitRevokeMyWorkspaceInvitationResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } +type ResendMyWorkspaceInvitationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId UUID `json:"workspace_id"` + InvitationId UUID `json:"invitation_id"` +} + +type ResendMyWorkspaceInvitationResponseObject interface { + VisitResendMyWorkspaceInvitationResponse(w http.ResponseWriter) error +} + +type ResendMyWorkspaceInvitation202JSONResponse InvitationResent + +func (response ResendMyWorkspaceInvitation202JSONResponse) VisitResendMyWorkspaceInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) + _, err := buf.WriteTo(w) + return err +} + +type ResendMyWorkspaceInvitation429ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response ResendMyWorkspaceInvitation429ApplicationProblemPlusJSONResponse) VisitResendMyWorkspaceInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(429) + _, err := buf.WriteTo(w) + return err +} + type ListMyWorkspaceMembersRequestObject struct { ApplicationId ApplicationID `json:"application_id"` WorkspaceId UUID `json:"workspace_id"` @@ -24851,7 +31107,7 @@ type ListMyWorkspaceMembersResponseObject interface { VisitListMyWorkspaceMembersResponse(w http.ResponseWriter) error } -type ListMyWorkspaceMembers200JSONResponse struct{ PageJSONResponse } +type ListMyWorkspaceMembers200JSONResponse WorkspaceMemberPage func (response ListMyWorkspaceMembers200JSONResponse) VisitListMyWorkspaceMembersResponse(w http.ResponseWriter) error { @@ -24894,12 +31150,18 @@ type ReplaceMyWorkspaceMemberRolesResponseObject interface { VisitReplaceMyWorkspaceMemberRolesResponse(w http.ResponseWriter) error } -type ReplaceMyWorkspaceMemberRoles200Response struct { -} +type ReplaceMyWorkspaceMemberRoles200JSONResponse WorkspaceMember + +func (response ReplaceMyWorkspaceMemberRoles200JSONResponse) VisitReplaceMyWorkspaceMemberRolesResponse(w http.ResponseWriter) error { -func (response ReplaceMyWorkspaceMemberRoles200Response) VisitReplaceMyWorkspaceMemberRolesResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type LeaveWorkspaceRequestObject struct { @@ -24945,6 +31207,146 @@ func (response TransferMyWorkspaceOwnership200JSONResponse) VisitTransferMyWorks return err } +type ListWorkspacePermissionGrantsRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId WorkspaceID `json:"workspace_id"` + Params ListWorkspacePermissionGrantsParams +} + +type ListWorkspacePermissionGrantsResponseObject interface { + VisitListWorkspacePermissionGrantsResponse(w http.ResponseWriter) error +} + +type ListWorkspacePermissionGrants200JSONResponse PermissionGrantPage + +func (response ListWorkspacePermissionGrants200JSONResponse) VisitListWorkspacePermissionGrantsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type ListWorkspacePermissionGrants403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response ListWorkspacePermissionGrants403ApplicationProblemPlusJSONResponse) VisitListWorkspacePermissionGrantsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err +} + +type CreateWorkspacePermissionGrantRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId WorkspaceID `json:"workspace_id"` + Params CreateWorkspacePermissionGrantParams + Body *CreateWorkspacePermissionGrantJSONRequestBody +} + +type CreateWorkspacePermissionGrantResponseObject interface { + VisitCreateWorkspacePermissionGrantResponse(w http.ResponseWriter) error +} + +type CreateWorkspacePermissionGrant201JSONResponse PermissionGrant + +func (response CreateWorkspacePermissionGrant201JSONResponse) VisitCreateWorkspacePermissionGrantResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type CreateWorkspacePermissionGrant403ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response CreateWorkspacePermissionGrant403ApplicationProblemPlusJSONResponse) VisitCreateWorkspacePermissionGrantResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(403) + _, err := buf.WriteTo(w) + return err +} + +type RevokeWorkspacePermissionGrantRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId WorkspaceID `json:"workspace_id"` + GrantId UUID `json:"grant_id"` + Params RevokeWorkspacePermissionGrantParams +} + +type RevokeWorkspacePermissionGrantResponseObject interface { + VisitRevokeWorkspacePermissionGrantResponse(w http.ResponseWriter) error +} + +type RevokeWorkspacePermissionGrant204Response struct { +} + +func (response RevokeWorkspacePermissionGrant204Response) VisitRevokeWorkspacePermissionGrantResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type RevokeWorkspacePermissionGrant409ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response RevokeWorkspacePermissionGrant409ApplicationProblemPlusJSONResponse) VisitRevokeWorkspacePermissionGrantResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(409) + _, err := buf.WriteTo(w) + return err +} + +type GetWorkspacePermissionGrantRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + WorkspaceId WorkspaceID `json:"workspace_id"` + GrantId UUID `json:"grant_id"` +} + +type GetWorkspacePermissionGrantResponseObject interface { + VisitGetWorkspacePermissionGrantResponse(w http.ResponseWriter) error +} + +type GetWorkspacePermissionGrant200JSONResponse PermissionGrant + +func (response GetWorkspacePermissionGrant200JSONResponse) VisitGetWorkspacePermissionGrantResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + type ListWorkspaceStorageObjectsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` WorkspaceId WorkspaceID `json:"workspace_id"` @@ -24954,7 +31356,7 @@ type ListWorkspaceStorageObjectsResponseObject interface { VisitListWorkspaceStorageObjectsResponse(w http.ResponseWriter) error } -type ListWorkspaceStorageObjects200JSONResponse struct{ PageJSONResponse } +type ListWorkspaceStorageObjects200JSONResponse StorageObjectPage func (response ListWorkspaceStorageObjects200JSONResponse) VisitListWorkspaceStorageObjectsResponse(w http.ResponseWriter) error { @@ -24996,12 +31398,18 @@ type GetWorkspaceStorageObjectResponseObject interface { VisitGetWorkspaceStorageObjectResponse(w http.ResponseWriter) error } -type GetWorkspaceStorageObject200Response struct { -} +type GetWorkspaceStorageObject200JSONResponse StorageObject + +func (response GetWorkspaceStorageObject200JSONResponse) VisitGetWorkspaceStorageObjectResponse(w http.ResponseWriter) error { -func (response GetWorkspaceStorageObject200Response) VisitGetWorkspaceStorageObjectResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type DownloadWorkspaceStorageObjectRequestObject struct { @@ -25014,12 +31422,18 @@ type DownloadWorkspaceStorageObjectResponseObject interface { VisitDownloadWorkspaceStorageObjectResponse(w http.ResponseWriter) error } -type DownloadWorkspaceStorageObject200Response struct { -} +type DownloadWorkspaceStorageObject200JSONResponse StorageDownload + +func (response DownloadWorkspaceStorageObject200JSONResponse) VisitDownloadWorkspaceStorageObjectResponse(w http.ResponseWriter) error { -func (response DownloadWorkspaceStorageObject200Response) VisitDownloadWorkspaceStorageObjectResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type CreateWorkspaceStorageUploadRequestObject struct { @@ -25033,12 +31447,18 @@ type CreateWorkspaceStorageUploadResponseObject interface { VisitCreateWorkspaceStorageUploadResponse(w http.ResponseWriter) error } -type CreateWorkspaceStorageUpload201Response struct { -} +type CreateWorkspaceStorageUpload201JSONResponse StorageUploadAuthorization + +func (response CreateWorkspaceStorageUpload201JSONResponse) VisitCreateWorkspaceStorageUploadResponse(w http.ResponseWriter) error { -func (response CreateWorkspaceStorageUpload201Response) VisitCreateWorkspaceStorageUploadResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type CompleteWorkspaceStorageUploadRequestObject struct { @@ -25051,11 +31471,48 @@ type CompleteWorkspaceStorageUploadResponseObject interface { VisitCompleteWorkspaceStorageUploadResponse(w http.ResponseWriter) error } -type CompleteWorkspaceStorageUpload200Response struct { -} +type CompleteWorkspaceStorageUpload200JSONResponse StorageObject + +func (response CompleteWorkspaceStorageUpload200JSONResponse) VisitCompleteWorkspaceStorageUploadResponse(w http.ResponseWriter) error { -func (response CompleteWorkspaceStorageUpload200Response) VisitCompleteWorkspaceStorageUploadResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type AppleAuthCallbackRequestObject struct { + Body *AppleAuthCallbackFormdataRequestBody +} + +type AppleAuthCallbackResponseObject interface { + VisitAppleAuthCallbackResponse(w http.ResponseWriter) error +} + +type AppleAuthCallback302Response struct { +} + +func (response AppleAuthCallback302Response) VisitAppleAuthCallbackResponse(w http.ResponseWriter) error { + w.WriteHeader(302) + return nil +} + +type GoogleAuthCallbackRequestObject struct { +} + +type GoogleAuthCallbackResponseObject interface { + VisitGoogleAuthCallbackResponse(w http.ResponseWriter) error +} + +type GoogleAuthCallback302Response struct { +} + +func (response GoogleAuthCallback302Response) VisitGoogleAuthCallbackResponse(w http.ResponseWriter) error { + w.WriteHeader(302) return nil } @@ -25067,12 +31524,18 @@ type GetApplicationResponseObject interface { VisitGetApplicationResponse(w http.ResponseWriter) error } -type GetApplication200Response struct { -} +type GetApplication200JSONResponse Application + +func (response GetApplication200JSONResponse) VisitGetApplicationResponse(w http.ResponseWriter) error { -func (response GetApplication200Response) VisitGetApplicationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type CreateAuditExportRequestObject struct { @@ -25084,12 +31547,18 @@ type CreateAuditExportResponseObject interface { VisitCreateAuditExportResponse(w http.ResponseWriter) error } -type CreateAuditExport201Response struct { -} +type CreateAuditExport201JSONResponse AuditExportRecord -func (response CreateAuditExport201Response) VisitCreateAuditExportResponse(w http.ResponseWriter) error { +func (response CreateAuditExport201JSONResponse) VisitCreateAuditExportResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type GetAuditExportRequestObject struct { @@ -25101,12 +31570,18 @@ type GetAuditExportResponseObject interface { VisitGetAuditExportResponse(w http.ResponseWriter) error } -type GetAuditExport200Response struct { -} +type GetAuditExport200JSONResponse AuditExportRecord -func (response GetAuditExport200Response) VisitGetAuditExportResponse(w http.ResponseWriter) error { +func (response GetAuditExport200JSONResponse) VisitGetAuditExportResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListAuditLogsRequestObject struct { @@ -25117,7 +31592,7 @@ type ListAuditLogsResponseObject interface { VisitListAuditLogsResponse(w http.ResponseWriter) error } -type ListAuditLogs200JSONResponse struct{ PageJSONResponse } +type ListAuditLogs200JSONResponse AuditRecordPage func (response ListAuditLogs200JSONResponse) VisitListAuditLogsResponse(w http.ResponseWriter) error { @@ -25140,12 +31615,18 @@ type GetAuditLogResponseObject interface { VisitGetAuditLogResponse(w http.ResponseWriter) error } -type GetAuditLog200Response struct { -} +type GetAuditLog200JSONResponse AuditRecord -func (response GetAuditLog200Response) VisitGetAuditLogResponse(w http.ResponseWriter) error { +func (response GetAuditLog200JSONResponse) VisitGetAuditLogResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateAuthConfigRequestObject struct { @@ -25173,7 +31654,7 @@ type ListApplicationAuthProvidersResponseObject interface { VisitListApplicationAuthProvidersResponse(w http.ResponseWriter) error } -type ListApplicationAuthProviders200JSONResponse struct{ PageJSONResponse } +type ListApplicationAuthProviders200JSONResponse AuthProviderPage func (response ListApplicationAuthProviders200JSONResponse) VisitListApplicationAuthProvidersResponse(w http.ResponseWriter) error { @@ -25196,12 +31677,18 @@ type ConfigureAppleProviderResponseObject interface { VisitConfigureAppleProviderResponse(w http.ResponseWriter) error } -type ConfigureAppleProvider200Response struct { -} +type ConfigureAppleProvider200JSONResponse AuthProvider -func (response ConfigureAppleProvider200Response) VisitConfigureAppleProviderResponse(w http.ResponseWriter) error { +func (response ConfigureAppleProvider200JSONResponse) VisitConfigureAppleProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ConfigureGoogleProviderRequestObject struct { @@ -25213,12 +31700,18 @@ type ConfigureGoogleProviderResponseObject interface { VisitConfigureGoogleProviderResponse(w http.ResponseWriter) error } -type ConfigureGoogleProvider200Response struct { -} +type ConfigureGoogleProvider200JSONResponse AuthProvider -func (response ConfigureGoogleProvider200Response) VisitConfigureGoogleProviderResponse(w http.ResponseWriter) error { +func (response ConfigureGoogleProvider200JSONResponse) VisitConfigureGoogleProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type DisableApplicationAuthProviderRequestObject struct { @@ -25246,7 +31739,7 @@ type ListDisputesResponseObject interface { VisitListDisputesResponse(w http.ResponseWriter) error } -type ListDisputes200JSONResponse struct{ PageJSONResponse } +type ListDisputes200JSONResponse DisputePage func (response ListDisputes200JSONResponse) VisitListDisputesResponse(w http.ResponseWriter) error { @@ -25269,12 +31762,18 @@ type GetDisputeResponseObject interface { VisitGetDisputeResponse(w http.ResponseWriter) error } -type GetDispute200Response struct { -} +type GetDispute200JSONResponse Dispute -func (response GetDispute200Response) VisitGetDisputeResponse(w http.ResponseWriter) error { +func (response GetDispute200JSONResponse) VisitGetDisputeResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListInvoicesRequestObject struct { @@ -25285,7 +31784,7 @@ type ListInvoicesResponseObject interface { VisitListInvoicesResponse(w http.ResponseWriter) error } -type ListInvoices200JSONResponse struct{ PageJSONResponse } +type ListInvoices200JSONResponse InvoicePage func (response ListInvoices200JSONResponse) VisitListInvoicesResponse(w http.ResponseWriter) error { @@ -25308,12 +31807,18 @@ type GetInvoiceResponseObject interface { VisitGetInvoiceResponse(w http.ResponseWriter) error } -type GetInvoice200Response struct { -} +type GetInvoice200JSONResponse Invoice -func (response GetInvoice200Response) VisitGetInvoiceResponse(w http.ResponseWriter) error { +func (response GetInvoice200JSONResponse) VisitGetInvoiceResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListPaymentsRequestObject struct { @@ -25324,7 +31829,7 @@ type ListPaymentsResponseObject interface { VisitListPaymentsResponse(w http.ResponseWriter) error } -type ListPayments200JSONResponse struct{ PageJSONResponse } +type ListPayments200JSONResponse PaymentPage func (response ListPayments200JSONResponse) VisitListPaymentsResponse(w http.ResponseWriter) error { @@ -25347,12 +31852,18 @@ type GetPaymentResponseObject interface { VisitGetPaymentResponse(w http.ResponseWriter) error } -type GetPayment200Response struct { -} +type GetPayment200JSONResponse Payment -func (response GetPayment200Response) VisitGetPaymentResponse(w http.ResponseWriter) error { +func (response GetPayment200JSONResponse) VisitGetPaymentResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type CreateRefundRequestObject struct { @@ -25366,12 +31877,18 @@ type CreateRefundResponseObject interface { VisitCreateRefundResponse(w http.ResponseWriter) error } -type CreateRefund201Response struct { -} +type CreateRefund201JSONResponse Refund + +func (response CreateRefund201JSONResponse) VisitCreateRefundResponse(w http.ResponseWriter) error { -func (response CreateRefund201Response) VisitCreateRefundResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type ListBillingProviderEventsRequestObject struct { @@ -25382,7 +31899,7 @@ type ListBillingProviderEventsResponseObject interface { VisitListBillingProviderEventsResponse(w http.ResponseWriter) error } -type ListBillingProviderEvents200JSONResponse struct{ PageJSONResponse } +type ListBillingProviderEvents200JSONResponse BillingProviderEventPage func (response ListBillingProviderEvents200JSONResponse) VisitListBillingProviderEventsResponse(w http.ResponseWriter) error { @@ -25421,7 +31938,7 @@ type ListBillingProvidersResponseObject interface { VisitListBillingProvidersResponse(w http.ResponseWriter) error } -type ListBillingProviders200JSONResponse struct{ PageJSONResponse } +type ListBillingProviders200JSONResponse BillingProviderPage func (response ListBillingProviders200JSONResponse) VisitListBillingProvidersResponse(w http.ResponseWriter) error { @@ -25444,12 +31961,18 @@ type CreateBillingProviderResponseObject interface { VisitCreateBillingProviderResponse(w http.ResponseWriter) error } -type CreateBillingProvider201Response struct { -} +type CreateBillingProvider201JSONResponse BillingProvider + +func (response CreateBillingProvider201JSONResponse) VisitCreateBillingProviderResponse(w http.ResponseWriter) error { -func (response CreateBillingProvider201Response) VisitCreateBillingProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableBillingProviderRequestObject struct { @@ -25494,12 +32017,18 @@ type GetBillingProviderResponseObject interface { VisitGetBillingProviderResponse(w http.ResponseWriter) error } -type GetBillingProvider200Response struct { -} +type GetBillingProvider200JSONResponse BillingProvider + +func (response GetBillingProvider200JSONResponse) VisitGetBillingProviderResponse(w http.ResponseWriter) error { -func (response GetBillingProvider200Response) VisitGetBillingProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateBillingProviderRequestObject struct { @@ -25530,12 +32059,18 @@ type CreateBillingReconciliationRunResponseObject interface { VisitCreateBillingReconciliationRunResponse(w http.ResponseWriter) error } -type CreateBillingReconciliationRun202Response struct { -} +type CreateBillingReconciliationRun202JSONResponse ReconciliationAccepted + +func (response CreateBillingReconciliationRun202JSONResponse) VisitCreateBillingReconciliationRunResponse(w http.ResponseWriter) error { -func (response CreateBillingReconciliationRun202Response) VisitCreateBillingReconciliationRunResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(202) - return nil + _, err := buf.WriteTo(w) + return err } type VerifyBillingProviderRequestObject struct { @@ -25563,7 +32098,7 @@ type ListBillingReconciliationRunsResponseObject interface { VisitListBillingReconciliationRunsResponse(w http.ResponseWriter) error } -type ListBillingReconciliationRuns200JSONResponse struct{ PageJSONResponse } +type ListBillingReconciliationRuns200JSONResponse ReconciliationRunPage func (response ListBillingReconciliationRuns200JSONResponse) VisitListBillingReconciliationRunsResponse(w http.ResponseWriter) error { @@ -25586,12 +32121,18 @@ type GetBillingReconciliationRunResponseObject interface { VisitGetBillingReconciliationRunResponse(w http.ResponseWriter) error } -type GetBillingReconciliationRun200Response struct { -} +type GetBillingReconciliationRun200JSONResponse ReconciliationRun + +func (response GetBillingReconciliationRun200JSONResponse) VisitGetBillingReconciliationRunResponse(w http.ResponseWriter) error { -func (response GetBillingReconciliationRun200Response) VisitGetBillingReconciliationRunResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListRefundsRequestObject struct { @@ -25602,7 +32143,7 @@ type ListRefundsResponseObject interface { VisitListRefundsResponse(w http.ResponseWriter) error } -type ListRefunds200JSONResponse struct{ PageJSONResponse } +type ListRefunds200JSONResponse RefundPage func (response ListRefunds200JSONResponse) VisitListRefundsResponse(w http.ResponseWriter) error { @@ -25625,12 +32166,18 @@ type GetRefundResponseObject interface { VisitGetRefundResponse(w http.ResponseWriter) error } -type GetRefund200Response struct { -} +type GetRefund200JSONResponse Refund + +func (response GetRefund200JSONResponse) VisitGetRefundResponse(w http.ResponseWriter) error { -func (response GetRefund200Response) VisitGetRefundResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type GetBillingStatisticsRequestObject struct { @@ -25642,12 +32189,18 @@ type GetBillingStatisticsResponseObject interface { VisitGetBillingStatisticsResponse(w http.ResponseWriter) error } -type GetBillingStatistics200Response struct { -} +type GetBillingStatistics200JSONResponse BillingStatistics + +func (response GetBillingStatistics200JSONResponse) VisitGetBillingStatisticsResponse(w http.ResponseWriter) error { -func (response GetBillingStatistics200Response) VisitGetBillingStatisticsResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListSubscriptionsRequestObject struct { @@ -25658,7 +32211,7 @@ type ListSubscriptionsResponseObject interface { VisitListSubscriptionsResponse(w http.ResponseWriter) error } -type ListSubscriptions200JSONResponse struct{ PageJSONResponse } +type ListSubscriptions200JSONResponse SubscriptionPage func (response ListSubscriptions200JSONResponse) VisitListSubscriptionsResponse(w http.ResponseWriter) error { @@ -25681,12 +32234,18 @@ type GetSubscriptionResponseObject interface { VisitGetSubscriptionResponse(w http.ResponseWriter) error } -type GetSubscription200Response struct { -} +type GetSubscription200JSONResponse Subscription + +func (response GetSubscription200JSONResponse) VisitGetSubscriptionResponse(w http.ResponseWriter) error { -func (response GetSubscription200Response) VisitGetSubscriptionResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type CancelSubscriptionRequestObject struct { @@ -25719,12 +32278,18 @@ type ChangeSubscriptionPriceResponseObject interface { VisitChangeSubscriptionPriceResponse(w http.ResponseWriter) error } -type ChangeSubscriptionPrice200Response struct { -} +type ChangeSubscriptionPrice200JSONResponse Subscription + +func (response ChangeSubscriptionPrice200JSONResponse) VisitChangeSubscriptionPriceResponse(w http.ResponseWriter) error { -func (response ChangeSubscriptionPrice200Response) VisitChangeSubscriptionPriceResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ResumeSubscriptionRequestObject struct { @@ -25753,7 +32318,7 @@ type ListClientsResponseObject interface { VisitListClientsResponse(w http.ResponseWriter) error } -type ListClients200JSONResponse struct{ PageJSONResponse } +type ListClients200JSONResponse OAuthClientPage func (response ListClients200JSONResponse) VisitListClientsResponse(w http.ResponseWriter) error { @@ -25776,12 +32341,18 @@ type CreateClientResponseObject interface { VisitCreateClientResponse(w http.ResponseWriter) error } -type CreateClient201Response struct { -} +type CreateClient201JSONResponse OAuthClient + +func (response CreateClient201JSONResponse) VisitCreateClientResponse(w http.ResponseWriter) error { -func (response CreateClient201Response) VisitCreateClientResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableClientRequestObject struct { @@ -25801,6 +32372,29 @@ func (response DisableClient204Response) VisitDisableClientResponse(w http.Respo return nil } +type GetClientRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + ClientId string `json:"client_id"` +} + +type GetClientResponseObject interface { + VisitGetClientResponse(w http.ResponseWriter) error +} + +type GetClient200JSONResponse OAuthClient + +func (response GetClient200JSONResponse) VisitGetClientResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + type UpdateClientRequestObject struct { ApplicationId ApplicationID `json:"application_id"` ClientId string `json:"client_id"` @@ -25828,12 +32422,18 @@ type RotateClientSecretResponseObject interface { VisitRotateClientSecretResponse(w http.ResponseWriter) error } -type RotateClientSecret200Response struct { -} +type RotateClientSecret200JSONResponse SecretCredential -func (response RotateClientSecret200Response) VisitRotateClientSecretResponse(w http.ResponseWriter) error { +func (response RotateClientSecret200JSONResponse) VisitRotateClientSecretResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListDelegationsRequestObject struct { @@ -25844,7 +32444,7 @@ type ListDelegationsResponseObject interface { VisitListDelegationsResponse(w http.ResponseWriter) error } -type ListDelegations200JSONResponse struct{ PageJSONResponse } +type ListDelegations200JSONResponse DelegationPage func (response ListDelegations200JSONResponse) VisitListDelegationsResponse(w http.ResponseWriter) error { @@ -25867,12 +32467,18 @@ type CreateDelegationResponseObject interface { VisitCreateDelegationResponse(w http.ResponseWriter) error } -type CreateDelegation201Response struct { -} +type CreateDelegation201JSONResponse Delegation -func (response CreateDelegation201Response) VisitCreateDelegationResponse(w http.ResponseWriter) error { +func (response CreateDelegation201JSONResponse) VisitCreateDelegationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type GetDelegationRequestObject struct { @@ -25884,12 +32490,18 @@ type GetDelegationResponseObject interface { VisitGetDelegationResponse(w http.ResponseWriter) error } -type GetDelegation200Response struct { -} +type GetDelegation200JSONResponse Delegation -func (response GetDelegation200Response) VisitGetDelegationResponse(w http.ResponseWriter) error { +func (response GetDelegation200JSONResponse) VisitGetDelegationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type RevokeDelegationRequestObject struct { @@ -25917,7 +32529,7 @@ type ListApplicationDomainsResponseObject interface { VisitListApplicationDomainsResponse(w http.ResponseWriter) error } -type ListApplicationDomains200JSONResponse struct{ PageJSONResponse } +type ListApplicationDomains200JSONResponse ApplicationDomainPage func (response ListApplicationDomains200JSONResponse) VisitListApplicationDomainsResponse(w http.ResponseWriter) error { @@ -25940,12 +32552,18 @@ type CreateApplicationDomainResponseObject interface { VisitCreateApplicationDomainResponse(w http.ResponseWriter) error } -type CreateApplicationDomain201Response struct { -} +type CreateApplicationDomain201JSONResponse ApplicationDomain -func (response CreateApplicationDomain201Response) VisitCreateApplicationDomainResponse(w http.ResponseWriter) error { +func (response CreateApplicationDomain201JSONResponse) VisitCreateApplicationDomainResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DeleteApplicationDomainRequestObject struct { @@ -25990,7 +32608,7 @@ type ListEntitlementsResponseObject interface { VisitListEntitlementsResponse(w http.ResponseWriter) error } -type ListEntitlements200JSONResponse struct{ PageJSONResponse } +type ListEntitlements200JSONResponse EntitlementGrantPage func (response ListEntitlements200JSONResponse) VisitListEntitlementsResponse(w http.ResponseWriter) error { @@ -26013,12 +32631,18 @@ type CreateEntitlementResponseObject interface { VisitCreateEntitlementResponse(w http.ResponseWriter) error } -type CreateEntitlement201Response struct { -} +type CreateEntitlement201JSONResponse EntitlementGrant + +func (response CreateEntitlement201JSONResponse) VisitCreateEntitlementResponse(w http.ResponseWriter) error { -func (response CreateEntitlement201Response) VisitCreateEntitlementResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type GetEntitlementRequestObject struct { @@ -26030,11 +32654,35 @@ type GetEntitlementResponseObject interface { VisitGetEntitlementResponse(w http.ResponseWriter) error } -type GetEntitlement200Response struct { -} +type GetEntitlement200JSONResponse EntitlementGrant + +func (response GetEntitlement200JSONResponse) VisitGetEntitlementResponse(w http.ResponseWriter) error { -func (response GetEntitlement200Response) VisitGetEntitlementResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type AdjustEntitlementRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + EntitlementId UUID `json:"entitlement_id"` + Body *AdjustEntitlementJSONRequestBody +} + +type AdjustEntitlementResponseObject interface { + VisitAdjustEntitlementResponse(w http.ResponseWriter) error +} + +type AdjustEntitlement204Response struct { +} + +func (response AdjustEntitlement204Response) VisitAdjustEntitlementResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } @@ -26082,7 +32730,7 @@ type ListEventTypesResponseObject interface { VisitListEventTypesResponse(w http.ResponseWriter) error } -type ListEventTypes200JSONResponse struct{ PageJSONResponse } +type ListEventTypes200JSONResponse EventTypePage func (response ListEventTypes200JSONResponse) VisitListEventTypesResponse(w http.ResponseWriter) error { @@ -26105,12 +32753,18 @@ type CreateEventTypeResponseObject interface { VisitCreateEventTypeResponse(w http.ResponseWriter) error } -type CreateEventType201Response struct { -} +type CreateEventType201JSONResponse EventTypeDefinition + +func (response CreateEventType201JSONResponse) VisitCreateEventTypeResponse(w http.ResponseWriter) error { -func (response CreateEventType201Response) VisitCreateEventTypeResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type CreateEventType409ApplicationProblemPlusJSONResponse struct { @@ -26211,7 +32865,7 @@ type ListEventsResponseObject interface { VisitListEventsResponse(w http.ResponseWriter) error } -type ListEvents200JSONResponse struct{ PageJSONResponse } +type ListEvents200JSONResponse EventPage func (response ListEvents200JSONResponse) VisitListEventsResponse(w http.ResponseWriter) error { @@ -26256,7 +32910,7 @@ type ListFeaturesResponseObject interface { VisitListFeaturesResponse(w http.ResponseWriter) error } -type ListFeatures200JSONResponse struct{ PageJSONResponse } +type ListFeatures200JSONResponse FeaturePage func (response ListFeatures200JSONResponse) VisitListFeaturesResponse(w http.ResponseWriter) error { @@ -26279,12 +32933,18 @@ type CreateFeatureResponseObject interface { VisitCreateFeatureResponse(w http.ResponseWriter) error } -type CreateFeature201Response struct { -} +type CreateFeature201JSONResponse Feature + +func (response CreateFeature201JSONResponse) VisitCreateFeatureResponse(w http.ResponseWriter) error { -func (response CreateFeature201Response) VisitCreateFeatureResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type CreateFeature422ApplicationProblemPlusJSONResponse struct { @@ -26336,6 +32996,130 @@ func (response UpdateInternalApplicationConfig412ApplicationProblemPlusJSONRespo return err } +type ListApplicationInvitationsControlRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` +} + +type ListApplicationInvitationsControlResponseObject interface { + VisitListApplicationInvitationsControlResponse(w http.ResponseWriter) error +} + +type ListApplicationInvitationsControl200JSONResponse ApplicationInvitationPage + +func (response ListApplicationInvitationsControl200JSONResponse) VisitListApplicationInvitationsControlResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type CreateApplicationInvitationControlRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Body *CreateApplicationInvitationControlJSONRequestBody +} + +type CreateApplicationInvitationControlResponseObject interface { + VisitCreateApplicationInvitationControlResponse(w http.ResponseWriter) error +} + +type CreateApplicationInvitationControl201JSONResponse ApplicationInvitation + +func (response CreateApplicationInvitationControl201JSONResponse) VisitCreateApplicationInvitationControlResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type RevokeApplicationInvitationControlRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + InvitationId UUID `json:"invitation_id"` +} + +type RevokeApplicationInvitationControlResponseObject interface { + VisitRevokeApplicationInvitationControlResponse(w http.ResponseWriter) error +} + +type RevokeApplicationInvitationControl204Response struct { +} + +func (response RevokeApplicationInvitationControl204Response) VisitRevokeApplicationInvitationControlResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type GetApplicationInvitationControlRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + InvitationId UUID `json:"invitation_id"` +} + +type GetApplicationInvitationControlResponseObject interface { + VisitGetApplicationInvitationControlResponse(w http.ResponseWriter) error +} + +type GetApplicationInvitationControl200JSONResponse ApplicationInvitation + +func (response GetApplicationInvitationControl200JSONResponse) VisitGetApplicationInvitationControlResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type ResendApplicationInvitationControlRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + InvitationId UUID `json:"invitation_id"` +} + +type ResendApplicationInvitationControlResponseObject interface { + VisitResendApplicationInvitationControlResponse(w http.ResponseWriter) error +} + +type ResendApplicationInvitationControl202JSONResponse InvitationResent + +func (response ResendApplicationInvitationControl202JSONResponse) VisitResendApplicationInvitationControlResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) + _, err := buf.WriteTo(w) + return err +} + +type ResendApplicationInvitationControl429ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response ResendApplicationInvitationControl429ApplicationProblemPlusJSONResponse) VisitResendApplicationInvitationControlResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(429) + _, err := buf.WriteTo(w) + return err +} + type ListLocalEntitlementRequestsRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } @@ -26344,7 +33128,7 @@ type ListLocalEntitlementRequestsResponseObject interface { VisitListLocalEntitlementRequestsResponse(w http.ResponseWriter) error } -type ListLocalEntitlementRequests200JSONResponse struct{ PageJSONResponse } +type ListLocalEntitlementRequests200JSONResponse LocalEntitlementRequestPage func (response ListLocalEntitlementRequests200JSONResponse) VisitListLocalEntitlementRequestsResponse(w http.ResponseWriter) error { @@ -26367,12 +33151,18 @@ type GetLocalEntitlementRequestResponseObject interface { VisitGetLocalEntitlementRequestResponse(w http.ResponseWriter) error } -type GetLocalEntitlementRequest200Response struct { -} +type GetLocalEntitlementRequest200JSONResponse LocalEntitlementRequest + +func (response GetLocalEntitlementRequest200JSONResponse) VisitGetLocalEntitlementRequestResponse(w http.ResponseWriter) error { -func (response GetLocalEntitlementRequest200Response) VisitGetLocalEntitlementRequestResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ApproveLocalEntitlementRequestRequestObject struct { @@ -26385,12 +33175,18 @@ type ApproveLocalEntitlementRequestResponseObject interface { VisitApproveLocalEntitlementRequestResponse(w http.ResponseWriter) error } -type ApproveLocalEntitlementRequest200Response struct { -} +type ApproveLocalEntitlementRequest200JSONResponse LocalEntitlementApproval + +func (response ApproveLocalEntitlementRequest200JSONResponse) VisitApproveLocalEntitlementRequestResponse(w http.ResponseWriter) error { -func (response ApproveLocalEntitlementRequest200Response) VisitApproveLocalEntitlementRequestResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type RejectLocalEntitlementRequestRequestObject struct { @@ -26437,7 +33233,7 @@ type ListNotificationProvidersResponseObject interface { VisitListNotificationProvidersResponse(w http.ResponseWriter) error } -type ListNotificationProviders200JSONResponse struct{ PageJSONResponse } +type ListNotificationProviders200JSONResponse NotificationProviderPage func (response ListNotificationProviders200JSONResponse) VisitListNotificationProvidersResponse(w http.ResponseWriter) error { @@ -26460,12 +33256,18 @@ type CreateNotificationProviderResponseObject interface { VisitCreateNotificationProviderResponse(w http.ResponseWriter) error } -type CreateNotificationProvider201Response struct { -} +type CreateNotificationProvider201JSONResponse NotificationProvider + +func (response CreateNotificationProvider201JSONResponse) VisitCreateNotificationProviderResponse(w http.ResponseWriter) error { -func (response CreateNotificationProvider201Response) VisitCreateNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableNotificationProviderRequestObject struct { @@ -26494,12 +33296,18 @@ type GetNotificationProviderResponseObject interface { VisitGetNotificationProviderResponse(w http.ResponseWriter) error } -type GetNotificationProvider200Response struct { -} +type GetNotificationProvider200JSONResponse NotificationProvider + +func (response GetNotificationProvider200JSONResponse) VisitGetNotificationProviderResponse(w http.ResponseWriter) error { -func (response GetNotificationProvider200Response) VisitGetNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateNotificationProviderRequestObject struct { @@ -26512,12 +33320,18 @@ type UpdateNotificationProviderResponseObject interface { VisitUpdateNotificationProviderResponse(w http.ResponseWriter) error } -type UpdateNotificationProvider200Response struct { -} +type UpdateNotificationProvider200JSONResponse NotificationProvider + +func (response UpdateNotificationProvider200JSONResponse) VisitUpdateNotificationProviderResponse(w http.ResponseWriter) error { -func (response UpdateNotificationProvider200Response) VisitUpdateNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type TestNotificationProviderRequestObject struct { @@ -26531,12 +33345,18 @@ type TestNotificationProviderResponseObject interface { VisitTestNotificationProviderResponse(w http.ResponseWriter) error } -type TestNotificationProvider202Response struct { -} +type TestNotificationProvider202JSONResponse NotificationQueued + +func (response TestNotificationProvider202JSONResponse) VisitTestNotificationProviderResponse(w http.ResponseWriter) error { -func (response TestNotificationProvider202Response) VisitTestNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(202) - return nil + _, err := buf.WriteTo(w) + return err } type VerifyNotificationProviderRequestObject struct { @@ -26580,12 +33400,18 @@ type ListNotificationTemplateVariablesResponseObject interface { VisitListNotificationTemplateVariablesResponse(w http.ResponseWriter) error } -type ListNotificationTemplateVariables200Response struct { -} +type ListNotificationTemplateVariables200JSONResponse TemplateVariables -func (response ListNotificationTemplateVariables200Response) VisitListNotificationTemplateVariablesResponse(w http.ResponseWriter) error { +func (response ListNotificationTemplateVariables200JSONResponse) VisitListNotificationTemplateVariablesResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListNotificationTemplatesRequestObject struct { @@ -26596,7 +33422,7 @@ type ListNotificationTemplatesResponseObject interface { VisitListNotificationTemplatesResponse(w http.ResponseWriter) error } -type ListNotificationTemplates200JSONResponse struct{ PageJSONResponse } +type ListNotificationTemplates200JSONResponse NotificationTemplatePage func (response ListNotificationTemplates200JSONResponse) VisitListNotificationTemplatesResponse(w http.ResponseWriter) error { @@ -26619,12 +33445,18 @@ type CreateNotificationTemplateResponseObject interface { VisitCreateNotificationTemplateResponse(w http.ResponseWriter) error } -type CreateNotificationTemplate201Response struct { -} +type CreateNotificationTemplate201JSONResponse NotificationTemplate + +func (response CreateNotificationTemplate201JSONResponse) VisitCreateNotificationTemplateResponse(w http.ResponseWriter) error { -func (response CreateNotificationTemplate201Response) VisitCreateNotificationTemplateResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type GetNotificationTemplateRequestObject struct { @@ -26636,12 +33468,18 @@ type GetNotificationTemplateResponseObject interface { VisitGetNotificationTemplateResponse(w http.ResponseWriter) error } -type GetNotificationTemplate200Response struct { -} +type GetNotificationTemplate200JSONResponse NotificationTemplate -func (response GetNotificationTemplate200Response) VisitGetNotificationTemplateResponse(w http.ResponseWriter) error { +func (response GetNotificationTemplate200JSONResponse) VisitGetNotificationTemplateResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateNotificationTemplateRequestObject struct { @@ -26654,12 +33492,18 @@ type UpdateNotificationTemplateResponseObject interface { VisitUpdateNotificationTemplateResponse(w http.ResponseWriter) error } -type UpdateNotificationTemplate201Response struct { -} +type UpdateNotificationTemplate201JSONResponse NotificationTemplate + +func (response UpdateNotificationTemplate201JSONResponse) VisitUpdateNotificationTemplateResponse(w http.ResponseWriter) error { -func (response UpdateNotificationTemplate201Response) VisitUpdateNotificationTemplateResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type ArchiveNotificationTemplateRequestObject struct { @@ -26689,12 +33533,18 @@ type PreviewNotificationTemplateResponseObject interface { VisitPreviewNotificationTemplateResponse(w http.ResponseWriter) error } -type PreviewNotificationTemplate200Response struct { -} +type PreviewNotificationTemplate200JSONResponse NotificationTemplatePreview -func (response PreviewNotificationTemplate200Response) VisitPreviewNotificationTemplateResponse(w http.ResponseWriter) error { +func (response PreviewNotificationTemplate200JSONResponse) VisitPreviewNotificationTemplateResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type PublishNotificationTemplateRequestObject struct { @@ -26722,7 +33572,7 @@ type ListNotificationsResponseObject interface { VisitListNotificationsResponse(w http.ResponseWriter) error } -type ListNotifications200JSONResponse struct{ PageJSONResponse } +type ListNotifications200JSONResponse NotificationPage func (response ListNotifications200JSONResponse) VisitListNotificationsResponse(w http.ResponseWriter) error { @@ -26736,118 +33586,249 @@ func (response ListNotifications200JSONResponse) VisitListNotificationsResponse( return err } -type QueueNotificationRequestObject struct { +type GetNotificationStatisticsRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` +} + +type GetNotificationStatisticsResponseObject interface { + VisitGetNotificationStatisticsResponse(w http.ResponseWriter) error +} + +type GetNotificationStatistics200JSONResponse NotificationStatistics + +func (response GetNotificationStatistics200JSONResponse) VisitGetNotificationStatisticsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type GetNotificationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + NotificationId UUID `json:"notification_id"` +} + +type GetNotificationResponseObject interface { + VisitGetNotificationResponse(w http.ResponseWriter) error +} + +type GetNotification200JSONResponse Notification + +func (response GetNotification200JSONResponse) VisitGetNotificationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type RetryNotificationRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + NotificationId UUID `json:"notification_id"` +} + +type RetryNotificationResponseObject interface { + VisitRetryNotificationResponse(w http.ResponseWriter) error +} + +type RetryNotification204Response struct { +} + +func (response RetryNotification204Response) VisitRetryNotificationResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type ListOAuthConsentsRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` +} + +type ListOAuthConsentsResponseObject interface { + VisitListOAuthConsentsResponse(w http.ResponseWriter) error +} + +type ListOAuthConsents200JSONResponse OAuthConsentPage + +func (response ListOAuthConsents200JSONResponse) VisitListOAuthConsentsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type RevokeOAuthConsentRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + UserId UUID `json:"user_id"` + ClientId UUID `json:"client_id"` +} + +type RevokeOAuthConsentResponseObject interface { + VisitRevokeOAuthConsentResponse(w http.ResponseWriter) error +} + +type RevokeOAuthConsent204Response struct { +} + +func (response RevokeOAuthConsent204Response) VisitRevokeOAuthConsentResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type ListControlPermissionGrantsRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Params ListControlPermissionGrantsParams +} + +type ListControlPermissionGrantsResponseObject interface { + VisitListControlPermissionGrantsResponse(w http.ResponseWriter) error +} + +type ListControlPermissionGrants200JSONResponse PermissionGrantPage + +func (response ListControlPermissionGrants200JSONResponse) VisitListControlPermissionGrantsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type CreateControlPermissionGrantRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - Params QueueNotificationParams - Body *QueueNotificationJSONRequestBody + Params CreateControlPermissionGrantParams + Body *CreateControlPermissionGrantJSONRequestBody } -type QueueNotificationResponseObject interface { - VisitQueueNotificationResponse(w http.ResponseWriter) error +type CreateControlPermissionGrantResponseObject interface { + VisitCreateControlPermissionGrantResponse(w http.ResponseWriter) error } -type QueueNotification202JSONResponse QueuedNotification +type CreateControlPermissionGrant201JSONResponse PermissionGrant -func (response QueueNotification202JSONResponse) VisitQueueNotificationResponse(w http.ResponseWriter) error { +func (response CreateControlPermissionGrant201JSONResponse) VisitCreateControlPermissionGrantResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } w.Header().Set("Content-Type", "application/json") - w.WriteHeader(202) + w.WriteHeader(201) _, err := buf.WriteTo(w) return err } -type GetNotificationStatisticsRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` +type CreateControlPermissionGrant422ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type GetNotificationStatisticsResponseObject interface { - VisitGetNotificationStatisticsResponse(w http.ResponseWriter) error -} +func (response CreateControlPermissionGrant422ApplicationProblemPlusJSONResponse) VisitCreateControlPermissionGrantResponse(w http.ResponseWriter) error { -type GetNotificationStatistics200Response struct { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(422) + _, err := buf.WriteTo(w) + return err } -func (response GetNotificationStatistics200Response) VisitGetNotificationStatisticsResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil +type GetControlEffectiveAccessRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + Params GetControlEffectiveAccessParams } -type GetNotificationRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - NotificationId UUID `json:"notification_id"` +type GetControlEffectiveAccessResponseObject interface { + VisitGetControlEffectiveAccessResponse(w http.ResponseWriter) error } -type GetNotificationResponseObject interface { - VisitGetNotificationResponse(w http.ResponseWriter) error -} +type GetControlEffectiveAccess200JSONResponse EffectiveAccess -type GetNotification200Response struct { -} +func (response GetControlEffectiveAccess200JSONResponse) VisitGetControlEffectiveAccessResponse(w http.ResponseWriter) error { -func (response GetNotification200Response) VisitGetNotificationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type RetryNotificationRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - NotificationId UUID `json:"notification_id"` +type RevokeControlPermissionGrantRequestObject struct { + ApplicationId ApplicationID `json:"application_id"` + GrantId UUID `json:"grant_id"` + Params RevokeControlPermissionGrantParams } -type RetryNotificationResponseObject interface { - VisitRetryNotificationResponse(w http.ResponseWriter) error +type RevokeControlPermissionGrantResponseObject interface { + VisitRevokeControlPermissionGrantResponse(w http.ResponseWriter) error } -type RetryNotification204Response struct { +type RevokeControlPermissionGrant204Response struct { } -func (response RetryNotification204Response) VisitRetryNotificationResponse(w http.ResponseWriter) error { +func (response RevokeControlPermissionGrant204Response) VisitRevokeControlPermissionGrantResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type ListOAuthConsentsRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` -} - -type ListOAuthConsentsResponseObject interface { - VisitListOAuthConsentsResponse(w http.ResponseWriter) error +type RevokeControlPermissionGrant409ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type ListOAuthConsents200JSONResponse struct{ PageJSONResponse } - -func (response ListOAuthConsents200JSONResponse) VisitListOAuthConsentsResponse(w http.ResponseWriter) error { +func (response RevokeControlPermissionGrant409ApplicationProblemPlusJSONResponse) VisitRevokeControlPermissionGrantResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(409) _, err := buf.WriteTo(w) return err } -type RevokeOAuthConsentRequestObject struct { +type GetControlPermissionGrantRequestObject struct { ApplicationId ApplicationID `json:"application_id"` - UserId UUID `json:"user_id"` - ClientId UUID `json:"client_id"` + GrantId UUID `json:"grant_id"` } -type RevokeOAuthConsentResponseObject interface { - VisitRevokeOAuthConsentResponse(w http.ResponseWriter) error +type GetControlPermissionGrantResponseObject interface { + VisitGetControlPermissionGrantResponse(w http.ResponseWriter) error } -type RevokeOAuthConsent204Response struct { -} +type GetControlPermissionGrant200JSONResponse PermissionGrant -func (response RevokeOAuthConsent204Response) VisitRevokeOAuthConsentResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil +func (response GetControlPermissionGrant200JSONResponse) VisitGetControlPermissionGrantResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err } type ListProductsRequestObject struct { @@ -26858,7 +33839,7 @@ type ListProductsResponseObject interface { VisitListProductsResponse(w http.ResponseWriter) error } -type ListProducts200JSONResponse struct{ PageJSONResponse } +type ListProducts200JSONResponse ProductPage func (response ListProducts200JSONResponse) VisitListProductsResponse(w http.ResponseWriter) error { @@ -26881,12 +33862,18 @@ type CreateProductResponseObject interface { VisitCreateProductResponse(w http.ResponseWriter) error } -type CreateProduct201Response struct { -} +type CreateProduct201JSONResponse Product + +func (response CreateProduct201JSONResponse) VisitCreateProductResponse(w http.ResponseWriter) error { -func (response CreateProduct201Response) VisitCreateProductResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type GetProductRequestObject struct { @@ -26898,12 +33885,18 @@ type GetProductResponseObject interface { VisitGetProductResponse(w http.ResponseWriter) error } -type GetProduct200Response struct { -} +type GetProduct200JSONResponse Product -func (response GetProduct200Response) VisitGetProductResponse(w http.ResponseWriter) error { +func (response GetProduct200JSONResponse) VisitGetProductResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateProductRequestObject struct { @@ -26933,7 +33926,7 @@ type ListPricesResponseObject interface { VisitListPricesResponse(w http.ResponseWriter) error } -type ListPrices200JSONResponse struct{ PageJSONResponse } +type ListPrices200JSONResponse PricePage func (response ListPrices200JSONResponse) VisitListPricesResponse(w http.ResponseWriter) error { @@ -26957,12 +33950,18 @@ type CreatePriceResponseObject interface { VisitCreatePriceResponse(w http.ResponseWriter) error } -type CreatePrice201Response struct { -} +type CreatePrice201JSONResponse Price + +func (response CreatePrice201JSONResponse) VisitCreatePriceResponse(w http.ResponseWriter) error { -func (response CreatePrice201Response) VisitCreatePriceResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type UpdatePublicApplicationConfigRequestObject struct { @@ -27006,7 +34005,7 @@ type ListRoleAssignmentsResponseObject interface { VisitListRoleAssignmentsResponse(w http.ResponseWriter) error } -type ListRoleAssignments200JSONResponse struct{ PageJSONResponse } +type ListRoleAssignments200JSONResponse RoleAssignmentPage func (response ListRoleAssignments200JSONResponse) VisitListRoleAssignmentsResponse(w http.ResponseWriter) error { @@ -27029,12 +34028,18 @@ type CreateRoleAssignmentResponseObject interface { VisitCreateRoleAssignmentResponse(w http.ResponseWriter) error } -type CreateRoleAssignment201Response struct { -} +type CreateRoleAssignment201JSONResponse RoleAssignmentRecord -func (response CreateRoleAssignment201Response) VisitCreateRoleAssignmentResponse(w http.ResponseWriter) error { +func (response CreateRoleAssignment201JSONResponse) VisitCreateRoleAssignmentResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DeleteRoleAssignmentRequestObject struct { @@ -27062,7 +34067,7 @@ type ListRolesResponseObject interface { VisitListRolesResponse(w http.ResponseWriter) error } -type ListRoles200JSONResponse struct{ PageJSONResponse } +type ListRoles200JSONResponse RolePage func (response ListRoles200JSONResponse) VisitListRolesResponse(w http.ResponseWriter) error { @@ -27085,12 +34090,34 @@ type CreateRoleResponseObject interface { VisitCreateRoleResponse(w http.ResponseWriter) error } -type CreateRole201Response struct { -} +type CreateRole201JSONResponse Role + +func (response CreateRole201JSONResponse) VisitCreateRoleResponse(w http.ResponseWriter) error { -func (response CreateRole201Response) VisitCreateRoleResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err +} + +type CreateRole422ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response CreateRole422ApplicationProblemPlusJSONResponse) VisitCreateRoleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(422) + _, err := buf.WriteTo(w) + return err } type DeleteRoleRequestObject struct { @@ -27135,12 +34162,18 @@ type GetRoleResponseObject interface { VisitGetRoleResponse(w http.ResponseWriter) error } -type GetRole200Response struct { -} +type GetRole200JSONResponse Role -func (response GetRole200Response) VisitGetRoleResponse(w http.ResponseWriter) error { +func (response GetRole200JSONResponse) VisitGetRoleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type GetRole404ApplicationProblemPlusJSONResponse struct { @@ -27162,6 +34195,7 @@ func (response GetRole404ApplicationProblemPlusJSONResponse) VisitGetRoleRespons type UpdateRoleRequestObject struct { ApplicationId ApplicationID `json:"application_id"` RoleId UUID `json:"role_id"` + Params UpdateRoleParams Body *UpdateRoleJSONRequestBody } @@ -27193,6 +34227,20 @@ func (response UpdateRole409ApplicationProblemPlusJSONResponse) VisitUpdateRoleR return err } +type UpdateRole422ApplicationProblemPlusJSONResponse Problem + +func (response UpdateRole422ApplicationProblemPlusJSONResponse) VisitUpdateRoleResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(422) + _, err := buf.WriteTo(w) + return err +} + type ListSenderIdentitiesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } @@ -27201,7 +34249,7 @@ type ListSenderIdentitiesResponseObject interface { VisitListSenderIdentitiesResponse(w http.ResponseWriter) error } -type ListSenderIdentities200JSONResponse struct{ PageJSONResponse } +type ListSenderIdentities200JSONResponse SenderIdentityPage func (response ListSenderIdentities200JSONResponse) VisitListSenderIdentitiesResponse(w http.ResponseWriter) error { @@ -27224,12 +34272,18 @@ type CreateSenderIdentityResponseObject interface { VisitCreateSenderIdentityResponse(w http.ResponseWriter) error } -type CreateSenderIdentity201Response struct { -} +type CreateSenderIdentity201JSONResponse SenderIdentity + +func (response CreateSenderIdentity201JSONResponse) VisitCreateSenderIdentityResponse(w http.ResponseWriter) error { -func (response CreateSenderIdentity201Response) VisitCreateSenderIdentityResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type SetDefaultSenderIdentityRequestObject struct { @@ -27257,12 +34311,18 @@ type GetApplicationStatisticsResponseObject interface { VisitGetApplicationStatisticsResponse(w http.ResponseWriter) error } -type GetApplicationStatistics200Response struct { -} +type GetApplicationStatistics200JSONResponse ApplicationStatistics -func (response GetApplicationStatistics200Response) VisitGetApplicationStatisticsResponse(w http.ResponseWriter) error { +func (response GetApplicationStatistics200JSONResponse) VisitGetApplicationStatisticsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListControlApplicationStorageObjectsRequestObject struct { @@ -27273,7 +34333,7 @@ type ListControlApplicationStorageObjectsResponseObject interface { VisitListControlApplicationStorageObjectsResponse(w http.ResponseWriter) error } -type ListControlApplicationStorageObjects200JSONResponse struct{ PageJSONResponse } +type ListControlApplicationStorageObjects200JSONResponse StorageObjectPage func (response ListControlApplicationStorageObjects200JSONResponse) VisitListControlApplicationStorageObjectsResponse(w http.ResponseWriter) error { @@ -27314,12 +34374,18 @@ type GetControlApplicationStorageObjectResponseObject interface { VisitGetControlApplicationStorageObjectResponse(w http.ResponseWriter) error } -type GetControlApplicationStorageObject200Response struct { -} +type GetControlApplicationStorageObject200JSONResponse StorageObject + +func (response GetControlApplicationStorageObject200JSONResponse) VisitGetControlApplicationStorageObjectResponse(w http.ResponseWriter) error { -func (response GetControlApplicationStorageObject200Response) VisitGetControlApplicationStorageObjectResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type DownloadControlApplicationStorageObjectRequestObject struct { @@ -27331,12 +34397,18 @@ type DownloadControlApplicationStorageObjectResponseObject interface { VisitDownloadControlApplicationStorageObjectResponse(w http.ResponseWriter) error } -type DownloadControlApplicationStorageObject200Response struct { -} +type DownloadControlApplicationStorageObject200JSONResponse StorageDownload -func (response DownloadControlApplicationStorageObject200Response) VisitDownloadControlApplicationStorageObjectResponse(w http.ResponseWriter) error { +func (response DownloadControlApplicationStorageObject200JSONResponse) VisitDownloadControlApplicationStorageObjectResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListApplicationStorageProvidersRequestObject struct { @@ -27347,7 +34419,7 @@ type ListApplicationStorageProvidersResponseObject interface { VisitListApplicationStorageProvidersResponse(w http.ResponseWriter) error } -type ListApplicationStorageProviders200JSONResponse struct{ PageJSONResponse } +type ListApplicationStorageProviders200JSONResponse StorageProviderPage func (response ListApplicationStorageProviders200JSONResponse) VisitListApplicationStorageProvidersResponse(w http.ResponseWriter) error { @@ -27370,12 +34442,18 @@ type CreateApplicationStorageProviderResponseObject interface { VisitCreateApplicationStorageProviderResponse(w http.ResponseWriter) error } -type CreateApplicationStorageProvider201Response struct { -} +type CreateApplicationStorageProvider201JSONResponse StorageProvider + +func (response CreateApplicationStorageProvider201JSONResponse) VisitCreateApplicationStorageProviderResponse(w http.ResponseWriter) error { -func (response CreateApplicationStorageProvider201Response) VisitCreateApplicationStorageProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableApplicationStorageProviderRequestObject struct { @@ -27421,12 +34499,18 @@ type GetApplicationStorageProviderResponseObject interface { VisitGetApplicationStorageProviderResponse(w http.ResponseWriter) error } -type GetApplicationStorageProvider200Response struct { -} +type GetApplicationStorageProvider200JSONResponse StorageProvider + +func (response GetApplicationStorageProvider200JSONResponse) VisitGetApplicationStorageProviderResponse(w http.ResponseWriter) error { -func (response GetApplicationStorageProvider200Response) VisitGetApplicationStorageProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateApplicationStorageProviderRequestObject struct { @@ -27439,12 +34523,18 @@ type UpdateApplicationStorageProviderResponseObject interface { VisitUpdateApplicationStorageProviderResponse(w http.ResponseWriter) error } -type UpdateApplicationStorageProvider200Response struct { -} +type UpdateApplicationStorageProvider200JSONResponse StorageProvider -func (response UpdateApplicationStorageProvider200Response) VisitUpdateApplicationStorageProviderResponse(w http.ResponseWriter) error { +func (response UpdateApplicationStorageProvider200JSONResponse) VisitUpdateApplicationStorageProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type EnableApplicationStorageProviderRequestObject struct { @@ -27456,12 +34546,18 @@ type EnableApplicationStorageProviderResponseObject interface { VisitEnableApplicationStorageProviderResponse(w http.ResponseWriter) error } -type EnableApplicationStorageProvider200Response struct { -} +type EnableApplicationStorageProvider200JSONResponse StorageProviderStatus + +func (response EnableApplicationStorageProvider200JSONResponse) VisitEnableApplicationStorageProviderResponse(w http.ResponseWriter) error { -func (response EnableApplicationStorageProvider200Response) VisitEnableApplicationStorageProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type VerifyApplicationStorageProviderRequestObject struct { @@ -27491,12 +34587,18 @@ type CreateControlApplicationStorageUploadResponseObject interface { VisitCreateControlApplicationStorageUploadResponse(w http.ResponseWriter) error } -type CreateControlApplicationStorageUpload201Response struct { -} +type CreateControlApplicationStorageUpload201JSONResponse StorageUploadAuthorization -func (response CreateControlApplicationStorageUpload201Response) VisitCreateControlApplicationStorageUploadResponse(w http.ResponseWriter) error { +func (response CreateControlApplicationStorageUpload201JSONResponse) VisitCreateControlApplicationStorageUploadResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type CompleteControlApplicationStorageUploadRequestObject struct { @@ -27508,12 +34610,18 @@ type CompleteControlApplicationStorageUploadResponseObject interface { VisitCompleteControlApplicationStorageUploadResponse(w http.ResponseWriter) error } -type CompleteControlApplicationStorageUpload200Response struct { -} +type CompleteControlApplicationStorageUpload200JSONResponse StorageObject + +func (response CompleteControlApplicationStorageUpload200JSONResponse) VisitCompleteControlApplicationStorageUploadResponse(w http.ResponseWriter) error { -func (response CompleteControlApplicationStorageUpload200Response) VisitCompleteControlApplicationStorageUploadResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListUsersRequestObject struct { @@ -27524,7 +34632,7 @@ type ListUsersResponseObject interface { VisitListUsersResponse(w http.ResponseWriter) error } -type ListUsers200JSONResponse struct{ PageJSONResponse } +type ListUsers200JSONResponse UserPage func (response ListUsers200JSONResponse) VisitListUsersResponse(w http.ResponseWriter) error { @@ -27547,12 +34655,18 @@ type CreateUserResponseObject interface { VisitCreateUserResponse(w http.ResponseWriter) error } -type CreateUser201Response struct { -} +type CreateUser201JSONResponse User -func (response CreateUser201Response) VisitCreateUserResponse(w http.ResponseWriter) error { +func (response CreateUser201JSONResponse) VisitCreateUserResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type GetUserRequestObject struct { @@ -27564,12 +34678,18 @@ type GetUserResponseObject interface { VisitGetUserResponse(w http.ResponseWriter) error } -type GetUser200Response struct { -} +type GetUser200JSONResponse User + +func (response GetUser200JSONResponse) VisitGetUserResponse(w http.ResponseWriter) error { -func (response GetUser200Response) VisitGetUserResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateUserRequestObject struct { @@ -27599,7 +34719,7 @@ type ListUserAddressesResponseObject interface { VisitListUserAddressesResponse(w http.ResponseWriter) error } -type ListUserAddresses200JSONResponse struct{ PageJSONResponse } +type ListUserAddresses200JSONResponse AddressPage func (response ListUserAddresses200JSONResponse) VisitListUserAddressesResponse(w http.ResponseWriter) error { @@ -27640,7 +34760,7 @@ type ListUserSessionsResponseObject interface { VisitListUserSessionsResponse(w http.ResponseWriter) error } -type ListUserSessions200JSONResponse struct{ PageJSONResponse } +type ListUserSessions200JSONResponse SessionPage func (response ListUserSessions200JSONResponse) VisitListUserSessionsResponse(w http.ResponseWriter) error { @@ -27663,12 +34783,18 @@ type RevokeUserSessionsResponseObject interface { VisitRevokeUserSessionsResponse(w http.ResponseWriter) error } -type RevokeUserSessions200Response struct { -} +type RevokeUserSessions200JSONResponse RevokedSessionCount -func (response RevokeUserSessions200Response) VisitRevokeUserSessionsResponse(w http.ResponseWriter) error { +func (response RevokeUserSessions200JSONResponse) VisitRevokeUserSessionsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type SuspendUserRequestObject struct { @@ -27769,7 +34895,7 @@ type ListWebhookDeliveriesResponseObject interface { VisitListWebhookDeliveriesResponse(w http.ResponseWriter) error } -type ListWebhookDeliveries200JSONResponse struct{ PageJSONResponse } +type ListWebhookDeliveries200JSONResponse WebhookDeliveryPage func (response ListWebhookDeliveries200JSONResponse) VisitListWebhookDeliveriesResponse(w http.ResponseWriter) error { @@ -27792,12 +34918,18 @@ type GetWebhookDeliveryResponseObject interface { VisitGetWebhookDeliveryResponse(w http.ResponseWriter) error } -type GetWebhookDelivery200Response struct { -} +type GetWebhookDelivery200JSONResponse WebhookDelivery + +func (response GetWebhookDelivery200JSONResponse) VisitGetWebhookDeliveryResponse(w http.ResponseWriter) error { -func (response GetWebhookDelivery200Response) VisitGetWebhookDeliveryResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type GetWebhookDelivery404ApplicationProblemPlusJSONResponse struct { @@ -27841,7 +34973,7 @@ type ListWebhooksResponseObject interface { VisitListWebhooksResponse(w http.ResponseWriter) error } -type ListWebhooks200JSONResponse struct{ PageJSONResponse } +type ListWebhooks200JSONResponse WebhookPage func (response ListWebhooks200JSONResponse) VisitListWebhooksResponse(w http.ResponseWriter) error { @@ -27864,12 +34996,18 @@ type CreateWebhookResponseObject interface { VisitCreateWebhookResponse(w http.ResponseWriter) error } -type CreateWebhook201Response struct { -} +type CreateWebhook201JSONResponse Webhook + +func (response CreateWebhook201JSONResponse) VisitCreateWebhookResponse(w http.ResponseWriter) error { -func (response CreateWebhook201Response) VisitCreateWebhookResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableWebhookRequestObject struct { @@ -27898,12 +35036,18 @@ type GetWebhookResponseObject interface { VisitGetWebhookResponse(w http.ResponseWriter) error } -type GetWebhook200Response struct { -} +type GetWebhook200JSONResponse Webhook + +func (response GetWebhook200JSONResponse) VisitGetWebhookResponse(w http.ResponseWriter) error { -func (response GetWebhook200Response) VisitGetWebhookResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type GetWebhook404ApplicationProblemPlusJSONResponse struct { @@ -27965,12 +35109,18 @@ type RotateWebhookSecretResponseObject interface { VisitRotateWebhookSecretResponse(w http.ResponseWriter) error } -type RotateWebhookSecret200Response struct { -} +type RotateWebhookSecret200JSONResponse SecretCredential + +func (response RotateWebhookSecret200JSONResponse) VisitRotateWebhookSecretResponse(w http.ResponseWriter) error { -func (response RotateWebhookSecret200Response) VisitRotateWebhookSecretResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type TestWebhookRequestObject struct { @@ -27983,86 +35133,36 @@ type TestWebhookResponseObject interface { VisitTestWebhookResponse(w http.ResponseWriter) error } -type TestWebhook202Response struct { -} - -func (response TestWebhook202Response) VisitTestWebhookResponse(w http.ResponseWriter) error { - w.WriteHeader(202) - return nil -} - -type TestWebhook404ApplicationProblemPlusJSONResponse struct { - ProblemApplicationProblemPlusJSONResponse -} +type TestWebhook202JSONResponse WebhookTestAccepted -func (response TestWebhook404ApplicationProblemPlusJSONResponse) VisitTestWebhookResponse(w http.ResponseWriter) error { +func (response TestWebhook202JSONResponse) VisitTestWebhookResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/problem+json") - w.WriteHeader(404) + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(202) _, err := buf.WriteTo(w) return err } -type ListWorkspaceInvitationsRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` -} - -type ListWorkspaceInvitationsResponseObject interface { - VisitListWorkspaceInvitationsResponse(w http.ResponseWriter) error +type TestWebhook404ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type ListWorkspaceInvitations200JSONResponse struct{ PageJSONResponse } - -func (response ListWorkspaceInvitations200JSONResponse) VisitListWorkspaceInvitationsResponse(w http.ResponseWriter) error { +func (response TestWebhook404ApplicationProblemPlusJSONResponse) VisitTestWebhookResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { return err } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(404) _, err := buf.WriteTo(w) return err } -type CreateWorkspaceInvitationRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - Body *CreateWorkspaceInvitationJSONRequestBody -} - -type CreateWorkspaceInvitationResponseObject interface { - VisitCreateWorkspaceInvitationResponse(w http.ResponseWriter) error -} - -type CreateWorkspaceInvitation201Response struct { -} - -func (response CreateWorkspaceInvitation201Response) VisitCreateWorkspaceInvitationResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil -} - -type RevokeWorkspaceInvitationRequestObject struct { - ApplicationId ApplicationID `json:"application_id"` - InvitationId UUID `json:"invitation_id"` -} - -type RevokeWorkspaceInvitationResponseObject interface { - VisitRevokeWorkspaceInvitationResponse(w http.ResponseWriter) error -} - -type RevokeWorkspaceInvitation204Response struct { -} - -func (response RevokeWorkspaceInvitation204Response) VisitRevokeWorkspaceInvitationResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil -} - type ListWorkspacesRequestObject struct { ApplicationId ApplicationID `json:"application_id"` } @@ -28071,7 +35171,7 @@ type ListWorkspacesResponseObject interface { VisitListWorkspacesResponse(w http.ResponseWriter) error } -type ListWorkspaces200JSONResponse struct{ PageJSONResponse } +type ListWorkspaces200JSONResponse WorkspacePage func (response ListWorkspaces200JSONResponse) VisitListWorkspacesResponse(w http.ResponseWriter) error { @@ -28094,12 +35194,18 @@ type CreateWorkspaceResponseObject interface { VisitCreateWorkspaceResponse(w http.ResponseWriter) error } -type CreateWorkspace201Response struct { -} +type CreateWorkspace201JSONResponse Workspace + +func (response CreateWorkspace201JSONResponse) VisitCreateWorkspaceResponse(w http.ResponseWriter) error { -func (response CreateWorkspace201Response) VisitCreateWorkspaceResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DeleteWorkspaceRequestObject struct { @@ -28144,12 +35250,18 @@ type GetWorkspaceResponseObject interface { VisitGetWorkspaceResponse(w http.ResponseWriter) error } -type GetWorkspace200Response struct { -} +type GetWorkspace200JSONResponse Workspace + +func (response GetWorkspace200JSONResponse) VisitGetWorkspaceResponse(w http.ResponseWriter) error { -func (response GetWorkspace200Response) VisitGetWorkspaceResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateWorkspaceRequestObject struct { @@ -28179,7 +35291,7 @@ type ListWorkspaceMembersResponseObject interface { VisitListWorkspaceMembersResponse(w http.ResponseWriter) error } -type ListWorkspaceMembers200JSONResponse struct{ PageJSONResponse } +type ListWorkspaceMembers200JSONResponse WorkspaceMemberPage func (response ListWorkspaceMembers200JSONResponse) VisitListWorkspaceMembersResponse(w http.ResponseWriter) error { @@ -28222,12 +35334,18 @@ type ReplaceWorkspaceMemberRolesResponseObject interface { VisitReplaceWorkspaceMemberRolesResponse(w http.ResponseWriter) error } -type ReplaceWorkspaceMemberRoles200Response struct { -} +type ReplaceWorkspaceMemberRoles200JSONResponse WorkspaceMember + +func (response ReplaceWorkspaceMemberRoles200JSONResponse) VisitReplaceWorkspaceMemberRolesResponse(w http.ResponseWriter) error { -func (response ReplaceWorkspaceMemberRoles200Response) VisitReplaceWorkspaceMemberRolesResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type RecoverWorkspaceOwnershipRequestObject struct { @@ -28256,120 +35374,197 @@ func (response RecoverWorkspaceOwnership200JSONResponse) VisitRecoverWorkspaceOw return err } -type StartOperatorEmailLoginRequestObject struct { - Body *StartOperatorEmailLoginJSONRequestBody +type StartControlUserEmailLoginRequestObject struct { + Body *StartControlUserEmailLoginJSONRequestBody } -type StartOperatorEmailLoginResponseObject interface { - VisitStartOperatorEmailLoginResponse(w http.ResponseWriter) error +type StartControlUserEmailLoginResponseObject interface { + VisitStartControlUserEmailLoginResponse(w http.ResponseWriter) error } -type StartOperatorEmailLogin202Response struct { -} +type StartControlUserEmailLogin202JSONResponse ChallengeAccepted + +func (response StartControlUserEmailLogin202JSONResponse) VisitStartControlUserEmailLoginResponse(w http.ResponseWriter) error { -func (response StartOperatorEmailLogin202Response) VisitStartOperatorEmailLoginResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(202) - return nil + _, err := buf.WriteTo(w) + return err } -type VerifyOperatorEmailLoginRequestObject struct { - Body *VerifyOperatorEmailLoginJSONRequestBody +type VerifyControlUserEmailLoginRequestObject struct { + Body *VerifyControlUserEmailLoginJSONRequestBody } -type VerifyOperatorEmailLoginResponseObject interface { - VisitVerifyOperatorEmailLoginResponse(w http.ResponseWriter) error +type VerifyControlUserEmailLoginResponseObject interface { + VisitVerifyControlUserEmailLoginResponse(w http.ResponseWriter) error } -type VerifyOperatorEmailLogin200Response struct { -} +type VerifyControlUserEmailLogin200JSONResponse TokenResponse + +func (response VerifyControlUserEmailLogin200JSONResponse) VisitVerifyControlUserEmailLoginResponse(w http.ResponseWriter) error { -func (response VerifyOperatorEmailLogin200Response) VisitVerifyOperatorEmailLoginResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type LogoutOperatorRequestObject struct { +type UnlinkControlExternalIdentityRequestObject struct { + IdentityId UUID `json:"identity_id"` } -type LogoutOperatorResponseObject interface { - VisitLogoutOperatorResponse(w http.ResponseWriter) error +type UnlinkControlExternalIdentityResponseObject interface { + VisitUnlinkControlExternalIdentityResponse(w http.ResponseWriter) error } -type LogoutOperator204Response struct { +type UnlinkControlExternalIdentity204Response struct { } -func (response LogoutOperator204Response) VisitLogoutOperatorResponse(w http.ResponseWriter) error { +func (response UnlinkControlExternalIdentity204Response) VisitUnlinkControlExternalIdentityResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type LogoutAllOperatorSessionsRequestObject struct { +type UnlinkControlExternalIdentity409ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse } -type LogoutAllOperatorSessionsResponseObject interface { - VisitLogoutAllOperatorSessionsResponse(w http.ResponseWriter) error +func (response UnlinkControlExternalIdentity409ApplicationProblemPlusJSONResponse) VisitUnlinkControlExternalIdentityResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(409) + _, err := buf.WriteTo(w) + return err +} + +type LogoutControlUserRequestObject struct { +} + +type LogoutControlUserResponseObject interface { + VisitLogoutControlUserResponse(w http.ResponseWriter) error } -type LogoutAllOperatorSessions204Response struct { +type LogoutControlUser204Response struct { } -func (response LogoutAllOperatorSessions204Response) VisitLogoutAllOperatorSessionsResponse(w http.ResponseWriter) error { +func (response LogoutControlUser204Response) VisitLogoutControlUserResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type GetOperatorAccountRequestObject struct { +type LogoutAllControlUserSessionsRequestObject struct { } -type GetOperatorAccountResponseObject interface { - VisitGetOperatorAccountResponse(w http.ResponseWriter) error +type LogoutAllControlUserSessionsResponseObject interface { + VisitLogoutAllControlUserSessionsResponse(w http.ResponseWriter) error } -type GetOperatorAccount200Response struct { +type LogoutAllControlUserSessions204Response struct { } -func (response GetOperatorAccount200Response) VisitGetOperatorAccountResponse(w http.ResponseWriter) error { - w.WriteHeader(200) +func (response LogoutAllControlUserSessions204Response) VisitLogoutAllControlUserSessionsResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type UpdateOperatorAccountRequestObject struct { - Body *UpdateOperatorAccountJSONRequestBody +type GetControlUserAccountRequestObject struct { } -type UpdateOperatorAccountResponseObject interface { - VisitUpdateOperatorAccountResponse(w http.ResponseWriter) error +type GetControlUserAccountResponseObject interface { + VisitGetControlUserAccountResponse(w http.ResponseWriter) error } -type UpdateOperatorAccount204Response struct { +type GetControlUserAccount200JSONResponse ControlUserAccount + +func (response GetControlUserAccount200JSONResponse) VisitGetControlUserAccountResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type UpdateControlUserAccountRequestObject struct { + Body *UpdateControlUserAccountJSONRequestBody } -func (response UpdateOperatorAccount204Response) VisitUpdateOperatorAccountResponse(w http.ResponseWriter) error { +type UpdateControlUserAccountResponseObject interface { + VisitUpdateControlUserAccountResponse(w http.ResponseWriter) error +} + +type UpdateControlUserAccount204Response struct { +} + +func (response UpdateControlUserAccount204Response) VisitUpdateControlUserAccountResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type LoginOperatorWithPasswordRequestObject struct { - Body *LoginOperatorWithPasswordJSONRequestBody +type GetControlAuthMethodsRequestObject struct { } -type LoginOperatorWithPasswordResponseObject interface { - VisitLoginOperatorWithPasswordResponse(w http.ResponseWriter) error +type GetControlAuthMethodsResponseObject interface { + VisitGetControlAuthMethodsResponse(w http.ResponseWriter) error } -type LoginOperatorWithPassword200Response struct { +type GetControlAuthMethods200JSONResponse ControlAuthMethods + +func (response GetControlAuthMethods200JSONResponse) VisitGetControlAuthMethodsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type LoginControlUserWithPasswordRequestObject struct { + Body *LoginControlUserWithPasswordJSONRequestBody +} + +type LoginControlUserWithPasswordResponseObject interface { + VisitLoginControlUserWithPasswordResponse(w http.ResponseWriter) error } -func (response LoginOperatorWithPassword200Response) VisitLoginOperatorWithPasswordResponse(w http.ResponseWriter) error { +type LoginControlUserWithPassword200JSONResponse TokenResponse + +func (response LoginControlUserWithPassword200JSONResponse) VisitLoginControlUserWithPasswordResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } -type LoginOperatorWithPassword401ApplicationProblemPlusJSONResponse struct { +type LoginControlUserWithPassword401ApplicationProblemPlusJSONResponse struct { ProblemApplicationProblemPlusJSONResponse } -func (response LoginOperatorWithPassword401ApplicationProblemPlusJSONResponse) VisitLoginOperatorWithPasswordResponse(w http.ResponseWriter) error { +func (response LoginControlUserWithPassword401ApplicationProblemPlusJSONResponse) VisitLoginControlUserWithPasswordResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -28381,27 +35576,182 @@ func (response LoginOperatorWithPassword401ApplicationProblemPlusJSONResponse) V return err } -type ChangeOperatorPasswordRequestObject struct { - Body *ChangeOperatorPasswordJSONRequestBody +type ChangeControlUserPasswordRequestObject struct { + Body *ChangeControlUserPasswordJSONRequestBody +} + +type ChangeControlUserPasswordResponseObject interface { + VisitChangeControlUserPasswordResponse(w http.ResponseWriter) error +} + +type ChangeControlUserPassword204Response struct { +} + +func (response ChangeControlUserPassword204Response) VisitChangeControlUserPasswordResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type ChangeControlUserPassword409ApplicationProblemPlusJSONResponse struct { + ProblemApplicationProblemPlusJSONResponse +} + +func (response ChangeControlUserPassword409ApplicationProblemPlusJSONResponse) VisitChangeControlUserPasswordResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(409) + _, err := buf.WriteTo(w) + return err +} + +type LinkControlExternalIdentityRequestObject struct { + Provider string `json:"provider"` +} + +type LinkControlExternalIdentityResponseObject interface { + VisitLinkControlExternalIdentityResponse(w http.ResponseWriter) error +} + +type LinkControlExternalIdentity201JSONResponse ExternalAuthStart + +func (response LinkControlExternalIdentity201JSONResponse) VisitLinkControlExternalIdentityResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type StartControlExternalLoginRequestObject struct { + Provider string `json:"provider"` +} + +type StartControlExternalLoginResponseObject interface { + VisitStartControlExternalLoginResponse(w http.ResponseWriter) error +} + +type StartControlExternalLogin201JSONResponse ExternalAuthStart + +func (response StartControlExternalLogin201JSONResponse) VisitStartControlExternalLoginResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type ListControlUserSessionsRequestObject struct { +} + +type ListControlUserSessionsResponseObject interface { + VisitListControlUserSessionsResponse(w http.ResponseWriter) error +} + +type ListControlUserSessions200JSONResponse SessionPage + +func (response ListControlUserSessions200JSONResponse) VisitListControlUserSessionsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type RevokeControlUserSessionRequestObject struct { + SessionId UUID `json:"session_id"` +} + +type RevokeControlUserSessionResponseObject interface { + VisitRevokeControlUserSessionResponse(w http.ResponseWriter) error +} + +type RevokeControlUserSession204Response struct { +} + +func (response RevokeControlUserSession204Response) VisitRevokeControlUserSessionResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type RefreshControlUserSessionRequestObject struct { +} + +type RefreshControlUserSessionResponseObject interface { + VisitRefreshControlUserSessionResponse(w http.ResponseWriter) error +} + +type RefreshControlUserSession200JSONResponse TokenResponse + +func (response RefreshControlUserSession200JSONResponse) VisitRefreshControlUserSessionResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type GetControlAuthPolicyRequestObject struct { +} + +type GetControlAuthPolicyResponseObject interface { + VisitGetControlAuthPolicyResponse(w http.ResponseWriter) error +} + +type GetControlAuthPolicy200JSONResponse ControlAuthPolicy + +func (response GetControlAuthPolicy200JSONResponse) VisitGetControlAuthPolicyResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type UpdateControlAuthPolicyRequestObject struct { + Body *UpdateControlAuthPolicyJSONRequestBody } -type ChangeOperatorPasswordResponseObject interface { - VisitChangeOperatorPasswordResponse(w http.ResponseWriter) error +type UpdateControlAuthPolicyResponseObject interface { + VisitUpdateControlAuthPolicyResponse(w http.ResponseWriter) error } -type ChangeOperatorPassword204Response struct { +type UpdateControlAuthPolicy204Response struct { } -func (response ChangeOperatorPassword204Response) VisitChangeOperatorPasswordResponse(w http.ResponseWriter) error { +func (response UpdateControlAuthPolicy204Response) VisitUpdateControlAuthPolicyResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } -type ChangeOperatorPassword409ApplicationProblemPlusJSONResponse struct { +type UpdateControlAuthPolicy409ApplicationProblemPlusJSONResponse struct { ProblemApplicationProblemPlusJSONResponse } -func (response ChangeOperatorPassword409ApplicationProblemPlusJSONResponse) VisitChangeOperatorPasswordResponse(w http.ResponseWriter) error { +func (response UpdateControlAuthPolicy409ApplicationProblemPlusJSONResponse) VisitUpdateControlAuthPolicyResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -28413,58 +35763,6 @@ func (response ChangeOperatorPassword409ApplicationProblemPlusJSONResponse) Visi return err } -type ListOperatorSessionsRequestObject struct { -} - -type ListOperatorSessionsResponseObject interface { - VisitListOperatorSessionsResponse(w http.ResponseWriter) error -} - -type ListOperatorSessions200JSONResponse struct{ PageJSONResponse } - -func (response ListOperatorSessions200JSONResponse) VisitListOperatorSessionsResponse(w http.ResponseWriter) error { - - var buf bytes.Buffer - if err := json.NewEncoder(&buf).Encode(response); err != nil { - return err - } - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(200) - _, err := buf.WriteTo(w) - return err -} - -type RevokeOperatorSessionRequestObject struct { - SessionId UUID `json:"session_id"` -} - -type RevokeOperatorSessionResponseObject interface { - VisitRevokeOperatorSessionResponse(w http.ResponseWriter) error -} - -type RevokeOperatorSession204Response struct { -} - -func (response RevokeOperatorSession204Response) VisitRevokeOperatorSessionResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil -} - -type RefreshOperatorSessionRequestObject struct { -} - -type RefreshOperatorSessionResponseObject interface { - VisitRefreshOperatorSessionResponse(w http.ResponseWriter) error -} - -type RefreshOperatorSession200Response struct { -} - -func (response RefreshOperatorSession200Response) VisitRefreshOperatorSessionResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil -} - type ListInstallationAuthProvidersRequestObject struct { } @@ -28472,7 +35770,7 @@ type ListInstallationAuthProvidersResponseObject interface { VisitListInstallationAuthProvidersResponse(w http.ResponseWriter) error } -type ListInstallationAuthProviders200JSONResponse struct{ PageJSONResponse } +type ListInstallationAuthProviders200JSONResponse AuthProviderPage func (response ListInstallationAuthProviders200JSONResponse) VisitListInstallationAuthProvidersResponse(w http.ResponseWriter) error { @@ -28544,12 +35842,18 @@ type ConfigureInstallationAuthProviderResponseObject interface { VisitConfigureInstallationAuthProviderResponse(w http.ResponseWriter) error } -type ConfigureInstallationAuthProvider200Response struct { -} +type ConfigureInstallationAuthProvider200JSONResponse AuthProvider + +func (response ConfigureInstallationAuthProvider200JSONResponse) VisitConfigureInstallationAuthProviderResponse(w http.ResponseWriter) error { -func (response ConfigureInstallationAuthProvider200Response) VisitConfigureInstallationAuthProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListInstallationBillingProvidersRequestObject struct { @@ -28559,7 +35863,7 @@ type ListInstallationBillingProvidersResponseObject interface { VisitListInstallationBillingProvidersResponse(w http.ResponseWriter) error } -type ListInstallationBillingProviders200JSONResponse struct{ PageJSONResponse } +type ListInstallationBillingProviders200JSONResponse BillingProviderPage func (response ListInstallationBillingProviders200JSONResponse) VisitListInstallationBillingProvidersResponse(w http.ResponseWriter) error { @@ -28581,12 +35885,18 @@ type CreateInstallationBillingProviderResponseObject interface { VisitCreateInstallationBillingProviderResponse(w http.ResponseWriter) error } -type CreateInstallationBillingProvider201Response struct { -} +type CreateInstallationBillingProvider201JSONResponse BillingProvider -func (response CreateInstallationBillingProvider201Response) VisitCreateInstallationBillingProviderResponse(w http.ResponseWriter) error { +func (response CreateInstallationBillingProvider201JSONResponse) VisitCreateInstallationBillingProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableInstallationBillingProviderRequestObject struct { @@ -28613,12 +35923,18 @@ type GetInstallationBillingProviderResponseObject interface { VisitGetInstallationBillingProviderResponse(w http.ResponseWriter) error } -type GetInstallationBillingProvider200Response struct { -} +type GetInstallationBillingProvider200JSONResponse BillingProvider + +func (response GetInstallationBillingProvider200JSONResponse) VisitGetInstallationBillingProviderResponse(w http.ResponseWriter) error { -func (response GetInstallationBillingProvider200Response) VisitGetInstallationBillingProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateInstallationBillingProviderRequestObject struct { @@ -28654,6 +35970,88 @@ func (response VerifyInstallationBillingProvider204Response) VisitVerifyInstalla return nil } +type ListInstallationControlUserInvitationsRequestObject struct { +} + +type ListInstallationControlUserInvitationsResponseObject interface { + VisitListInstallationControlUserInvitationsResponse(w http.ResponseWriter) error +} + +type ListInstallationControlUserInvitations200JSONResponse ControlUserInvitationPage + +func (response ListInstallationControlUserInvitations200JSONResponse) VisitListInstallationControlUserInvitationsResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type CreateInstallationControlUserInvitationRequestObject struct { + Body *CreateInstallationControlUserInvitationJSONRequestBody +} + +type CreateInstallationControlUserInvitationResponseObject interface { + VisitCreateInstallationControlUserInvitationResponse(w http.ResponseWriter) error +} + +type CreateInstallationControlUserInvitation201JSONResponse ControlUserInvitation + +func (response CreateInstallationControlUserInvitation201JSONResponse) VisitCreateInstallationControlUserInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + +type RevokeInstallationControlUserInvitationRequestObject struct { + InvitationId UUID `json:"invitation_id"` +} + +type RevokeInstallationControlUserInvitationResponseObject interface { + VisitRevokeInstallationControlUserInvitationResponse(w http.ResponseWriter) error +} + +type RevokeInstallationControlUserInvitation204Response struct { +} + +func (response RevokeInstallationControlUserInvitation204Response) VisitRevokeInstallationControlUserInvitationResponse(w http.ResponseWriter) error { + w.WriteHeader(204) + return nil +} + +type ResendInstallationControlUserInvitationRequestObject struct { + InvitationId UUID `json:"invitation_id"` + Body *ResendInstallationControlUserInvitationJSONRequestBody +} + +type ResendInstallationControlUserInvitationResponseObject interface { + VisitResendInstallationControlUserInvitationResponse(w http.ResponseWriter) error +} + +type ResendInstallationControlUserInvitation200JSONResponse ControlUserInvitation + +func (response ResendInstallationControlUserInvitation200JSONResponse) VisitResendInstallationControlUserInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + type GetManagementAPIStatusRequestObject struct { } @@ -28683,12 +36081,18 @@ type UpdateManagementAPIStatusResponseObject interface { VisitUpdateManagementAPIStatusResponse(w http.ResponseWriter) error } -type UpdateManagementAPIStatus200Response struct { -} +type UpdateManagementAPIStatus200JSONResponse ManagementAPIStatus -func (response UpdateManagementAPIStatus200Response) VisitUpdateManagementAPIStatusResponse(w http.ResponseWriter) error { +func (response UpdateManagementAPIStatus200JSONResponse) VisitUpdateManagementAPIStatusResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListManagementClientsRequestObject struct { @@ -28698,7 +36102,7 @@ type ListManagementClientsResponseObject interface { VisitListManagementClientsResponse(w http.ResponseWriter) error } -type ListManagementClients200JSONResponse struct{ PageJSONResponse } +type ListManagementClients200JSONResponse ManagementClientPage func (response ListManagementClients200JSONResponse) VisitListManagementClientsResponse(w http.ResponseWriter) error { @@ -28720,12 +36124,18 @@ type CreateManagementClientResponseObject interface { VisitCreateManagementClientResponse(w http.ResponseWriter) error } -type CreateManagementClient201Response struct { -} +type CreateManagementClient201JSONResponse ManagementClient + +func (response CreateManagementClient201JSONResponse) VisitCreateManagementClientResponse(w http.ResponseWriter) error { -func (response CreateManagementClient201Response) VisitCreateManagementClientResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type CreateManagementClient409ApplicationProblemPlusJSONResponse struct { @@ -28768,12 +36178,18 @@ type RotateManagementClientSecretResponseObject interface { VisitRotateManagementClientSecretResponse(w http.ResponseWriter) error } -type RotateManagementClientSecret200Response struct { -} +type RotateManagementClientSecret200JSONResponse SecretCredential + +func (response RotateManagementClientSecret200JSONResponse) VisitRotateManagementClientSecretResponse(w http.ResponseWriter) error { -func (response RotateManagementClientSecret200Response) VisitRotateManagementClientSecretResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListInstallationNotificationProvidersRequestObject struct { @@ -28783,7 +36199,7 @@ type ListInstallationNotificationProvidersResponseObject interface { VisitListInstallationNotificationProvidersResponse(w http.ResponseWriter) error } -type ListInstallationNotificationProviders200JSONResponse struct{ PageJSONResponse } +type ListInstallationNotificationProviders200JSONResponse NotificationProviderPage func (response ListInstallationNotificationProviders200JSONResponse) VisitListInstallationNotificationProvidersResponse(w http.ResponseWriter) error { @@ -28805,12 +36221,18 @@ type CreateInstallationNotificationProviderResponseObject interface { VisitCreateInstallationNotificationProviderResponse(w http.ResponseWriter) error } -type CreateInstallationNotificationProvider201Response struct { -} +type CreateInstallationNotificationProvider201JSONResponse NotificationProvider -func (response CreateInstallationNotificationProvider201Response) VisitCreateInstallationNotificationProviderResponse(w http.ResponseWriter) error { +func (response CreateInstallationNotificationProvider201JSONResponse) VisitCreateInstallationNotificationProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableInstallationNotificationProviderRequestObject struct { @@ -28853,12 +36275,18 @@ type GetInstallationNotificationProviderResponseObject interface { VisitGetInstallationNotificationProviderResponse(w http.ResponseWriter) error } -type GetInstallationNotificationProvider200Response struct { -} +type GetInstallationNotificationProvider200JSONResponse NotificationProvider + +func (response GetInstallationNotificationProvider200JSONResponse) VisitGetInstallationNotificationProviderResponse(w http.ResponseWriter) error { -func (response GetInstallationNotificationProvider200Response) VisitGetInstallationNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type GetInstallationNotificationProvider404ApplicationProblemPlusJSONResponse struct { @@ -28886,12 +36314,18 @@ type UpdateInstallationNotificationProviderResponseObject interface { VisitUpdateInstallationNotificationProviderResponse(w http.ResponseWriter) error } -type UpdateInstallationNotificationProvider200Response struct { -} +type UpdateInstallationNotificationProvider200JSONResponse NotificationProvider -func (response UpdateInstallationNotificationProvider200Response) VisitUpdateInstallationNotificationProviderResponse(w http.ResponseWriter) error { +func (response UpdateInstallationNotificationProvider200JSONResponse) VisitUpdateInstallationNotificationProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateInstallationNotificationProvider404ApplicationProblemPlusJSONResponse struct { @@ -28920,12 +36354,18 @@ type TestInstallationNotificationProviderResponseObject interface { VisitTestInstallationNotificationProviderResponse(w http.ResponseWriter) error } -type TestInstallationNotificationProvider202Response struct { -} +type TestInstallationNotificationProvider202JSONResponse NotificationQueued + +func (response TestInstallationNotificationProvider202JSONResponse) VisitTestInstallationNotificationProviderResponse(w http.ResponseWriter) error { -func (response TestInstallationNotificationProvider202Response) VisitTestInstallationNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(202) - return nil + _, err := buf.WriteTo(w) + return err } type TestInstallationNotificationProvider404ApplicationProblemPlusJSONResponse struct { @@ -28983,12 +36423,18 @@ type ListInstallationNotificationTemplateVariablesResponseObject interface { VisitListInstallationNotificationTemplateVariablesResponse(w http.ResponseWriter) error } -type ListInstallationNotificationTemplateVariables200Response struct { -} +type ListInstallationNotificationTemplateVariables200JSONResponse TemplateVariables -func (response ListInstallationNotificationTemplateVariables200Response) VisitListInstallationNotificationTemplateVariablesResponse(w http.ResponseWriter) error { +func (response ListInstallationNotificationTemplateVariables200JSONResponse) VisitListInstallationNotificationTemplateVariablesResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListInstallationNotificationTemplatesRequestObject struct { @@ -28998,7 +36444,7 @@ type ListInstallationNotificationTemplatesResponseObject interface { VisitListInstallationNotificationTemplatesResponse(w http.ResponseWriter) error } -type ListInstallationNotificationTemplates200JSONResponse struct{ PageJSONResponse } +type ListInstallationNotificationTemplates200JSONResponse NotificationTemplatePage func (response ListInstallationNotificationTemplates200JSONResponse) VisitListInstallationNotificationTemplatesResponse(w http.ResponseWriter) error { @@ -29020,12 +36466,18 @@ type CreateInstallationNotificationTemplateResponseObject interface { VisitCreateInstallationNotificationTemplateResponse(w http.ResponseWriter) error } -type CreateInstallationNotificationTemplate201Response struct { -} +type CreateInstallationNotificationTemplate201JSONResponse NotificationTemplate + +func (response CreateInstallationNotificationTemplate201JSONResponse) VisitCreateInstallationNotificationTemplateResponse(w http.ResponseWriter) error { -func (response CreateInstallationNotificationTemplate201Response) VisitCreateInstallationNotificationTemplateResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type GetInstallationNotificationTemplateRequestObject struct { @@ -29036,12 +36488,18 @@ type GetInstallationNotificationTemplateResponseObject interface { VisitGetInstallationNotificationTemplateResponse(w http.ResponseWriter) error } -type GetInstallationNotificationTemplate200Response struct { -} +type GetInstallationNotificationTemplate200JSONResponse NotificationTemplate -func (response GetInstallationNotificationTemplate200Response) VisitGetInstallationNotificationTemplateResponse(w http.ResponseWriter) error { +func (response GetInstallationNotificationTemplate200JSONResponse) VisitGetInstallationNotificationTemplateResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateInstallationNotificationTemplateRequestObject struct { @@ -29053,12 +36511,18 @@ type UpdateInstallationNotificationTemplateResponseObject interface { VisitUpdateInstallationNotificationTemplateResponse(w http.ResponseWriter) error } -type UpdateInstallationNotificationTemplate201Response struct { -} +type UpdateInstallationNotificationTemplate201JSONResponse NotificationTemplate + +func (response UpdateInstallationNotificationTemplate201JSONResponse) VisitUpdateInstallationNotificationTemplateResponse(w http.ResponseWriter) error { -func (response UpdateInstallationNotificationTemplate201Response) VisitUpdateInstallationNotificationTemplateResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type ArchiveInstallationNotificationTemplateRequestObject struct { @@ -29086,40 +36550,9 @@ type PreviewInstallationNotificationTemplateResponseObject interface { VisitPreviewInstallationNotificationTemplateResponse(w http.ResponseWriter) error } -type PreviewInstallationNotificationTemplate200Response struct { -} - -func (response PreviewInstallationNotificationTemplate200Response) VisitPreviewInstallationNotificationTemplateResponse(w http.ResponseWriter) error { - w.WriteHeader(200) - return nil -} - -type PublishInstallationNotificationTemplateRequestObject struct { - TemplateId UUID `json:"template_id"` -} - -type PublishInstallationNotificationTemplateResponseObject interface { - VisitPublishInstallationNotificationTemplateResponse(w http.ResponseWriter) error -} +type PreviewInstallationNotificationTemplate200JSONResponse NotificationTemplatePreview -type PublishInstallationNotificationTemplate204Response struct { -} - -func (response PublishInstallationNotificationTemplate204Response) VisitPublishInstallationNotificationTemplateResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil -} - -type ListInstallationOperatorsRequestObject struct { -} - -type ListInstallationOperatorsResponseObject interface { - VisitListInstallationOperatorsResponse(w http.ResponseWriter) error -} - -type ListInstallationOperators200JSONResponse struct{ PageJSONResponse } - -func (response ListInstallationOperators200JSONResponse) VisitListInstallationOperatorsResponse(w http.ResponseWriter) error { +func (response PreviewInstallationNotificationTemplate200JSONResponse) VisitPreviewInstallationNotificationTemplateResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -29131,51 +36564,18 @@ func (response ListInstallationOperators200JSONResponse) VisitListInstallationOp return err } -type CreateInstallationOperatorRequestObject struct { - Body *CreateInstallationOperatorJSONRequestBody -} - -type CreateInstallationOperatorResponseObject interface { - VisitCreateInstallationOperatorResponse(w http.ResponseWriter) error -} - -type CreateInstallationOperator201Response struct { -} - -func (response CreateInstallationOperator201Response) VisitCreateInstallationOperatorResponse(w http.ResponseWriter) error { - w.WriteHeader(201) - return nil -} - -type DeleteInstallationOperatorRequestObject struct { - OperatorId UUID `json:"operator_id"` -} - -type DeleteInstallationOperatorResponseObject interface { - VisitDeleteInstallationOperatorResponse(w http.ResponseWriter) error -} - -type DeleteInstallationOperator204Response struct { -} - -func (response DeleteInstallationOperator204Response) VisitDeleteInstallationOperatorResponse(w http.ResponseWriter) error { - w.WriteHeader(204) - return nil -} - -type UpdateInstallationOperatorRequestObject struct { - OperatorId UUID `json:"operator_id"` - Body *UpdateInstallationOperatorJSONRequestBody +type PublishInstallationNotificationTemplateRequestObject struct { + TemplateId UUID `json:"template_id"` } -type UpdateInstallationOperatorResponseObject interface { - VisitUpdateInstallationOperatorResponse(w http.ResponseWriter) error +type PublishInstallationNotificationTemplateResponseObject interface { + VisitPublishInstallationNotificationTemplateResponse(w http.ResponseWriter) error } -type UpdateInstallationOperator204Response struct { +type PublishInstallationNotificationTemplate204Response struct { } -func (response UpdateInstallationOperator204Response) VisitUpdateInstallationOperatorResponse(w http.ResponseWriter) error { +func (response PublishInstallationNotificationTemplate204Response) VisitPublishInstallationNotificationTemplateResponse(w http.ResponseWriter) error { w.WriteHeader(204) return nil } @@ -29221,7 +36621,7 @@ type ListSigningKeysResponseObject interface { VisitListSigningKeysResponse(w http.ResponseWriter) error } -type ListSigningKeys200JSONResponse struct{ PageJSONResponse } +type ListSigningKeys200JSONResponse SigningKeyPage func (response ListSigningKeys200JSONResponse) VisitListSigningKeysResponse(w http.ResponseWriter) error { @@ -29242,12 +36642,18 @@ type RotateSigningKeyResponseObject interface { VisitRotateSigningKeyResponse(w http.ResponseWriter) error } -type RotateSigningKey201Response struct { -} +type RotateSigningKey201JSONResponse SigningKey + +func (response RotateSigningKey201JSONResponse) VisitRotateSigningKeyResponse(w http.ResponseWriter) error { -func (response RotateSigningKey201Response) VisitRotateSigningKeyResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type ListInstallationStorageObjectsRequestObject struct { @@ -29257,7 +36663,7 @@ type ListInstallationStorageObjectsResponseObject interface { VisitListInstallationStorageObjectsResponse(w http.ResponseWriter) error } -type ListInstallationStorageObjects200JSONResponse struct{ PageJSONResponse } +type ListInstallationStorageObjects200JSONResponse StorageObjectPage func (response ListInstallationStorageObjects200JSONResponse) VisitListInstallationStorageObjectsResponse(w http.ResponseWriter) error { @@ -29296,12 +36702,18 @@ type GetInstallationStorageObjectResponseObject interface { VisitGetInstallationStorageObjectResponse(w http.ResponseWriter) error } -type GetInstallationStorageObject200Response struct { -} +type GetInstallationStorageObject200JSONResponse StorageObject -func (response GetInstallationStorageObject200Response) VisitGetInstallationStorageObjectResponse(w http.ResponseWriter) error { +func (response GetInstallationStorageObject200JSONResponse) VisitGetInstallationStorageObjectResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type DownloadInstallationStorageObjectRequestObject struct { @@ -29312,12 +36724,18 @@ type DownloadInstallationStorageObjectResponseObject interface { VisitDownloadInstallationStorageObjectResponse(w http.ResponseWriter) error } -type DownloadInstallationStorageObject200Response struct { -} +type DownloadInstallationStorageObject200JSONResponse StorageDownload -func (response DownloadInstallationStorageObject200Response) VisitDownloadInstallationStorageObjectResponse(w http.ResponseWriter) error { +func (response DownloadInstallationStorageObject200JSONResponse) VisitDownloadInstallationStorageObjectResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListInstallationStorageProvidersRequestObject struct { @@ -29327,7 +36745,7 @@ type ListInstallationStorageProvidersResponseObject interface { VisitListInstallationStorageProvidersResponse(w http.ResponseWriter) error } -type ListInstallationStorageProviders200JSONResponse struct{ PageJSONResponse } +type ListInstallationStorageProviders200JSONResponse StorageProviderPage func (response ListInstallationStorageProviders200JSONResponse) VisitListInstallationStorageProvidersResponse(w http.ResponseWriter) error { @@ -29349,12 +36767,18 @@ type CreateInstallationStorageProviderResponseObject interface { VisitCreateInstallationStorageProviderResponse(w http.ResponseWriter) error } -type CreateInstallationStorageProvider201Response struct { -} +type CreateInstallationStorageProvider201JSONResponse StorageProvider -func (response CreateInstallationStorageProvider201Response) VisitCreateInstallationStorageProviderResponse(w http.ResponseWriter) error { +func (response CreateInstallationStorageProvider201JSONResponse) VisitCreateInstallationStorageProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableInstallationStorageProviderRequestObject struct { @@ -29398,12 +36822,18 @@ type GetInstallationStorageProviderResponseObject interface { VisitGetInstallationStorageProviderResponse(w http.ResponseWriter) error } -type GetInstallationStorageProvider200Response struct { -} +type GetInstallationStorageProvider200JSONResponse StorageProvider -func (response GetInstallationStorageProvider200Response) VisitGetInstallationStorageProviderResponse(w http.ResponseWriter) error { +func (response GetInstallationStorageProvider200JSONResponse) VisitGetInstallationStorageProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateInstallationStorageProviderRequestObject struct { @@ -29415,12 +36845,18 @@ type UpdateInstallationStorageProviderResponseObject interface { VisitUpdateInstallationStorageProviderResponse(w http.ResponseWriter) error } -type UpdateInstallationStorageProvider200Response struct { -} +type UpdateInstallationStorageProvider200JSONResponse StorageProvider -func (response UpdateInstallationStorageProvider200Response) VisitUpdateInstallationStorageProviderResponse(w http.ResponseWriter) error { +func (response UpdateInstallationStorageProvider200JSONResponse) VisitUpdateInstallationStorageProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type EnableInstallationStorageProviderRequestObject struct { @@ -29431,12 +36867,18 @@ type EnableInstallationStorageProviderResponseObject interface { VisitEnableInstallationStorageProviderResponse(w http.ResponseWriter) error } -type EnableInstallationStorageProvider200Response struct { -} +type EnableInstallationStorageProvider200JSONResponse StorageProviderStatus -func (response EnableInstallationStorageProvider200Response) VisitEnableInstallationStorageProviderResponse(w http.ResponseWriter) error { +func (response EnableInstallationStorageProvider200JSONResponse) VisitEnableInstallationStorageProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type VerifyInstallationStorageProviderRequestObject struct { @@ -29502,35 +36944,101 @@ type CompleteInstallationStorageUploadResponseObject interface { VisitCompleteInstallationStorageUploadResponse(w http.ResponseWriter) error } -type CompleteInstallationStorageUpload200Response struct { +type CompleteInstallationStorageUpload200JSONResponse StorageObject + +func (response CompleteInstallationStorageUpload200JSONResponse) VisitCompleteInstallationStorageUploadResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type ListInstallationControlUsersRequestObject struct { +} + +type ListInstallationControlUsersResponseObject interface { + VisitListInstallationControlUsersResponse(w http.ResponseWriter) error } -func (response CompleteInstallationStorageUpload200Response) VisitCompleteInstallationStorageUploadResponse(w http.ResponseWriter) error { +type ListInstallationControlUsers200JSONResponse ControlUserPage + +func (response ListInstallationControlUsers200JSONResponse) VisitListInstallationControlUsersResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type DeleteInstallationControlUserRequestObject struct { + ControlUserId UUID `json:"control_user_id"` +} + +type DeleteInstallationControlUserResponseObject interface { + VisitDeleteInstallationControlUserResponse(w http.ResponseWriter) error +} + +type DeleteInstallationControlUser204Response struct { +} + +func (response DeleteInstallationControlUser204Response) VisitDeleteInstallationControlUserResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type AcceptOrganizationInvitationRequestObject struct { - Body *AcceptOrganizationInvitationJSONRequestBody +type UpdateInstallationControlUserRequestObject struct { + ControlUserId UUID `json:"control_user_id"` + Body *UpdateInstallationControlUserJSONRequestBody } -type AcceptOrganizationInvitationResponseObject interface { - VisitAcceptOrganizationInvitationResponse(w http.ResponseWriter) error +type UpdateInstallationControlUserResponseObject interface { + VisitUpdateInstallationControlUserResponse(w http.ResponseWriter) error } -type AcceptOrganizationInvitation200Response struct { +type UpdateInstallationControlUser204Response struct { } -func (response AcceptOrganizationInvitation200Response) VisitAcceptOrganizationInvitationResponse(w http.ResponseWriter) error { - w.WriteHeader(200) +func (response UpdateInstallationControlUser204Response) VisitUpdateInstallationControlUserResponse(w http.ResponseWriter) error { + w.WriteHeader(204) return nil } -type AcceptOrganizationInvitation401ApplicationProblemPlusJSONResponse struct { +type AcceptControlUserInvitationRequestObject struct { + Body *AcceptControlUserInvitationJSONRequestBody +} + +type AcceptControlUserInvitationResponseObject interface { + VisitAcceptControlUserInvitationResponse(w http.ResponseWriter) error +} + +type AcceptControlUserInvitation200JSONResponse TokenResponse + +func (response AcceptControlUserInvitation200JSONResponse) VisitAcceptControlUserInvitationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + _, err := buf.WriteTo(w) + return err +} + +type AcceptControlUserInvitation401ApplicationProblemPlusJSONResponse struct { ProblemApplicationProblemPlusJSONResponse } -func (response AcceptOrganizationInvitation401ApplicationProblemPlusJSONResponse) VisitAcceptOrganizationInvitationResponse(w http.ResponseWriter) error { +func (response AcceptControlUserInvitation401ApplicationProblemPlusJSONResponse) VisitAcceptControlUserInvitationResponse(w http.ResponseWriter) error { var buf bytes.Buffer if err := json.NewEncoder(&buf).Encode(response); err != nil { @@ -29542,6 +37050,29 @@ func (response AcceptOrganizationInvitation401ApplicationProblemPlusJSONResponse return err } +type StartControlInvitationExternalLoginRequestObject struct { + Provider string `json:"provider"` + Body *StartControlInvitationExternalLoginJSONRequestBody +} + +type StartControlInvitationExternalLoginResponseObject interface { + VisitStartControlInvitationExternalLoginResponse(w http.ResponseWriter) error +} + +type StartControlInvitationExternalLogin201JSONResponse ExternalAuthStart + +func (response StartControlInvitationExternalLogin201JSONResponse) VisitStartControlInvitationExternalLoginResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(201) + _, err := buf.WriteTo(w) + return err +} + type ListOrganizationsRequestObject struct { Params ListOrganizationsParams } @@ -29572,12 +37103,18 @@ type CreateOrganizationResponseObject interface { VisitCreateOrganizationResponse(w http.ResponseWriter) error } -type CreateOrganization201Response struct { -} +type CreateOrganization201JSONResponse Organization + +func (response CreateOrganization201JSONResponse) VisitCreateOrganizationResponse(w http.ResponseWriter) error { -func (response CreateOrganization201Response) VisitCreateOrganizationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type CreateOrganization409ApplicationProblemPlusJSONResponse struct { @@ -29620,12 +37157,18 @@ type GetOrganizationResponseObject interface { VisitGetOrganizationResponse(w http.ResponseWriter) error } -type GetOrganization200Response struct { -} +type GetOrganization200JSONResponse Organization + +func (response GetOrganization200JSONResponse) VisitGetOrganizationResponse(w http.ResponseWriter) error { -func (response GetOrganization200Response) VisitGetOrganizationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateOrganizationRequestObject struct { @@ -29670,7 +37213,7 @@ type ListApplicationsResponseObject interface { VisitListApplicationsResponse(w http.ResponseWriter) error } -type ListApplications200JSONResponse struct{ PageJSONResponse } +type ListApplications200JSONResponse ApplicationPage func (response ListApplications200JSONResponse) VisitListApplicationsResponse(w http.ResponseWriter) error { @@ -29693,12 +37236,18 @@ type CreateApplicationResponseObject interface { VisitCreateApplicationResponse(w http.ResponseWriter) error } -type CreateApplication201Response struct { -} +type CreateApplication201JSONResponse Application + +func (response CreateApplication201JSONResponse) VisitCreateApplicationResponse(w http.ResponseWriter) error { -func (response CreateApplication201Response) VisitCreateApplicationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type RetireApplicationRequestObject struct { @@ -29777,7 +37326,7 @@ type ListOrganizationAuditLogsResponseObject interface { VisitListOrganizationAuditLogsResponse(w http.ResponseWriter) error } -type ListOrganizationAuditLogs200JSONResponse struct{ PageJSONResponse } +type ListOrganizationAuditLogs200JSONResponse AuditRecordPage func (response ListOrganizationAuditLogs200JSONResponse) VisitListOrganizationAuditLogsResponse(w http.ResponseWriter) error { @@ -29799,7 +37348,7 @@ type ListOrganizationAuthProvidersResponseObject interface { VisitListOrganizationAuthProvidersResponse(w http.ResponseWriter) error } -type ListOrganizationAuthProviders200JSONResponse struct{ PageJSONResponse } +type ListOrganizationAuthProviders200JSONResponse AuthProviderPage func (response ListOrganizationAuthProviders200JSONResponse) VisitListOrganizationAuthProvidersResponse(w http.ResponseWriter) error { @@ -29874,12 +37423,18 @@ type ConfigureOrganizationAuthProviderResponseObject interface { VisitConfigureOrganizationAuthProviderResponse(w http.ResponseWriter) error } -type ConfigureOrganizationAuthProvider200Response struct { -} +type ConfigureOrganizationAuthProvider200JSONResponse AuthProvider + +func (response ConfigureOrganizationAuthProvider200JSONResponse) VisitConfigureOrganizationAuthProviderResponse(w http.ResponseWriter) error { -func (response ConfigureOrganizationAuthProvider200Response) VisitConfigureOrganizationAuthProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListOrganizationBillingProvidersRequestObject struct { @@ -29890,7 +37445,7 @@ type ListOrganizationBillingProvidersResponseObject interface { VisitListOrganizationBillingProvidersResponse(w http.ResponseWriter) error } -type ListOrganizationBillingProviders200JSONResponse struct{ PageJSONResponse } +type ListOrganizationBillingProviders200JSONResponse BillingProviderPage func (response ListOrganizationBillingProviders200JSONResponse) VisitListOrganizationBillingProvidersResponse(w http.ResponseWriter) error { @@ -29913,12 +37468,18 @@ type CreateOrganizationBillingProviderResponseObject interface { VisitCreateOrganizationBillingProviderResponse(w http.ResponseWriter) error } -type CreateOrganizationBillingProvider201Response struct { -} +type CreateOrganizationBillingProvider201JSONResponse BillingProvider + +func (response CreateOrganizationBillingProvider201JSONResponse) VisitCreateOrganizationBillingProviderResponse(w http.ResponseWriter) error { -func (response CreateOrganizationBillingProvider201Response) VisitCreateOrganizationBillingProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableOrganizationBillingProviderRequestObject struct { @@ -29947,12 +37508,18 @@ type GetOrganizationBillingProviderResponseObject interface { VisitGetOrganizationBillingProviderResponse(w http.ResponseWriter) error } -type GetOrganizationBillingProvider200Response struct { -} +type GetOrganizationBillingProvider200JSONResponse BillingProvider + +func (response GetOrganizationBillingProvider200JSONResponse) VisitGetOrganizationBillingProviderResponse(w http.ResponseWriter) error { -func (response GetOrganizationBillingProvider200Response) VisitGetOrganizationBillingProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateOrganizationBillingProviderRequestObject struct { @@ -29998,7 +37565,7 @@ type ListOrganizationInvitationsResponseObject interface { VisitListOrganizationInvitationsResponse(w http.ResponseWriter) error } -type ListOrganizationInvitations200JSONResponse struct{ PageJSONResponse } +type ListOrganizationInvitations200JSONResponse ControlUserInvitationPage func (response ListOrganizationInvitations200JSONResponse) VisitListOrganizationInvitationsResponse(w http.ResponseWriter) error { @@ -30021,12 +37588,18 @@ type CreateOrganizationInvitationResponseObject interface { VisitCreateOrganizationInvitationResponse(w http.ResponseWriter) error } -type CreateOrganizationInvitation201Response struct { -} +type CreateOrganizationInvitation201JSONResponse ControlUserInvitation + +func (response CreateOrganizationInvitation201JSONResponse) VisitCreateOrganizationInvitationResponse(w http.ResponseWriter) error { -func (response CreateOrganizationInvitation201Response) VisitCreateOrganizationInvitationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type RevokeOrganizationInvitationRequestObject struct { @@ -30055,12 +37628,18 @@ type ResendOrganizationInvitationResponseObject interface { VisitResendOrganizationInvitationResponse(w http.ResponseWriter) error } -type ResendOrganizationInvitation200Response struct { -} +type ResendOrganizationInvitation200JSONResponse ControlUserInvitation + +func (response ResendOrganizationInvitation200JSONResponse) VisitResendOrganizationInvitationResponse(w http.ResponseWriter) error { -func (response ResendOrganizationInvitation200Response) VisitResendOrganizationInvitationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListOrganizationMembersRequestObject struct { @@ -30071,7 +37650,7 @@ type ListOrganizationMembersResponseObject interface { VisitListOrganizationMembersResponse(w http.ResponseWriter) error } -type ListOrganizationMembers200JSONResponse struct{ PageJSONResponse } +type ListOrganizationMembers200JSONResponse OrganizationMemberPage func (response ListOrganizationMembers200JSONResponse) VisitListOrganizationMembersResponse(w http.ResponseWriter) error { @@ -30128,7 +37707,7 @@ type ListOrganizationNotificationProvidersResponseObject interface { VisitListOrganizationNotificationProvidersResponse(w http.ResponseWriter) error } -type ListOrganizationNotificationProviders200JSONResponse struct{ PageJSONResponse } +type ListOrganizationNotificationProviders200JSONResponse NotificationProviderPage func (response ListOrganizationNotificationProviders200JSONResponse) VisitListOrganizationNotificationProvidersResponse(w http.ResponseWriter) error { @@ -30151,12 +37730,18 @@ type CreateOrganizationNotificationProviderResponseObject interface { VisitCreateOrganizationNotificationProviderResponse(w http.ResponseWriter) error } -type CreateOrganizationNotificationProvider201Response struct { -} +type CreateOrganizationNotificationProvider201JSONResponse NotificationProvider + +func (response CreateOrganizationNotificationProvider201JSONResponse) VisitCreateOrganizationNotificationProviderResponse(w http.ResponseWriter) error { -func (response CreateOrganizationNotificationProvider201Response) VisitCreateOrganizationNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableOrganizationNotificationProviderRequestObject struct { @@ -30185,12 +37770,18 @@ type GetOrganizationNotificationProviderResponseObject interface { VisitGetOrganizationNotificationProviderResponse(w http.ResponseWriter) error } -type GetOrganizationNotificationProvider200Response struct { -} +type GetOrganizationNotificationProvider200JSONResponse NotificationProvider + +func (response GetOrganizationNotificationProvider200JSONResponse) VisitGetOrganizationNotificationProviderResponse(w http.ResponseWriter) error { -func (response GetOrganizationNotificationProvider200Response) VisitGetOrganizationNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateOrganizationNotificationProviderRequestObject struct { @@ -30203,12 +37794,18 @@ type UpdateOrganizationNotificationProviderResponseObject interface { VisitUpdateOrganizationNotificationProviderResponse(w http.ResponseWriter) error } -type UpdateOrganizationNotificationProvider200Response struct { -} +type UpdateOrganizationNotificationProvider200JSONResponse NotificationProvider + +func (response UpdateOrganizationNotificationProvider200JSONResponse) VisitUpdateOrganizationNotificationProviderResponse(w http.ResponseWriter) error { -func (response UpdateOrganizationNotificationProvider200Response) VisitUpdateOrganizationNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type TestOrganizationNotificationProviderRequestObject struct { @@ -30222,12 +37819,18 @@ type TestOrganizationNotificationProviderResponseObject interface { VisitTestOrganizationNotificationProviderResponse(w http.ResponseWriter) error } -type TestOrganizationNotificationProvider202Response struct { -} +type TestOrganizationNotificationProvider202JSONResponse NotificationQueued + +func (response TestOrganizationNotificationProvider202JSONResponse) VisitTestOrganizationNotificationProviderResponse(w http.ResponseWriter) error { -func (response TestOrganizationNotificationProvider202Response) VisitTestOrganizationNotificationProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(202) - return nil + _, err := buf.WriteTo(w) + return err } type VerifyOrganizationNotificationProviderRequestObject struct { @@ -30293,7 +37896,7 @@ type ListOrganizationStorageObjectsResponseObject interface { VisitListOrganizationStorageObjectsResponse(w http.ResponseWriter) error } -type ListOrganizationStorageObjects200JSONResponse struct{ PageJSONResponse } +type ListOrganizationStorageObjects200JSONResponse StorageObjectPage func (response ListOrganizationStorageObjects200JSONResponse) VisitListOrganizationStorageObjectsResponse(w http.ResponseWriter) error { @@ -30334,12 +37937,18 @@ type GetOrganizationStorageObjectResponseObject interface { VisitGetOrganizationStorageObjectResponse(w http.ResponseWriter) error } -type GetOrganizationStorageObject200Response struct { -} +type GetOrganizationStorageObject200JSONResponse StorageObject + +func (response GetOrganizationStorageObject200JSONResponse) VisitGetOrganizationStorageObjectResponse(w http.ResponseWriter) error { -func (response GetOrganizationStorageObject200Response) VisitGetOrganizationStorageObjectResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type DownloadOrganizationStorageObjectRequestObject struct { @@ -30351,12 +37960,18 @@ type DownloadOrganizationStorageObjectResponseObject interface { VisitDownloadOrganizationStorageObjectResponse(w http.ResponseWriter) error } -type DownloadOrganizationStorageObject200Response struct { -} +type DownloadOrganizationStorageObject200JSONResponse StorageDownload -func (response DownloadOrganizationStorageObject200Response) VisitDownloadOrganizationStorageObjectResponse(w http.ResponseWriter) error { +func (response DownloadOrganizationStorageObject200JSONResponse) VisitDownloadOrganizationStorageObjectResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ListOrganizationStorageProvidersRequestObject struct { @@ -30367,7 +37982,7 @@ type ListOrganizationStorageProvidersResponseObject interface { VisitListOrganizationStorageProvidersResponse(w http.ResponseWriter) error } -type ListOrganizationStorageProviders200JSONResponse struct{ PageJSONResponse } +type ListOrganizationStorageProviders200JSONResponse StorageProviderPage func (response ListOrganizationStorageProviders200JSONResponse) VisitListOrganizationStorageProvidersResponse(w http.ResponseWriter) error { @@ -30390,12 +38005,18 @@ type CreateOrganizationStorageProviderResponseObject interface { VisitCreateOrganizationStorageProviderResponse(w http.ResponseWriter) error } -type CreateOrganizationStorageProvider201Response struct { -} +type CreateOrganizationStorageProvider201JSONResponse StorageProvider -func (response CreateOrganizationStorageProvider201Response) VisitCreateOrganizationStorageProviderResponse(w http.ResponseWriter) error { +func (response CreateOrganizationStorageProvider201JSONResponse) VisitCreateOrganizationStorageProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type DisableOrganizationStorageProviderRequestObject struct { @@ -30441,12 +38062,18 @@ type GetOrganizationStorageProviderResponseObject interface { VisitGetOrganizationStorageProviderResponse(w http.ResponseWriter) error } -type GetOrganizationStorageProvider200Response struct { -} +type GetOrganizationStorageProvider200JSONResponse StorageProvider -func (response GetOrganizationStorageProvider200Response) VisitGetOrganizationStorageProviderResponse(w http.ResponseWriter) error { +func (response GetOrganizationStorageProvider200JSONResponse) VisitGetOrganizationStorageProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type UpdateOrganizationStorageProviderRequestObject struct { @@ -30459,12 +38086,18 @@ type UpdateOrganizationStorageProviderResponseObject interface { VisitUpdateOrganizationStorageProviderResponse(w http.ResponseWriter) error } -type UpdateOrganizationStorageProvider200Response struct { -} +type UpdateOrganizationStorageProvider200JSONResponse StorageProvider + +func (response UpdateOrganizationStorageProvider200JSONResponse) VisitUpdateOrganizationStorageProviderResponse(w http.ResponseWriter) error { -func (response UpdateOrganizationStorageProvider200Response) VisitUpdateOrganizationStorageProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type EnableOrganizationStorageProviderRequestObject struct { @@ -30476,12 +38109,18 @@ type EnableOrganizationStorageProviderResponseObject interface { VisitEnableOrganizationStorageProviderResponse(w http.ResponseWriter) error } -type EnableOrganizationStorageProvider200Response struct { -} +type EnableOrganizationStorageProvider200JSONResponse StorageProviderStatus + +func (response EnableOrganizationStorageProvider200JSONResponse) VisitEnableOrganizationStorageProviderResponse(w http.ResponseWriter) error { -func (response EnableOrganizationStorageProvider200Response) VisitEnableOrganizationStorageProviderResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type VerifyOrganizationStorageProviderRequestObject struct { @@ -30509,7 +38148,7 @@ type ManagementListOrganizationsResponseObject interface { VisitManagementListOrganizationsResponse(w http.ResponseWriter) error } -type ManagementListOrganizations200JSONResponse struct{ PageJSONResponse } +type ManagementListOrganizations200JSONResponse OrganizationPage func (response ManagementListOrganizations200JSONResponse) VisitManagementListOrganizationsResponse(w http.ResponseWriter) error { @@ -30531,12 +38170,18 @@ type ManagementCreateOrganizationResponseObject interface { VisitManagementCreateOrganizationResponse(w http.ResponseWriter) error } -type ManagementCreateOrganization201Response struct { -} +type ManagementCreateOrganization201JSONResponse Organization + +func (response ManagementCreateOrganization201JSONResponse) VisitManagementCreateOrganizationResponse(w http.ResponseWriter) error { -func (response ManagementCreateOrganization201Response) VisitManagementCreateOrganizationResponse(w http.ResponseWriter) error { + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type ManagementRetireOrganizationRequestObject struct { @@ -30563,12 +38208,18 @@ type ManagementGetOrganizationResponseObject interface { VisitManagementGetOrganizationResponse(w http.ResponseWriter) error } -type ManagementGetOrganization200Response struct { -} +type ManagementGetOrganization200JSONResponse Organization -func (response ManagementGetOrganization200Response) VisitManagementGetOrganizationResponse(w http.ResponseWriter) error { +func (response ManagementGetOrganization200JSONResponse) VisitManagementGetOrganizationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type ManagementUpdateOrganizationRequestObject struct { @@ -30598,7 +38249,7 @@ type ManagementListApplicationsResponseObject interface { VisitManagementListApplicationsResponse(w http.ResponseWriter) error } -type ManagementListApplications200JSONResponse struct{ PageJSONResponse } +type ManagementListApplications200JSONResponse ApplicationPage func (response ManagementListApplications200JSONResponse) VisitManagementListApplicationsResponse(w http.ResponseWriter) error { @@ -30621,12 +38272,18 @@ type ManagementCreateApplicationResponseObject interface { VisitManagementCreateApplicationResponse(w http.ResponseWriter) error } -type ManagementCreateApplication201Response struct { -} +type ManagementCreateApplication201JSONResponse Application -func (response ManagementCreateApplication201Response) VisitManagementCreateApplicationResponse(w http.ResponseWriter) error { +func (response ManagementCreateApplication201JSONResponse) VisitManagementCreateApplicationResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type ManagementCreateApplication409ApplicationProblemPlusJSONResponse struct { @@ -30762,12 +38419,18 @@ type BootstrapResponseObject interface { VisitBootstrapResponse(w http.ResponseWriter) error } -type Bootstrap201Response struct { -} +type Bootstrap201JSONResponse SetupSession -func (response Bootstrap201Response) VisitBootstrapResponse(w http.ResponseWriter) error { +func (response Bootstrap201JSONResponse) VisitBootstrapResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type Bootstrap401ApplicationProblemPlusJSONResponse struct { @@ -30787,18 +38450,25 @@ func (response Bootstrap401ApplicationProblemPlusJSONResponse) VisitBootstrapRes } type CompleteSetupRequestObject struct { + Body *CompleteSetupJSONRequestBody } type CompleteSetupResponseObject interface { VisitCompleteSetupResponse(w http.ResponseWriter) error } -type CompleteSetup200Response struct { -} +type CompleteSetup200JSONResponse SetupCompletion -func (response CompleteSetup200Response) VisitCompleteSetupResponse(w http.ResponseWriter) error { +func (response CompleteSetup200JSONResponse) VisitCompleteSetupResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) - return nil + _, err := buf.WriteTo(w) + return err } type CompleteSetup409ApplicationProblemPlusJSONResponse struct { @@ -30817,6 +38487,20 @@ func (response CompleteSetup409ApplicationProblemPlusJSONResponse) VisitComplete return err } +type CompleteSetup422ApplicationProblemPlusJSONResponse Problem + +func (response CompleteSetup422ApplicationProblemPlusJSONResponse) VisitCompleteSetupResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(422) + _, err := buf.WriteTo(w) + return err +} + type CreateSetupNotificationProviderRequestObject struct { Body *CreateSetupNotificationProviderJSONRequestBody } @@ -30825,12 +38509,18 @@ type CreateSetupNotificationProviderResponseObject interface { VisitCreateSetupNotificationProviderResponse(w http.ResponseWriter) error } -type CreateSetupNotificationProvider201Response struct { -} +type CreateSetupNotificationProvider201JSONResponse NotificationProvider -func (response CreateSetupNotificationProvider201Response) VisitCreateSetupNotificationProviderResponse(w http.ResponseWriter) error { +func (response CreateSetupNotificationProvider201JSONResponse) VisitCreateSetupNotificationProviderResponse(w http.ResponseWriter) error { + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(response); err != nil { + return err + } + w.Header().Set("Content-Type", "application/json") w.WriteHeader(201) - return nil + _, err := buf.WriteTo(w) + return err } type SetupStatusRequestObject struct { @@ -30840,10 +38530,7 @@ type SetupStatusResponseObject interface { VisitSetupStatusResponse(w http.ResponseWriter) error } -type SetupStatus200JSONResponse struct { - Available bool `json:"available"` - OperatorEmailLoginAvailable bool `json:"operator_email_login_available"` -} +type SetupStatus200JSONResponse SetupStatus func (response SetupStatus200JSONResponse) VisitSetupStatusResponse(w http.ResponseWriter) error { @@ -30864,7 +38551,7 @@ type VersionResponseObject interface { VisitVersionResponse(w http.ResponseWriter) error } -type Version200JSONResponse map[string]interface{} +type Version200JSONResponse VersionInfo func (response Version200JSONResponse) VisitVersionResponse(w http.ResponseWriter) error { @@ -30920,6 +38607,12 @@ type StrictServerInterface interface { // (POST /v1/applications/{application_id}/auth/email/verify) EmailVerify(ctx context.Context, request EmailVerifyRequestObject) (EmailVerifyResponseObject, error) + // (POST /v1/applications/{application_id}/auth/invitations/exchange) + ExchangeApplicationInvitation(ctx context.Context, request ExchangeApplicationInvitationRequestObject) (ExchangeApplicationInvitationResponseObject, error) + + // (POST /v1/applications/{application_id}/auth/invitations/token) + RedeemApplicationInvitation(ctx context.Context, request RedeemApplicationInvitationRequestObject) (RedeemApplicationInvitationResponseObject, error) + // (POST /v1/applications/{application_id}/auth/logout) LogoutCurrentSession(ctx context.Context, request LogoutCurrentSessionRequestObject) (LogoutCurrentSessionResponseObject, error) @@ -30950,18 +38643,12 @@ type StrictServerInterface interface { // (GET /v1/applications/{application_id}/auth/providers) ListAuthProviders(ctx context.Context, request ListAuthProvidersRequestObject) (ListAuthProvidersResponseObject, error) - // (POST /v1/applications/{application_id}/auth/providers/apple/callback) - AppleAuthCallback(ctx context.Context, request AppleAuthCallbackRequestObject) (AppleAuthCallbackResponseObject, error) - // (POST /v1/applications/{application_id}/auth/providers/apple/exchange) ExchangeAppleAuth(ctx context.Context, request ExchangeAppleAuthRequestObject) (ExchangeAppleAuthResponseObject, error) // (POST /v1/applications/{application_id}/auth/providers/apple/start) StartAppleAuth(ctx context.Context, request StartAppleAuthRequestObject) (StartAppleAuthResponseObject, error) - // (GET /v1/applications/{application_id}/auth/providers/google/callback) - GoogleAuthCallback(ctx context.Context, request GoogleAuthCallbackRequestObject) (GoogleAuthCallbackResponseObject, error) - // (POST /v1/applications/{application_id}/auth/providers/google/exchange) ExchangeGoogleAuth(ctx context.Context, request ExchangeGoogleAuthRequestObject) (ExchangeGoogleAuthResponseObject, error) @@ -30989,6 +38676,21 @@ type StrictServerInterface interface { // (POST /v1/applications/{application_id}/events) PublishCustomEvent(ctx context.Context, request PublishCustomEventRequestObject) (PublishCustomEventResponseObject, error) + // (GET /v1/applications/{application_id}/invitations) + ListApplicationInvitations(ctx context.Context, request ListApplicationInvitationsRequestObject) (ListApplicationInvitationsResponseObject, error) + + // (POST /v1/applications/{application_id}/invitations) + CreateApplicationInvitationMachine(ctx context.Context, request CreateApplicationInvitationMachineRequestObject) (CreateApplicationInvitationMachineResponseObject, error) + + // (DELETE /v1/applications/{application_id}/invitations/{invitation_id}) + RevokeApplicationInvitation(ctx context.Context, request RevokeApplicationInvitationRequestObject) (RevokeApplicationInvitationResponseObject, error) + + // (GET /v1/applications/{application_id}/invitations/{invitation_id}) + GetApplicationInvitation(ctx context.Context, request GetApplicationInvitationRequestObject) (GetApplicationInvitationResponseObject, error) + + // (POST /v1/applications/{application_id}/invitations/{invitation_id}/resend) + ResendApplicationInvitation(ctx context.Context, request ResendApplicationInvitationRequestObject) (ResendApplicationInvitationResponseObject, error) + // (POST /v1/applications/{application_id}/local-entitlement-checkouts) LocalEntitlementCheckout(ctx context.Context, request LocalEntitlementCheckoutRequestObject) (LocalEntitlementCheckoutResponseObject, error) @@ -31152,10 +38854,7 @@ type StrictServerInterface interface { ListMySubscriptions(ctx context.Context, request ListMySubscriptionsRequestObject) (ListMySubscriptionsResponseObject, error) // (GET /v1/applications/{application_id}/me/workspace-invitations) - ListMyWorkspaceInvitations(ctx context.Context, request ListMyWorkspaceInvitationsRequestObject) (ListMyWorkspaceInvitationsResponseObject, error) - - // (POST /v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept) - AcceptMyWorkspaceInvitation(ctx context.Context, request AcceptMyWorkspaceInvitationRequestObject) (AcceptMyWorkspaceInvitationResponseObject, error) + ListMyPendingInvitations(ctx context.Context, request ListMyPendingInvitationsRequestObject) (ListMyPendingInvitationsResponseObject, error) // (GET /v1/applications/{application_id}/me/workspaces) ListMyWorkspaces(ctx context.Context, request ListMyWorkspacesRequestObject) (ListMyWorkspacesResponseObject, error) @@ -31163,9 +38862,33 @@ type StrictServerInterface interface { // (POST /v1/applications/{application_id}/me/workspaces) CreateMyWorkspace(ctx context.Context, request CreateMyWorkspaceRequestObject) (CreateMyWorkspaceResponseObject, error) + // (POST /v1/applications/{application_id}/notifications) + SendMachineNotification(ctx context.Context, request SendMachineNotificationRequestObject) (SendMachineNotificationResponseObject, error) + + // (GET /v1/applications/{application_id}/permission-grants) + ListPermissionGrants(ctx context.Context, request ListPermissionGrantsRequestObject) (ListPermissionGrantsResponseObject, error) + + // (POST /v1/applications/{application_id}/permission-grants) + CreatePermissionGrant(ctx context.Context, request CreatePermissionGrantRequestObject) (CreatePermissionGrantResponseObject, error) + + // (GET /v1/applications/{application_id}/permission-grants/effective) + GetEffectiveAccess(ctx context.Context, request GetEffectiveAccessRequestObject) (GetEffectiveAccessResponseObject, error) + + // (DELETE /v1/applications/{application_id}/permission-grants/{grant_id}) + RevokePermissionGrant(ctx context.Context, request RevokePermissionGrantRequestObject) (RevokePermissionGrantResponseObject, error) + + // (GET /v1/applications/{application_id}/permission-grants/{grant_id}) + GetPermissionGrant(ctx context.Context, request GetPermissionGrantRequestObject) (GetPermissionGrantResponseObject, error) + // (GET /v1/applications/{application_id}/public-config) PublicConfig(ctx context.Context, request PublicConfigRequestObject) (PublicConfigResponseObject, error) + // (GET /v1/applications/{application_id}/service/workspaces/{workspace_id}) + ServiceGetApplicationWorkspace(ctx context.Context, request ServiceGetApplicationWorkspaceRequestObject) (ServiceGetApplicationWorkspaceResponseObject, error) + + // (GET /v1/applications/{application_id}/service/workspaces/{workspace_id}/access) + ServiceListApplicationWorkspaceAccess(ctx context.Context, request ServiceListApplicationWorkspaceAccessRequestObject) (ServiceListApplicationWorkspaceAccessResponseObject, error) + // (GET /v1/applications/{application_id}/storage/objects) ListApplicationStorageObjects(ctx context.Context, request ListApplicationStorageObjectsRequestObject) (ListApplicationStorageObjectsResponseObject, error) @@ -31184,6 +38907,21 @@ type StrictServerInterface interface { // (POST /v1/applications/{application_id}/storage/uploads/{object_id}/complete) CompleteApplicationStorageUpload(ctx context.Context, request CompleteApplicationStorageUploadRequestObject) (CompleteApplicationStorageUploadResponseObject, error) + // (GET /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing) + ServiceGetSubjectBilling(ctx context.Context, request ServiceGetSubjectBillingRequestObject) (ServiceGetSubjectBillingResponseObject, error) + + // (GET /v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements) + ServiceGetSubjectEntitlements(ctx context.Context, request ServiceGetSubjectEntitlementsRequestObject) (ServiceGetSubjectEntitlementsResponseObject, error) + + // (GET /v1/applications/{application_id}/users) + ServiceListApplicationUsers(ctx context.Context, request ServiceListApplicationUsersRequestObject) (ServiceListApplicationUsersResponseObject, error) + + // (GET /v1/applications/{application_id}/users/{user_id}) + ServiceGetApplicationUser(ctx context.Context, request ServiceGetApplicationUserRequestObject) (ServiceGetApplicationUserResponseObject, error) + + // (GET /v1/applications/{application_id}/workspaces) + ServiceListApplicationWorkspaces(ctx context.Context, request ServiceListApplicationWorkspacesRequestObject) (ServiceListApplicationWorkspacesResponseObject, error) + // (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}) ArchiveMyWorkspace(ctx context.Context, request ArchiveMyWorkspaceRequestObject) (ArchiveMyWorkspaceResponseObject, error) @@ -31193,6 +38931,9 @@ type StrictServerInterface interface { // (PATCH /v1/applications/{application_id}/workspaces/{workspace_id}) UpdateMyWorkspace(ctx context.Context, request UpdateMyWorkspaceRequestObject) (UpdateMyWorkspaceResponseObject, error) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/access) + ListMyWorkspaceAccess(ctx context.Context, request ListMyWorkspaceAccessRequestObject) (ListMyWorkspaceAccessResponseObject, error) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/addresses) ListWorkspaceAddresses(ctx context.Context, request ListWorkspaceAddressesRequestObject) (ListWorkspaceAddressesResponseObject, error) @@ -31214,9 +38955,18 @@ type StrictServerInterface interface { // (PATCH /v1/applications/{application_id}/workspaces/{workspace_id}/billing-profile) UpdateWorkspaceBillingProfile(ctx context.Context, request UpdateWorkspaceBillingProfileRequestObject) (UpdateWorkspaceBillingProfileResponseObject, error) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/invitations) + ListMyWorkspaceInvitations(ctx context.Context, request ListMyWorkspaceInvitationsRequestObject) (ListMyWorkspaceInvitationsResponseObject, error) + // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/invitations) CreateMyWorkspaceInvitation(ctx context.Context, request CreateMyWorkspaceInvitationRequestObject) (CreateMyWorkspaceInvitationResponseObject, error) + // (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}) + RevokeMyWorkspaceInvitation(ctx context.Context, request RevokeMyWorkspaceInvitationRequestObject) (RevokeMyWorkspaceInvitationResponseObject, error) + + // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend) + ResendMyWorkspaceInvitation(ctx context.Context, request ResendMyWorkspaceInvitationRequestObject) (ResendMyWorkspaceInvitationResponseObject, error) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/members) ListMyWorkspaceMembers(ctx context.Context, request ListMyWorkspaceMembersRequestObject) (ListMyWorkspaceMembersResponseObject, error) @@ -31232,6 +38982,18 @@ type StrictServerInterface interface { // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/owner-transfer) TransferMyWorkspaceOwnership(ctx context.Context, request TransferMyWorkspaceOwnershipRequestObject) (TransferMyWorkspaceOwnershipResponseObject, error) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants) + ListWorkspacePermissionGrants(ctx context.Context, request ListWorkspacePermissionGrantsRequestObject) (ListWorkspacePermissionGrantsResponseObject, error) + + // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants) + CreateWorkspacePermissionGrant(ctx context.Context, request CreateWorkspacePermissionGrantRequestObject) (CreateWorkspacePermissionGrantResponseObject, error) + + // (DELETE /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}) + RevokeWorkspacePermissionGrant(ctx context.Context, request RevokeWorkspacePermissionGrantRequestObject) (RevokeWorkspacePermissionGrantResponseObject, error) + + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}) + GetWorkspacePermissionGrant(ctx context.Context, request GetWorkspacePermissionGrantRequestObject) (GetWorkspacePermissionGrantResponseObject, error) + // (GET /v1/applications/{application_id}/workspaces/{workspace_id}/storage/objects) ListWorkspaceStorageObjects(ctx context.Context, request ListWorkspaceStorageObjectsRequestObject) (ListWorkspaceStorageObjectsResponseObject, error) @@ -31250,6 +39012,12 @@ type StrictServerInterface interface { // (POST /v1/applications/{application_id}/workspaces/{workspace_id}/storage/uploads/{object_id}/complete) CompleteWorkspaceStorageUpload(ctx context.Context, request CompleteWorkspaceStorageUploadRequestObject) (CompleteWorkspaceStorageUploadResponseObject, error) + // (POST /v1/auth/providers/apple/callback) + AppleAuthCallback(ctx context.Context, request AppleAuthCallbackRequestObject) (AppleAuthCallbackResponseObject, error) + + // (GET /v1/auth/providers/google/callback) + GoogleAuthCallback(ctx context.Context, request GoogleAuthCallbackRequestObject) (GoogleAuthCallbackResponseObject, error) + // (GET /v1/control/applications/{application_id}) GetApplication(ctx context.Context, request GetApplicationRequestObject) (GetApplicationResponseObject, error) @@ -31367,6 +39135,9 @@ type StrictServerInterface interface { // (DELETE /v1/control/applications/{application_id}/clients/{client_id}) DisableClient(ctx context.Context, request DisableClientRequestObject) (DisableClientResponseObject, error) + // (GET /v1/control/applications/{application_id}/clients/{client_id}) + GetClient(ctx context.Context, request GetClientRequestObject) (GetClientResponseObject, error) + // (PATCH /v1/control/applications/{application_id}/clients/{client_id}) UpdateClient(ctx context.Context, request UpdateClientRequestObject) (UpdateClientResponseObject, error) @@ -31406,6 +39177,9 @@ type StrictServerInterface interface { // (GET /v1/control/applications/{application_id}/entitlements/{entitlement_id}) GetEntitlement(ctx context.Context, request GetEntitlementRequestObject) (GetEntitlementResponseObject, error) + // (POST /v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust) + AdjustEntitlement(ctx context.Context, request AdjustEntitlementRequestObject) (AdjustEntitlementResponseObject, error) + // (POST /v1/control/applications/{application_id}/entitlements/{entitlement_id}/restore) RestoreEntitlement(ctx context.Context, request RestoreEntitlementRequestObject) (RestoreEntitlementResponseObject, error) @@ -31442,6 +39216,21 @@ type StrictServerInterface interface { // (PATCH /v1/control/applications/{application_id}/internal-config) UpdateInternalApplicationConfig(ctx context.Context, request UpdateInternalApplicationConfigRequestObject) (UpdateInternalApplicationConfigResponseObject, error) + // (GET /v1/control/applications/{application_id}/invitations) + ListApplicationInvitationsControl(ctx context.Context, request ListApplicationInvitationsControlRequestObject) (ListApplicationInvitationsControlResponseObject, error) + + // (POST /v1/control/applications/{application_id}/invitations) + CreateApplicationInvitationControl(ctx context.Context, request CreateApplicationInvitationControlRequestObject) (CreateApplicationInvitationControlResponseObject, error) + + // (DELETE /v1/control/applications/{application_id}/invitations/{invitation_id}) + RevokeApplicationInvitationControl(ctx context.Context, request RevokeApplicationInvitationControlRequestObject) (RevokeApplicationInvitationControlResponseObject, error) + + // (GET /v1/control/applications/{application_id}/invitations/{invitation_id}) + GetApplicationInvitationControl(ctx context.Context, request GetApplicationInvitationControlRequestObject) (GetApplicationInvitationControlResponseObject, error) + + // (POST /v1/control/applications/{application_id}/invitations/{invitation_id}/resend) + ResendApplicationInvitationControl(ctx context.Context, request ResendApplicationInvitationControlRequestObject) (ResendApplicationInvitationControlResponseObject, error) + // (GET /v1/control/applications/{application_id}/local-entitlement-requests) ListLocalEntitlementRequests(ctx context.Context, request ListLocalEntitlementRequestsRequestObject) (ListLocalEntitlementRequestsResponseObject, error) @@ -31505,9 +39294,6 @@ type StrictServerInterface interface { // (GET /v1/control/applications/{application_id}/notifications) ListNotifications(ctx context.Context, request ListNotificationsRequestObject) (ListNotificationsResponseObject, error) - // (POST /v1/control/applications/{application_id}/notifications) - QueueNotification(ctx context.Context, request QueueNotificationRequestObject) (QueueNotificationResponseObject, error) - // (GET /v1/control/applications/{application_id}/notifications/statistics) GetNotificationStatistics(ctx context.Context, request GetNotificationStatisticsRequestObject) (GetNotificationStatisticsResponseObject, error) @@ -31523,6 +39309,21 @@ type StrictServerInterface interface { // (POST /v1/control/applications/{application_id}/oauth-consents/{user_id}/{client_id}/revoke) RevokeOAuthConsent(ctx context.Context, request RevokeOAuthConsentRequestObject) (RevokeOAuthConsentResponseObject, error) + // (GET /v1/control/applications/{application_id}/permission-grants) + ListControlPermissionGrants(ctx context.Context, request ListControlPermissionGrantsRequestObject) (ListControlPermissionGrantsResponseObject, error) + + // (POST /v1/control/applications/{application_id}/permission-grants) + CreateControlPermissionGrant(ctx context.Context, request CreateControlPermissionGrantRequestObject) (CreateControlPermissionGrantResponseObject, error) + + // (GET /v1/control/applications/{application_id}/permission-grants/effective) + GetControlEffectiveAccess(ctx context.Context, request GetControlEffectiveAccessRequestObject) (GetControlEffectiveAccessResponseObject, error) + + // (DELETE /v1/control/applications/{application_id}/permission-grants/{grant_id}) + RevokeControlPermissionGrant(ctx context.Context, request RevokeControlPermissionGrantRequestObject) (RevokeControlPermissionGrantResponseObject, error) + + // (GET /v1/control/applications/{application_id}/permission-grants/{grant_id}) + GetControlPermissionGrant(ctx context.Context, request GetControlPermissionGrantRequestObject) (GetControlPermissionGrantResponseObject, error) + // (GET /v1/control/applications/{application_id}/products) ListProducts(ctx context.Context, request ListProductsRequestObject) (ListProductsResponseObject, error) @@ -31688,15 +39489,6 @@ type StrictServerInterface interface { // (POST /v1/control/applications/{application_id}/webhooks/{webhook_id}/test) TestWebhook(ctx context.Context, request TestWebhookRequestObject) (TestWebhookResponseObject, error) - // (GET /v1/control/applications/{application_id}/workspace-invitations) - ListWorkspaceInvitations(ctx context.Context, request ListWorkspaceInvitationsRequestObject) (ListWorkspaceInvitationsResponseObject, error) - - // (POST /v1/control/applications/{application_id}/workspace-invitations) - CreateWorkspaceInvitation(ctx context.Context, request CreateWorkspaceInvitationRequestObject) (CreateWorkspaceInvitationResponseObject, error) - - // (DELETE /v1/control/applications/{application_id}/workspace-invitations/{invitation_id}) - RevokeWorkspaceInvitation(ctx context.Context, request RevokeWorkspaceInvitationRequestObject) (RevokeWorkspaceInvitationResponseObject, error) - // (GET /v1/control/applications/{application_id}/workspaces) ListWorkspaces(ctx context.Context, request ListWorkspacesRequestObject) (ListWorkspacesResponseObject, error) @@ -31725,37 +39517,55 @@ type StrictServerInterface interface { RecoverWorkspaceOwnership(ctx context.Context, request RecoverWorkspaceOwnershipRequestObject) (RecoverWorkspaceOwnershipResponseObject, error) // (POST /v1/control/auth/email/start) - StartOperatorEmailLogin(ctx context.Context, request StartOperatorEmailLoginRequestObject) (StartOperatorEmailLoginResponseObject, error) + StartControlUserEmailLogin(ctx context.Context, request StartControlUserEmailLoginRequestObject) (StartControlUserEmailLoginResponseObject, error) // (POST /v1/control/auth/email/verify) - VerifyOperatorEmailLogin(ctx context.Context, request VerifyOperatorEmailLoginRequestObject) (VerifyOperatorEmailLoginResponseObject, error) + VerifyControlUserEmailLogin(ctx context.Context, request VerifyControlUserEmailLoginRequestObject) (VerifyControlUserEmailLoginResponseObject, error) + + // (DELETE /v1/control/auth/identities/{identity_id}) + UnlinkControlExternalIdentity(ctx context.Context, request UnlinkControlExternalIdentityRequestObject) (UnlinkControlExternalIdentityResponseObject, error) // (POST /v1/control/auth/logout) - LogoutOperator(ctx context.Context, request LogoutOperatorRequestObject) (LogoutOperatorResponseObject, error) + LogoutControlUser(ctx context.Context, request LogoutControlUserRequestObject) (LogoutControlUserResponseObject, error) // (POST /v1/control/auth/logout-all) - LogoutAllOperatorSessions(ctx context.Context, request LogoutAllOperatorSessionsRequestObject) (LogoutAllOperatorSessionsResponseObject, error) + LogoutAllControlUserSessions(ctx context.Context, request LogoutAllControlUserSessionsRequestObject) (LogoutAllControlUserSessionsResponseObject, error) // (GET /v1/control/auth/me) - GetOperatorAccount(ctx context.Context, request GetOperatorAccountRequestObject) (GetOperatorAccountResponseObject, error) + GetControlUserAccount(ctx context.Context, request GetControlUserAccountRequestObject) (GetControlUserAccountResponseObject, error) // (PATCH /v1/control/auth/me) - UpdateOperatorAccount(ctx context.Context, request UpdateOperatorAccountRequestObject) (UpdateOperatorAccountResponseObject, error) + UpdateControlUserAccount(ctx context.Context, request UpdateControlUserAccountRequestObject) (UpdateControlUserAccountResponseObject, error) + + // (GET /v1/control/auth/methods) + GetControlAuthMethods(ctx context.Context, request GetControlAuthMethodsRequestObject) (GetControlAuthMethodsResponseObject, error) // (POST /v1/control/auth/password) - LoginOperatorWithPassword(ctx context.Context, request LoginOperatorWithPasswordRequestObject) (LoginOperatorWithPasswordResponseObject, error) + LoginControlUserWithPassword(ctx context.Context, request LoginControlUserWithPasswordRequestObject) (LoginControlUserWithPasswordResponseObject, error) // (PUT /v1/control/auth/password) - ChangeOperatorPassword(ctx context.Context, request ChangeOperatorPasswordRequestObject) (ChangeOperatorPasswordResponseObject, error) + ChangeControlUserPassword(ctx context.Context, request ChangeControlUserPasswordRequestObject) (ChangeControlUserPasswordResponseObject, error) + + // (POST /v1/control/auth/providers/{provider}/link) + LinkControlExternalIdentity(ctx context.Context, request LinkControlExternalIdentityRequestObject) (LinkControlExternalIdentityResponseObject, error) + + // (POST /v1/control/auth/providers/{provider}/start) + StartControlExternalLogin(ctx context.Context, request StartControlExternalLoginRequestObject) (StartControlExternalLoginResponseObject, error) // (GET /v1/control/auth/sessions) - ListOperatorSessions(ctx context.Context, request ListOperatorSessionsRequestObject) (ListOperatorSessionsResponseObject, error) + ListControlUserSessions(ctx context.Context, request ListControlUserSessionsRequestObject) (ListControlUserSessionsResponseObject, error) // (DELETE /v1/control/auth/sessions/{session_id}) - RevokeOperatorSession(ctx context.Context, request RevokeOperatorSessionRequestObject) (RevokeOperatorSessionResponseObject, error) + RevokeControlUserSession(ctx context.Context, request RevokeControlUserSessionRequestObject) (RevokeControlUserSessionResponseObject, error) // (POST /v1/control/auth/token/refresh) - RefreshOperatorSession(ctx context.Context, request RefreshOperatorSessionRequestObject) (RefreshOperatorSessionResponseObject, error) + RefreshControlUserSession(ctx context.Context, request RefreshControlUserSessionRequestObject) (RefreshControlUserSessionResponseObject, error) + + // (GET /v1/control/installation/auth-policy) + GetControlAuthPolicy(ctx context.Context, request GetControlAuthPolicyRequestObject) (GetControlAuthPolicyResponseObject, error) + + // (PATCH /v1/control/installation/auth-policy) + UpdateControlAuthPolicy(ctx context.Context, request UpdateControlAuthPolicyRequestObject) (UpdateControlAuthPolicyResponseObject, error) // (GET /v1/control/installation/auth/providers) ListInstallationAuthProviders(ctx context.Context, request ListInstallationAuthProvidersRequestObject) (ListInstallationAuthProvidersResponseObject, error) @@ -31787,6 +39597,18 @@ type StrictServerInterface interface { // (POST /v1/control/installation/billing/providers/{provider_id}/verify) VerifyInstallationBillingProvider(ctx context.Context, request VerifyInstallationBillingProviderRequestObject) (VerifyInstallationBillingProviderResponseObject, error) + // (GET /v1/control/installation/invitations) + ListInstallationControlUserInvitations(ctx context.Context, request ListInstallationControlUserInvitationsRequestObject) (ListInstallationControlUserInvitationsResponseObject, error) + + // (POST /v1/control/installation/invitations) + CreateInstallationControlUserInvitation(ctx context.Context, request CreateInstallationControlUserInvitationRequestObject) (CreateInstallationControlUserInvitationResponseObject, error) + + // (DELETE /v1/control/installation/invitations/{invitation_id}) + RevokeInstallationControlUserInvitation(ctx context.Context, request RevokeInstallationControlUserInvitationRequestObject) (RevokeInstallationControlUserInvitationResponseObject, error) + + // (POST /v1/control/installation/invitations/{invitation_id}/resend) + ResendInstallationControlUserInvitation(ctx context.Context, request ResendInstallationControlUserInvitationRequestObject) (ResendInstallationControlUserInvitationResponseObject, error) + // (GET /v1/control/installation/management-api) GetManagementAPIStatus(ctx context.Context, request GetManagementAPIStatusRequestObject) (GetManagementAPIStatusResponseObject, error) @@ -31850,18 +39672,6 @@ type StrictServerInterface interface { // (POST /v1/control/installation/notification-templates/{template_id}/publish) PublishInstallationNotificationTemplate(ctx context.Context, request PublishInstallationNotificationTemplateRequestObject) (PublishInstallationNotificationTemplateResponseObject, error) - // (GET /v1/control/installation/operators) - ListInstallationOperators(ctx context.Context, request ListInstallationOperatorsRequestObject) (ListInstallationOperatorsResponseObject, error) - - // (POST /v1/control/installation/operators) - CreateInstallationOperator(ctx context.Context, request CreateInstallationOperatorRequestObject) (CreateInstallationOperatorResponseObject, error) - - // (DELETE /v1/control/installation/operators/{operator_id}) - DeleteInstallationOperator(ctx context.Context, request DeleteInstallationOperatorRequestObject) (DeleteInstallationOperatorResponseObject, error) - - // (PATCH /v1/control/installation/operators/{operator_id}) - UpdateInstallationOperator(ctx context.Context, request UpdateInstallationOperatorRequestObject) (UpdateInstallationOperatorResponseObject, error) - // (PUT /v1/control/installation/organizations/{organization_id}/policy) UpdateOrganizationPolicy(ctx context.Context, request UpdateOrganizationPolicyRequestObject) (UpdateOrganizationPolicyResponseObject, error) @@ -31910,8 +39720,20 @@ type StrictServerInterface interface { // (POST /v1/control/installation/storage/uploads/{object_id}/complete) CompleteInstallationStorageUpload(ctx context.Context, request CompleteInstallationStorageUploadRequestObject) (CompleteInstallationStorageUploadResponseObject, error) - // (POST /v1/control/organization-invitations/accept) - AcceptOrganizationInvitation(ctx context.Context, request AcceptOrganizationInvitationRequestObject) (AcceptOrganizationInvitationResponseObject, error) + // (GET /v1/control/installation/users) + ListInstallationControlUsers(ctx context.Context, request ListInstallationControlUsersRequestObject) (ListInstallationControlUsersResponseObject, error) + + // (DELETE /v1/control/installation/users/{control_user_id}) + DeleteInstallationControlUser(ctx context.Context, request DeleteInstallationControlUserRequestObject) (DeleteInstallationControlUserResponseObject, error) + + // (PATCH /v1/control/installation/users/{control_user_id}) + UpdateInstallationControlUser(ctx context.Context, request UpdateInstallationControlUserRequestObject) (UpdateInstallationControlUserResponseObject, error) + + // (POST /v1/control/invitations/accept) + AcceptControlUserInvitation(ctx context.Context, request AcceptControlUserInvitationRequestObject) (AcceptControlUserInvitationResponseObject, error) + + // (POST /v1/control/invitations/providers/{provider}/start) + StartControlInvitationExternalLogin(ctx context.Context, request StartControlInvitationExternalLoginRequestObject) (StartControlInvitationExternalLoginResponseObject, error) // (GET /v1/control/organizations) ListOrganizations(ctx context.Context, request ListOrganizationsRequestObject) (ListOrganizationsResponseObject, error) @@ -32527,6 +40349,72 @@ func (sh *strictHandler) EmailVerify(w http.ResponseWriter, r *http.Request, app } } +// ExchangeApplicationInvitation operation middleware +func (sh *strictHandler) ExchangeApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request ExchangeApplicationInvitationRequestObject + + request.ApplicationId = applicationId + + var body ExchangeApplicationInvitationJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ExchangeApplicationInvitation(ctx, request.(ExchangeApplicationInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ExchangeApplicationInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ExchangeApplicationInvitationResponseObject); ok { + if err := validResponse.VisitExchangeApplicationInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// RedeemApplicationInvitation operation middleware +func (sh *strictHandler) RedeemApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request RedeemApplicationInvitationRequestObject + + request.ApplicationId = applicationId + + var body RedeemApplicationInvitationJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RedeemApplicationInvitation(ctx, request.(RedeemApplicationInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RedeemApplicationInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RedeemApplicationInvitationResponseObject); ok { + if err := validResponse.VisitRedeemApplicationInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // LogoutCurrentSession operation middleware func (sh *strictHandler) LogoutCurrentSession(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request LogoutCurrentSessionRequestObject @@ -32559,13 +40447,6 @@ func (sh *strictHandler) AuthMethods(w http.ResponseWriter, r *http.Request, app request.ApplicationId = applicationId - var body AuthMethodsJSONRequestBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) - return - } - request.Body = &body - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { return sh.ssi.AuthMethods(ctx, request.(AuthMethodsRequestObject)) } @@ -32843,43 +40724,6 @@ func (sh *strictHandler) ListAuthProviders(w http.ResponseWriter, r *http.Reques } } -// AppleAuthCallback operation middleware -func (sh *strictHandler) AppleAuthCallback(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - var request AppleAuthCallbackRequestObject - - request.ApplicationId = applicationId - - if err := r.ParseForm(); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode formdata: %w", err)) - return - } - var body AppleAuthCallbackFormdataRequestBody - if err := runtime.BindForm(&body, r.Form, nil, nil); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't bind formdata: %w", err)) - return - } - request.Body = &body - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.AppleAuthCallback(ctx, request.(AppleAuthCallbackRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "AppleAuthCallback") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(AppleAuthCallbackResponseObject); ok { - if err := validResponse.VisitAppleAuthCallbackResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - // ExchangeAppleAuth operation middleware func (sh *strictHandler) ExchangeAppleAuth(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request ExchangeAppleAuthRequestObject @@ -32946,32 +40790,6 @@ func (sh *strictHandler) StartAppleAuth(w http.ResponseWriter, r *http.Request, } } -// GoogleAuthCallback operation middleware -func (sh *strictHandler) GoogleAuthCallback(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - var request GoogleAuthCallbackRequestObject - - request.ApplicationId = applicationId - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.GoogleAuthCallback(ctx, request.(GoogleAuthCallbackRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "GoogleAuthCallback") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(GoogleAuthCallbackResponseObject); ok { - if err := validResponse.VisitGoogleAuthCallbackResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - // ExchangeGoogleAuth operation middleware func (sh *strictHandler) ExchangeGoogleAuth(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request ExchangeGoogleAuthRequestObject @@ -33260,6 +41078,146 @@ func (sh *strictHandler) PublishCustomEvent(w http.ResponseWriter, r *http.Reque } } +// ListApplicationInvitations operation middleware +func (sh *strictHandler) ListApplicationInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request ListApplicationInvitationsRequestObject + + request.ApplicationId = applicationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListApplicationInvitations(ctx, request.(ListApplicationInvitationsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListApplicationInvitations") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListApplicationInvitationsResponseObject); ok { + if err := validResponse.VisitListApplicationInvitationsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// CreateApplicationInvitationMachine operation middleware +func (sh *strictHandler) CreateApplicationInvitationMachine(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request CreateApplicationInvitationMachineRequestObject + + request.ApplicationId = applicationId + + var body CreateApplicationInvitationMachineJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.CreateApplicationInvitationMachine(ctx, request.(CreateApplicationInvitationMachineRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "CreateApplicationInvitationMachine") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(CreateApplicationInvitationMachineResponseObject); ok { + if err := validResponse.VisitCreateApplicationInvitationMachineResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// RevokeApplicationInvitation operation middleware +func (sh *strictHandler) RevokeApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + var request RevokeApplicationInvitationRequestObject + + request.ApplicationId = applicationId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokeApplicationInvitation(ctx, request.(RevokeApplicationInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RevokeApplicationInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RevokeApplicationInvitationResponseObject); ok { + if err := validResponse.VisitRevokeApplicationInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetApplicationInvitation operation middleware +func (sh *strictHandler) GetApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + var request GetApplicationInvitationRequestObject + + request.ApplicationId = applicationId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetApplicationInvitation(ctx, request.(GetApplicationInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetApplicationInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetApplicationInvitationResponseObject); ok { + if err := validResponse.VisitGetApplicationInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ResendApplicationInvitation operation middleware +func (sh *strictHandler) ResendApplicationInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + var request ResendApplicationInvitationRequestObject + + request.ApplicationId = applicationId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ResendApplicationInvitation(ctx, request.(ResendApplicationInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ResendApplicationInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ResendApplicationInvitationResponseObject); ok { + if err := validResponse.VisitResendApplicationInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // LocalEntitlementCheckout operation middleware func (sh *strictHandler) LocalEntitlementCheckout(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params LocalEntitlementCheckoutParams) { var request LocalEntitlementCheckoutRequestObject @@ -34816,25 +42774,51 @@ func (sh *strictHandler) ListMySubscriptions(w http.ResponseWriter, r *http.Requ } } -// ListMyWorkspaceInvitations operation middleware -func (sh *strictHandler) ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - var request ListMyWorkspaceInvitationsRequestObject +// ListMyPendingInvitations operation middleware +func (sh *strictHandler) ListMyPendingInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request ListMyPendingInvitationsRequestObject request.ApplicationId = applicationId handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.ListMyWorkspaceInvitations(ctx, request.(ListMyWorkspaceInvitationsRequestObject)) + return sh.ssi.ListMyPendingInvitations(ctx, request.(ListMyPendingInvitationsRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "ListMyWorkspaceInvitations") + handler = middleware(handler, "ListMyPendingInvitations") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(ListMyWorkspaceInvitationsResponseObject); ok { - if err := validResponse.VisitListMyWorkspaceInvitationsResponse(w); err != nil { + } else if validResponse, ok := response.(ListMyPendingInvitationsResponseObject); ok { + if err := validResponse.VisitListMyPendingInvitationsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ListMyWorkspaces operation middleware +func (sh *strictHandler) ListMyWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request ListMyWorkspacesRequestObject + + request.ApplicationId = applicationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListMyWorkspaces(ctx, request.(ListMyWorkspacesRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListMyWorkspaces") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListMyWorkspacesResponseObject); ok { + if err := validResponse.VisitListMyWorkspacesResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -34842,14 +42826,108 @@ func (sh *strictHandler) ListMyWorkspaceInvitations(w http.ResponseWriter, r *ht } } -// AcceptMyWorkspaceInvitation operation middleware -func (sh *strictHandler) AcceptMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { - var request AcceptMyWorkspaceInvitationRequestObject +// CreateMyWorkspace operation middleware +func (sh *strictHandler) CreateMyWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request CreateMyWorkspaceRequestObject request.ApplicationId = applicationId - request.InvitationId = invitationId - var body AcceptMyWorkspaceInvitationJSONRequestBody + var body CreateMyWorkspaceJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.CreateMyWorkspace(ctx, request.(CreateMyWorkspaceRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "CreateMyWorkspace") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(CreateMyWorkspaceResponseObject); ok { + if err := validResponse.VisitCreateMyWorkspaceResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// SendMachineNotification operation middleware +func (sh *strictHandler) SendMachineNotification(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params SendMachineNotificationParams) { + var request SendMachineNotificationRequestObject + + request.ApplicationId = applicationId + request.Params = params + + var body SendMachineNotificationJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.SendMachineNotification(ctx, request.(SendMachineNotificationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "SendMachineNotification") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(SendMachineNotificationResponseObject); ok { + if err := validResponse.VisitSendMachineNotificationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ListPermissionGrants operation middleware +func (sh *strictHandler) ListPermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params ListPermissionGrantsParams) { + var request ListPermissionGrantsRequestObject + + request.ApplicationId = applicationId + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListPermissionGrants(ctx, request.(ListPermissionGrantsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListPermissionGrants") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListPermissionGrantsResponseObject); ok { + if err := validResponse.VisitListPermissionGrantsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// CreatePermissionGrant operation middleware +func (sh *strictHandler) CreatePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params CreatePermissionGrantParams) { + var request CreatePermissionGrantRequestObject + + request.ApplicationId = applicationId + request.Params = params + + var body CreatePermissionGrantJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) return @@ -34857,18 +42935,18 @@ func (sh *strictHandler) AcceptMyWorkspaceInvitation(w http.ResponseWriter, r *h request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.AcceptMyWorkspaceInvitation(ctx, request.(AcceptMyWorkspaceInvitationRequestObject)) + return sh.ssi.CreatePermissionGrant(ctx, request.(CreatePermissionGrantRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "AcceptMyWorkspaceInvitation") + handler = middleware(handler, "CreatePermissionGrant") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(AcceptMyWorkspaceInvitationResponseObject); ok { - if err := validResponse.VisitAcceptMyWorkspaceInvitationResponse(w); err != nil { + } else if validResponse, ok := response.(CreatePermissionGrantResponseObject); ok { + if err := validResponse.VisitCreatePermissionGrantResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -34876,25 +42954,26 @@ func (sh *strictHandler) AcceptMyWorkspaceInvitation(w http.ResponseWriter, r *h } } -// ListMyWorkspaces operation middleware -func (sh *strictHandler) ListMyWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - var request ListMyWorkspacesRequestObject +// GetEffectiveAccess operation middleware +func (sh *strictHandler) GetEffectiveAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params GetEffectiveAccessParams) { + var request GetEffectiveAccessRequestObject request.ApplicationId = applicationId + request.Params = params handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.ListMyWorkspaces(ctx, request.(ListMyWorkspacesRequestObject)) + return sh.ssi.GetEffectiveAccess(ctx, request.(GetEffectiveAccessRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "ListMyWorkspaces") + handler = middleware(handler, "GetEffectiveAccess") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(ListMyWorkspacesResponseObject); ok { - if err := validResponse.VisitListMyWorkspacesResponse(w); err != nil { + } else if validResponse, ok := response.(GetEffectiveAccessResponseObject); ok { + if err := validResponse.VisitGetEffectiveAccessResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -34902,32 +42981,54 @@ func (sh *strictHandler) ListMyWorkspaces(w http.ResponseWriter, r *http.Request } } -// CreateMyWorkspace operation middleware -func (sh *strictHandler) CreateMyWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - var request CreateMyWorkspaceRequestObject +// RevokePermissionGrant operation middleware +func (sh *strictHandler) RevokePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID, params RevokePermissionGrantParams) { + var request RevokePermissionGrantRequestObject request.ApplicationId = applicationId + request.GrantId = grantId + request.Params = params - var body CreateMyWorkspaceJSONRequestBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) - return + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokePermissionGrant(ctx, request.(RevokePermissionGrantRequestObject)) } - request.Body = &body + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RevokePermissionGrant") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RevokePermissionGrantResponseObject); ok { + if err := validResponse.VisitRevokePermissionGrantResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetPermissionGrant operation middleware +func (sh *strictHandler) GetPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID) { + var request GetPermissionGrantRequestObject + + request.ApplicationId = applicationId + request.GrantId = grantId handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.CreateMyWorkspace(ctx, request.(CreateMyWorkspaceRequestObject)) + return sh.ssi.GetPermissionGrant(ctx, request.(GetPermissionGrantRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "CreateMyWorkspace") + handler = middleware(handler, "GetPermissionGrant") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(CreateMyWorkspaceResponseObject); ok { - if err := validResponse.VisitCreateMyWorkspaceResponse(w); err != nil { + } else if validResponse, ok := response.(GetPermissionGrantResponseObject); ok { + if err := validResponse.VisitGetPermissionGrantResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -34961,6 +43062,60 @@ func (sh *strictHandler) PublicConfig(w http.ResponseWriter, r *http.Request, ap } } +// ServiceGetApplicationWorkspace operation middleware +func (sh *strictHandler) ServiceGetApplicationWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + var request ServiceGetApplicationWorkspaceRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ServiceGetApplicationWorkspace(ctx, request.(ServiceGetApplicationWorkspaceRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ServiceGetApplicationWorkspace") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ServiceGetApplicationWorkspaceResponseObject); ok { + if err := validResponse.VisitServiceGetApplicationWorkspaceResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ServiceListApplicationWorkspaceAccess operation middleware +func (sh *strictHandler) ServiceListApplicationWorkspaceAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + var request ServiceListApplicationWorkspaceAccessRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ServiceListApplicationWorkspaceAccess(ctx, request.(ServiceListApplicationWorkspaceAccessRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ServiceListApplicationWorkspaceAccess") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ServiceListApplicationWorkspaceAccessResponseObject); ok { + if err := validResponse.VisitServiceListApplicationWorkspaceAccessResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // ListApplicationStorageObjects operation middleware func (sh *strictHandler) ListApplicationStorageObjects(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request ListApplicationStorageObjectsRequestObject @@ -35129,6 +43284,141 @@ func (sh *strictHandler) CompleteApplicationStorageUpload(w http.ResponseWriter, } } +// ServiceGetSubjectBilling operation middleware +func (sh *strictHandler) ServiceGetSubjectBilling(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, subjectType interface{}, subjectId UUID) { + var request ServiceGetSubjectBillingRequestObject + + request.ApplicationId = applicationId + request.SubjectType = subjectType + request.SubjectId = subjectId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ServiceGetSubjectBilling(ctx, request.(ServiceGetSubjectBillingRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ServiceGetSubjectBilling") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ServiceGetSubjectBillingResponseObject); ok { + if err := validResponse.VisitServiceGetSubjectBillingResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ServiceGetSubjectEntitlements operation middleware +func (sh *strictHandler) ServiceGetSubjectEntitlements(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, subjectType interface{}, subjectId UUID) { + var request ServiceGetSubjectEntitlementsRequestObject + + request.ApplicationId = applicationId + request.SubjectType = subjectType + request.SubjectId = subjectId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ServiceGetSubjectEntitlements(ctx, request.(ServiceGetSubjectEntitlementsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ServiceGetSubjectEntitlements") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ServiceGetSubjectEntitlementsResponseObject); ok { + if err := validResponse.VisitServiceGetSubjectEntitlementsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ServiceListApplicationUsers operation middleware +func (sh *strictHandler) ServiceListApplicationUsers(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request ServiceListApplicationUsersRequestObject + + request.ApplicationId = applicationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ServiceListApplicationUsers(ctx, request.(ServiceListApplicationUsersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ServiceListApplicationUsers") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ServiceListApplicationUsersResponseObject); ok { + if err := validResponse.VisitServiceListApplicationUsersResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ServiceGetApplicationUser operation middleware +func (sh *strictHandler) ServiceGetApplicationUser(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, userId UUID) { + var request ServiceGetApplicationUserRequestObject + + request.ApplicationId = applicationId + request.UserId = userId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ServiceGetApplicationUser(ctx, request.(ServiceGetApplicationUserRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ServiceGetApplicationUser") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ServiceGetApplicationUserResponseObject); ok { + if err := validResponse.VisitServiceGetApplicationUserResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ServiceListApplicationWorkspaces operation middleware +func (sh *strictHandler) ServiceListApplicationWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request ServiceListApplicationWorkspacesRequestObject + + request.ApplicationId = applicationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ServiceListApplicationWorkspaces(ctx, request.(ServiceListApplicationWorkspacesRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ServiceListApplicationWorkspaces") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ServiceListApplicationWorkspacesResponseObject); ok { + if err := validResponse.VisitServiceListApplicationWorkspacesResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // ArchiveMyWorkspace operation middleware func (sh *strictHandler) ArchiveMyWorkspace(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { var request ArchiveMyWorkspaceRequestObject @@ -35217,6 +43507,33 @@ func (sh *strictHandler) UpdateMyWorkspace(w http.ResponseWriter, r *http.Reques } } +// ListMyWorkspaceAccess operation middleware +func (sh *strictHandler) ListMyWorkspaceAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + var request ListMyWorkspaceAccessRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListMyWorkspaceAccess(ctx, request.(ListMyWorkspaceAccessRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListMyWorkspaceAccess") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListMyWorkspaceAccessResponseObject); ok { + if err := validResponse.VisitListMyWorkspaceAccessResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // ListWorkspaceAddresses operation middleware func (sh *strictHandler) ListWorkspaceAddresses(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { var request ListWorkspaceAddressesRequestObject @@ -35430,6 +43747,33 @@ func (sh *strictHandler) UpdateWorkspaceBillingProfile(w http.ResponseWriter, r } } +// ListMyWorkspaceInvitations operation middleware +func (sh *strictHandler) ListMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { + var request ListMyWorkspaceInvitationsRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListMyWorkspaceInvitations(ctx, request.(ListMyWorkspaceInvitationsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListMyWorkspaceInvitations") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListMyWorkspaceInvitationsResponseObject); ok { + if err := validResponse.VisitListMyWorkspaceInvitationsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // CreateMyWorkspaceInvitation operation middleware func (sh *strictHandler) CreateMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { var request CreateMyWorkspaceInvitationRequestObject @@ -35464,6 +43808,62 @@ func (sh *strictHandler) CreateMyWorkspaceInvitation(w http.ResponseWriter, r *h } } +// RevokeMyWorkspaceInvitation operation middleware +func (sh *strictHandler) RevokeMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID, invitationId UUID) { + var request RevokeMyWorkspaceInvitationRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokeMyWorkspaceInvitation(ctx, request.(RevokeMyWorkspaceInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RevokeMyWorkspaceInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RevokeMyWorkspaceInvitationResponseObject); ok { + if err := validResponse.VisitRevokeMyWorkspaceInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ResendMyWorkspaceInvitation operation middleware +func (sh *strictHandler) ResendMyWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID, invitationId UUID) { + var request ResendMyWorkspaceInvitationRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ResendMyWorkspaceInvitation(ctx, request.(ResendMyWorkspaceInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ResendMyWorkspaceInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ResendMyWorkspaceInvitationResponseObject); ok { + if err := validResponse.VisitResendMyWorkspaceInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // ListMyWorkspaceMembers operation middleware func (sh *strictHandler) ListMyWorkspaceMembers(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId UUID) { var request ListMyWorkspaceMembersRequestObject @@ -35615,6 +44015,126 @@ func (sh *strictHandler) TransferMyWorkspaceOwnership(w http.ResponseWriter, r * } } +// ListWorkspacePermissionGrants operation middleware +func (sh *strictHandler) ListWorkspacePermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, params ListWorkspacePermissionGrantsParams) { + var request ListWorkspacePermissionGrantsRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListWorkspacePermissionGrants(ctx, request.(ListWorkspacePermissionGrantsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListWorkspacePermissionGrants") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListWorkspacePermissionGrantsResponseObject); ok { + if err := validResponse.VisitListWorkspacePermissionGrantsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// CreateWorkspacePermissionGrant operation middleware +func (sh *strictHandler) CreateWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, params CreateWorkspacePermissionGrantParams) { + var request CreateWorkspacePermissionGrantRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + request.Params = params + + var body CreateWorkspacePermissionGrantJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.CreateWorkspacePermissionGrant(ctx, request.(CreateWorkspacePermissionGrantRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "CreateWorkspacePermissionGrant") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(CreateWorkspacePermissionGrantResponseObject); ok { + if err := validResponse.VisitCreateWorkspacePermissionGrantResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// RevokeWorkspacePermissionGrant operation middleware +func (sh *strictHandler) RevokeWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, grantId UUID, params RevokeWorkspacePermissionGrantParams) { + var request RevokeWorkspacePermissionGrantRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + request.GrantId = grantId + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokeWorkspacePermissionGrant(ctx, request.(RevokeWorkspacePermissionGrantRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RevokeWorkspacePermissionGrant") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RevokeWorkspacePermissionGrantResponseObject); ok { + if err := validResponse.VisitRevokeWorkspacePermissionGrantResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetWorkspacePermissionGrant operation middleware +func (sh *strictHandler) GetWorkspacePermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID, grantId UUID) { + var request GetWorkspacePermissionGrantRequestObject + + request.ApplicationId = applicationId + request.WorkspaceId = workspaceId + request.GrantId = grantId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetWorkspacePermissionGrant(ctx, request.(GetWorkspacePermissionGrantRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetWorkspacePermissionGrant") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetWorkspacePermissionGrantResponseObject); ok { + if err := validResponse.VisitGetWorkspacePermissionGrantResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // ListWorkspaceStorageObjects operation middleware func (sh *strictHandler) ListWorkspaceStorageObjects(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, workspaceId WorkspaceID) { var request ListWorkspaceStorageObjectsRequestObject @@ -35789,6 +44309,65 @@ func (sh *strictHandler) CompleteWorkspaceStorageUpload(w http.ResponseWriter, r } } +// AppleAuthCallback operation middleware +func (sh *strictHandler) AppleAuthCallback(w http.ResponseWriter, r *http.Request) { + var request AppleAuthCallbackRequestObject + + if err := r.ParseForm(); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode formdata: %w", err)) + return + } + var body AppleAuthCallbackFormdataRequestBody + if err := runtime.BindForm(&body, r.Form, nil, nil); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't bind formdata: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.AppleAuthCallback(ctx, request.(AppleAuthCallbackRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "AppleAuthCallback") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(AppleAuthCallbackResponseObject); ok { + if err := validResponse.VisitAppleAuthCallbackResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GoogleAuthCallback operation middleware +func (sh *strictHandler) GoogleAuthCallback(w http.ResponseWriter, r *http.Request) { + var request GoogleAuthCallbackRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GoogleAuthCallback(ctx, request.(GoogleAuthCallbackRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GoogleAuthCallback") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GoogleAuthCallbackResponseObject); ok { + if err := validResponse.VisitGoogleAuthCallbackResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // GetApplication operation middleware func (sh *strictHandler) GetApplication(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request GetApplicationRequestObject @@ -36899,6 +45478,33 @@ func (sh *strictHandler) DisableClient(w http.ResponseWriter, r *http.Request, a } } +// GetClient operation middleware +func (sh *strictHandler) GetClient(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, clientId string) { + var request GetClientRequestObject + + request.ApplicationId = applicationId + request.ClientId = clientId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetClient(ctx, request.(GetClientRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetClient") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetClientResponseObject); ok { + if err := validResponse.VisitGetClientResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // UpdateClient operation middleware func (sh *strictHandler) UpdateClient(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, clientId string) { var request UpdateClientRequestObject @@ -37272,6 +45878,40 @@ func (sh *strictHandler) GetEntitlement(w http.ResponseWriter, r *http.Request, } } +// AdjustEntitlement operation middleware +func (sh *strictHandler) AdjustEntitlement(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, entitlementId UUID) { + var request AdjustEntitlementRequestObject + + request.ApplicationId = applicationId + request.EntitlementId = entitlementId + + var body AdjustEntitlementJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.AdjustEntitlement(ctx, request.(AdjustEntitlementRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "AdjustEntitlement") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(AdjustEntitlementResponseObject); ok { + if err := validResponse.VisitAdjustEntitlementResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // RestoreEntitlement operation middleware func (sh *strictHandler) RestoreEntitlement(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, entitlementId UUID) { var request RestoreEntitlementRequestObject @@ -37632,6 +46272,146 @@ func (sh *strictHandler) UpdateInternalApplicationConfig(w http.ResponseWriter, } } +// ListApplicationInvitationsControl operation middleware +func (sh *strictHandler) ListApplicationInvitationsControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request ListApplicationInvitationsControlRequestObject + + request.ApplicationId = applicationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListApplicationInvitationsControl(ctx, request.(ListApplicationInvitationsControlRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListApplicationInvitationsControl") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListApplicationInvitationsControlResponseObject); ok { + if err := validResponse.VisitListApplicationInvitationsControlResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// CreateApplicationInvitationControl operation middleware +func (sh *strictHandler) CreateApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { + var request CreateApplicationInvitationControlRequestObject + + request.ApplicationId = applicationId + + var body CreateApplicationInvitationControlJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.CreateApplicationInvitationControl(ctx, request.(CreateApplicationInvitationControlRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "CreateApplicationInvitationControl") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(CreateApplicationInvitationControlResponseObject); ok { + if err := validResponse.VisitCreateApplicationInvitationControlResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// RevokeApplicationInvitationControl operation middleware +func (sh *strictHandler) RevokeApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + var request RevokeApplicationInvitationControlRequestObject + + request.ApplicationId = applicationId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokeApplicationInvitationControl(ctx, request.(RevokeApplicationInvitationControlRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RevokeApplicationInvitationControl") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RevokeApplicationInvitationControlResponseObject); ok { + if err := validResponse.VisitRevokeApplicationInvitationControlResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetApplicationInvitationControl operation middleware +func (sh *strictHandler) GetApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + var request GetApplicationInvitationControlRequestObject + + request.ApplicationId = applicationId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetApplicationInvitationControl(ctx, request.(GetApplicationInvitationControlRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetApplicationInvitationControl") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetApplicationInvitationControlResponseObject); ok { + if err := validResponse.VisitGetApplicationInvitationControlResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ResendApplicationInvitationControl operation middleware +func (sh *strictHandler) ResendApplicationInvitationControl(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { + var request ResendApplicationInvitationControlRequestObject + + request.ApplicationId = applicationId + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ResendApplicationInvitationControl(ctx, request.(ResendApplicationInvitationControlRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ResendApplicationInvitationControl") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ResendApplicationInvitationControlResponseObject); ok { + if err := validResponse.VisitResendApplicationInvitationControlResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // ListLocalEntitlementRequests operation middleware func (sh *strictHandler) ListLocalEntitlementRequests(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request ListLocalEntitlementRequestsRequestObject @@ -38256,40 +47036,6 @@ func (sh *strictHandler) ListNotifications(w http.ResponseWriter, r *http.Reques } } -// QueueNotification operation middleware -func (sh *strictHandler) QueueNotification(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params QueueNotificationParams) { - var request QueueNotificationRequestObject - - request.ApplicationId = applicationId - request.Params = params - - var body QueueNotificationJSONRequestBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) - return - } - request.Body = &body - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.QueueNotification(ctx, request.(QueueNotificationRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "QueueNotification") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(QueueNotificationResponseObject); ok { - if err := validResponse.VisitQueueNotificationResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - // GetNotificationStatistics operation middleware func (sh *strictHandler) GetNotificationStatistics(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request GetNotificationStatisticsRequestObject @@ -38424,6 +47170,149 @@ func (sh *strictHandler) RevokeOAuthConsent(w http.ResponseWriter, r *http.Reque } } +// ListControlPermissionGrants operation middleware +func (sh *strictHandler) ListControlPermissionGrants(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params ListControlPermissionGrantsParams) { + var request ListControlPermissionGrantsRequestObject + + request.ApplicationId = applicationId + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListControlPermissionGrants(ctx, request.(ListControlPermissionGrantsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListControlPermissionGrants") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListControlPermissionGrantsResponseObject); ok { + if err := validResponse.VisitListControlPermissionGrantsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// CreateControlPermissionGrant operation middleware +func (sh *strictHandler) CreateControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params CreateControlPermissionGrantParams) { + var request CreateControlPermissionGrantRequestObject + + request.ApplicationId = applicationId + request.Params = params + + var body CreateControlPermissionGrantJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.CreateControlPermissionGrant(ctx, request.(CreateControlPermissionGrantRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "CreateControlPermissionGrant") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(CreateControlPermissionGrantResponseObject); ok { + if err := validResponse.VisitCreateControlPermissionGrantResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetControlEffectiveAccess operation middleware +func (sh *strictHandler) GetControlEffectiveAccess(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, params GetControlEffectiveAccessParams) { + var request GetControlEffectiveAccessRequestObject + + request.ApplicationId = applicationId + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetControlEffectiveAccess(ctx, request.(GetControlEffectiveAccessRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetControlEffectiveAccess") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetControlEffectiveAccessResponseObject); ok { + if err := validResponse.VisitGetControlEffectiveAccessResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// RevokeControlPermissionGrant operation middleware +func (sh *strictHandler) RevokeControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID, params RevokeControlPermissionGrantParams) { + var request RevokeControlPermissionGrantRequestObject + + request.ApplicationId = applicationId + request.GrantId = grantId + request.Params = params + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokeControlPermissionGrant(ctx, request.(RevokeControlPermissionGrantRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RevokeControlPermissionGrant") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RevokeControlPermissionGrantResponseObject); ok { + if err := validResponse.VisitRevokeControlPermissionGrantResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// GetControlPermissionGrant operation middleware +func (sh *strictHandler) GetControlPermissionGrant(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, grantId UUID) { + var request GetControlPermissionGrantRequestObject + + request.ApplicationId = applicationId + request.GrantId = grantId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetControlPermissionGrant(ctx, request.(GetControlPermissionGrantRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetControlPermissionGrant") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetControlPermissionGrantResponseObject); ok { + if err := validResponse.VisitGetControlPermissionGrantResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // ListProducts operation middleware func (sh *strictHandler) ListProducts(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request ListProductsRequestObject @@ -38838,11 +47727,12 @@ func (sh *strictHandler) GetRole(w http.ResponseWriter, r *http.Request, applica } // UpdateRole operation middleware -func (sh *strictHandler) UpdateRole(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, roleId UUID) { +func (sh *strictHandler) UpdateRole(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, roleId UUID, params UpdateRoleParams) { var request UpdateRoleRequestObject request.ApplicationId = applicationId request.RoleId = roleId + request.Params = params var body UpdateRoleJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { @@ -40041,92 +48931,6 @@ func (sh *strictHandler) TestWebhook(w http.ResponseWriter, r *http.Request, app } } -// ListWorkspaceInvitations operation middleware -func (sh *strictHandler) ListWorkspaceInvitations(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - var request ListWorkspaceInvitationsRequestObject - - request.ApplicationId = applicationId - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.ListWorkspaceInvitations(ctx, request.(ListWorkspaceInvitationsRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "ListWorkspaceInvitations") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(ListWorkspaceInvitationsResponseObject); ok { - if err := validResponse.VisitListWorkspaceInvitationsResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - -// CreateWorkspaceInvitation operation middleware -func (sh *strictHandler) CreateWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { - var request CreateWorkspaceInvitationRequestObject - - request.ApplicationId = applicationId - - var body CreateWorkspaceInvitationJSONRequestBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) - return - } - request.Body = &body - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.CreateWorkspaceInvitation(ctx, request.(CreateWorkspaceInvitationRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "CreateWorkspaceInvitation") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(CreateWorkspaceInvitationResponseObject); ok { - if err := validResponse.VisitCreateWorkspaceInvitationResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - -// RevokeWorkspaceInvitation operation middleware -func (sh *strictHandler) RevokeWorkspaceInvitation(w http.ResponseWriter, r *http.Request, applicationId ApplicationID, invitationId UUID) { - var request RevokeWorkspaceInvitationRequestObject - - request.ApplicationId = applicationId - request.InvitationId = invitationId - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.RevokeWorkspaceInvitation(ctx, request.(RevokeWorkspaceInvitationRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "RevokeWorkspaceInvitation") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(RevokeWorkspaceInvitationResponseObject); ok { - if err := validResponse.VisitRevokeWorkspaceInvitationResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - // ListWorkspaces operation middleware func (sh *strictHandler) ListWorkspaces(w http.ResponseWriter, r *http.Request, applicationId ApplicationID) { var request ListWorkspacesRequestObject @@ -40398,11 +49202,11 @@ func (sh *strictHandler) RecoverWorkspaceOwnership(w http.ResponseWriter, r *htt } } -// StartOperatorEmailLogin operation middleware -func (sh *strictHandler) StartOperatorEmailLogin(w http.ResponseWriter, r *http.Request) { - var request StartOperatorEmailLoginRequestObject +// StartControlUserEmailLogin operation middleware +func (sh *strictHandler) StartControlUserEmailLogin(w http.ResponseWriter, r *http.Request) { + var request StartControlUserEmailLoginRequestObject - var body StartOperatorEmailLoginJSONRequestBody + var body StartControlUserEmailLoginJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) return @@ -40410,18 +49214,18 @@ func (sh *strictHandler) StartOperatorEmailLogin(w http.ResponseWriter, r *http. request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.StartOperatorEmailLogin(ctx, request.(StartOperatorEmailLoginRequestObject)) + return sh.ssi.StartControlUserEmailLogin(ctx, request.(StartControlUserEmailLoginRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "StartOperatorEmailLogin") + handler = middleware(handler, "StartControlUserEmailLogin") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(StartOperatorEmailLoginResponseObject); ok { - if err := validResponse.VisitStartOperatorEmailLoginResponse(w); err != nil { + } else if validResponse, ok := response.(StartControlUserEmailLoginResponseObject); ok { + if err := validResponse.VisitStartControlUserEmailLoginResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40429,11 +49233,11 @@ func (sh *strictHandler) StartOperatorEmailLogin(w http.ResponseWriter, r *http. } } -// VerifyOperatorEmailLogin operation middleware -func (sh *strictHandler) VerifyOperatorEmailLogin(w http.ResponseWriter, r *http.Request) { - var request VerifyOperatorEmailLoginRequestObject +// VerifyControlUserEmailLogin operation middleware +func (sh *strictHandler) VerifyControlUserEmailLogin(w http.ResponseWriter, r *http.Request) { + var request VerifyControlUserEmailLoginRequestObject - var body VerifyOperatorEmailLoginJSONRequestBody + var body VerifyControlUserEmailLoginJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) return @@ -40441,18 +49245,44 @@ func (sh *strictHandler) VerifyOperatorEmailLogin(w http.ResponseWriter, r *http request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.VerifyOperatorEmailLogin(ctx, request.(VerifyOperatorEmailLoginRequestObject)) + return sh.ssi.VerifyControlUserEmailLogin(ctx, request.(VerifyControlUserEmailLoginRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "VerifyControlUserEmailLogin") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(VerifyControlUserEmailLoginResponseObject); ok { + if err := validResponse.VisitVerifyControlUserEmailLoginResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// UnlinkControlExternalIdentity operation middleware +func (sh *strictHandler) UnlinkControlExternalIdentity(w http.ResponseWriter, r *http.Request, identityId UUID) { + var request UnlinkControlExternalIdentityRequestObject + + request.IdentityId = identityId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.UnlinkControlExternalIdentity(ctx, request.(UnlinkControlExternalIdentityRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "VerifyOperatorEmailLogin") + handler = middleware(handler, "UnlinkControlExternalIdentity") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(VerifyOperatorEmailLoginResponseObject); ok { - if err := validResponse.VisitVerifyOperatorEmailLoginResponse(w); err != nil { + } else if validResponse, ok := response.(UnlinkControlExternalIdentityResponseObject); ok { + if err := validResponse.VisitUnlinkControlExternalIdentityResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40460,23 +49290,23 @@ func (sh *strictHandler) VerifyOperatorEmailLogin(w http.ResponseWriter, r *http } } -// LogoutOperator operation middleware -func (sh *strictHandler) LogoutOperator(w http.ResponseWriter, r *http.Request) { - var request LogoutOperatorRequestObject +// LogoutControlUser operation middleware +func (sh *strictHandler) LogoutControlUser(w http.ResponseWriter, r *http.Request) { + var request LogoutControlUserRequestObject handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.LogoutOperator(ctx, request.(LogoutOperatorRequestObject)) + return sh.ssi.LogoutControlUser(ctx, request.(LogoutControlUserRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "LogoutOperator") + handler = middleware(handler, "LogoutControlUser") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(LogoutOperatorResponseObject); ok { - if err := validResponse.VisitLogoutOperatorResponse(w); err != nil { + } else if validResponse, ok := response.(LogoutControlUserResponseObject); ok { + if err := validResponse.VisitLogoutControlUserResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40484,23 +49314,23 @@ func (sh *strictHandler) LogoutOperator(w http.ResponseWriter, r *http.Request) } } -// LogoutAllOperatorSessions operation middleware -func (sh *strictHandler) LogoutAllOperatorSessions(w http.ResponseWriter, r *http.Request) { - var request LogoutAllOperatorSessionsRequestObject +// LogoutAllControlUserSessions operation middleware +func (sh *strictHandler) LogoutAllControlUserSessions(w http.ResponseWriter, r *http.Request) { + var request LogoutAllControlUserSessionsRequestObject handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.LogoutAllOperatorSessions(ctx, request.(LogoutAllOperatorSessionsRequestObject)) + return sh.ssi.LogoutAllControlUserSessions(ctx, request.(LogoutAllControlUserSessionsRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "LogoutAllOperatorSessions") + handler = middleware(handler, "LogoutAllControlUserSessions") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(LogoutAllOperatorSessionsResponseObject); ok { - if err := validResponse.VisitLogoutAllOperatorSessionsResponse(w); err != nil { + } else if validResponse, ok := response.(LogoutAllControlUserSessionsResponseObject); ok { + if err := validResponse.VisitLogoutAllControlUserSessionsResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40508,23 +49338,23 @@ func (sh *strictHandler) LogoutAllOperatorSessions(w http.ResponseWriter, r *htt } } -// GetOperatorAccount operation middleware -func (sh *strictHandler) GetOperatorAccount(w http.ResponseWriter, r *http.Request) { - var request GetOperatorAccountRequestObject +// GetControlUserAccount operation middleware +func (sh *strictHandler) GetControlUserAccount(w http.ResponseWriter, r *http.Request) { + var request GetControlUserAccountRequestObject handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.GetOperatorAccount(ctx, request.(GetOperatorAccountRequestObject)) + return sh.ssi.GetControlUserAccount(ctx, request.(GetControlUserAccountRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "GetOperatorAccount") + handler = middleware(handler, "GetControlUserAccount") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(GetOperatorAccountResponseObject); ok { - if err := validResponse.VisitGetOperatorAccountResponse(w); err != nil { + } else if validResponse, ok := response.(GetControlUserAccountResponseObject); ok { + if err := validResponse.VisitGetControlUserAccountResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40532,11 +49362,11 @@ func (sh *strictHandler) GetOperatorAccount(w http.ResponseWriter, r *http.Reque } } -// UpdateOperatorAccount operation middleware -func (sh *strictHandler) UpdateOperatorAccount(w http.ResponseWriter, r *http.Request) { - var request UpdateOperatorAccountRequestObject +// UpdateControlUserAccount operation middleware +func (sh *strictHandler) UpdateControlUserAccount(w http.ResponseWriter, r *http.Request) { + var request UpdateControlUserAccountRequestObject - var body UpdateOperatorAccountJSONRequestBody + var body UpdateControlUserAccountJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) return @@ -40544,18 +49374,18 @@ func (sh *strictHandler) UpdateOperatorAccount(w http.ResponseWriter, r *http.Re request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.UpdateOperatorAccount(ctx, request.(UpdateOperatorAccountRequestObject)) + return sh.ssi.UpdateControlUserAccount(ctx, request.(UpdateControlUserAccountRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "UpdateOperatorAccount") + handler = middleware(handler, "UpdateControlUserAccount") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(UpdateOperatorAccountResponseObject); ok { - if err := validResponse.VisitUpdateOperatorAccountResponse(w); err != nil { + } else if validResponse, ok := response.(UpdateControlUserAccountResponseObject); ok { + if err := validResponse.VisitUpdateControlUserAccountResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40563,11 +49393,35 @@ func (sh *strictHandler) UpdateOperatorAccount(w http.ResponseWriter, r *http.Re } } -// LoginOperatorWithPassword operation middleware -func (sh *strictHandler) LoginOperatorWithPassword(w http.ResponseWriter, r *http.Request) { - var request LoginOperatorWithPasswordRequestObject +// GetControlAuthMethods operation middleware +func (sh *strictHandler) GetControlAuthMethods(w http.ResponseWriter, r *http.Request) { + var request GetControlAuthMethodsRequestObject - var body LoginOperatorWithPasswordJSONRequestBody + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.GetControlAuthMethods(ctx, request.(GetControlAuthMethodsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "GetControlAuthMethods") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(GetControlAuthMethodsResponseObject); ok { + if err := validResponse.VisitGetControlAuthMethodsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// LoginControlUserWithPassword operation middleware +func (sh *strictHandler) LoginControlUserWithPassword(w http.ResponseWriter, r *http.Request) { + var request LoginControlUserWithPasswordRequestObject + + var body LoginControlUserWithPasswordJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) return @@ -40575,18 +49429,18 @@ func (sh *strictHandler) LoginOperatorWithPassword(w http.ResponseWriter, r *htt request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.LoginOperatorWithPassword(ctx, request.(LoginOperatorWithPasswordRequestObject)) + return sh.ssi.LoginControlUserWithPassword(ctx, request.(LoginControlUserWithPasswordRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "LoginOperatorWithPassword") + handler = middleware(handler, "LoginControlUserWithPassword") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(LoginOperatorWithPasswordResponseObject); ok { - if err := validResponse.VisitLoginOperatorWithPasswordResponse(w); err != nil { + } else if validResponse, ok := response.(LoginControlUserWithPasswordResponseObject); ok { + if err := validResponse.VisitLoginControlUserWithPasswordResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40594,11 +49448,11 @@ func (sh *strictHandler) LoginOperatorWithPassword(w http.ResponseWriter, r *htt } } -// ChangeOperatorPassword operation middleware -func (sh *strictHandler) ChangeOperatorPassword(w http.ResponseWriter, r *http.Request) { - var request ChangeOperatorPasswordRequestObject +// ChangeControlUserPassword operation middleware +func (sh *strictHandler) ChangeControlUserPassword(w http.ResponseWriter, r *http.Request) { + var request ChangeControlUserPasswordRequestObject - var body ChangeOperatorPasswordJSONRequestBody + var body ChangeControlUserPasswordJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) return @@ -40606,18 +49460,120 @@ func (sh *strictHandler) ChangeOperatorPassword(w http.ResponseWriter, r *http.R request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.ChangeOperatorPassword(ctx, request.(ChangeOperatorPasswordRequestObject)) + return sh.ssi.ChangeControlUserPassword(ctx, request.(ChangeControlUserPasswordRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ChangeControlUserPassword") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ChangeControlUserPasswordResponseObject); ok { + if err := validResponse.VisitChangeControlUserPasswordResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// LinkControlExternalIdentity operation middleware +func (sh *strictHandler) LinkControlExternalIdentity(w http.ResponseWriter, r *http.Request, provider string) { + var request LinkControlExternalIdentityRequestObject + + request.Provider = provider + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.LinkControlExternalIdentity(ctx, request.(LinkControlExternalIdentityRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "LinkControlExternalIdentity") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(LinkControlExternalIdentityResponseObject); ok { + if err := validResponse.VisitLinkControlExternalIdentityResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// StartControlExternalLogin operation middleware +func (sh *strictHandler) StartControlExternalLogin(w http.ResponseWriter, r *http.Request, provider string) { + var request StartControlExternalLoginRequestObject + + request.Provider = provider + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.StartControlExternalLogin(ctx, request.(StartControlExternalLoginRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "StartControlExternalLogin") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(StartControlExternalLoginResponseObject); ok { + if err := validResponse.VisitStartControlExternalLoginResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ListControlUserSessions operation middleware +func (sh *strictHandler) ListControlUserSessions(w http.ResponseWriter, r *http.Request) { + var request ListControlUserSessionsRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListControlUserSessions(ctx, request.(ListControlUserSessionsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListControlUserSessions") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListControlUserSessionsResponseObject); ok { + if err := validResponse.VisitListControlUserSessionsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// RevokeControlUserSession operation middleware +func (sh *strictHandler) RevokeControlUserSession(w http.ResponseWriter, r *http.Request, sessionId UUID) { + var request RevokeControlUserSessionRequestObject + + request.SessionId = sessionId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokeControlUserSession(ctx, request.(RevokeControlUserSessionRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "ChangeOperatorPassword") + handler = middleware(handler, "RevokeControlUserSession") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(ChangeOperatorPasswordResponseObject); ok { - if err := validResponse.VisitChangeOperatorPasswordResponse(w); err != nil { + } else if validResponse, ok := response.(RevokeControlUserSessionResponseObject); ok { + if err := validResponse.VisitRevokeControlUserSessionResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40625,23 +49581,23 @@ func (sh *strictHandler) ChangeOperatorPassword(w http.ResponseWriter, r *http.R } } -// ListOperatorSessions operation middleware -func (sh *strictHandler) ListOperatorSessions(w http.ResponseWriter, r *http.Request) { - var request ListOperatorSessionsRequestObject +// RefreshControlUserSession operation middleware +func (sh *strictHandler) RefreshControlUserSession(w http.ResponseWriter, r *http.Request) { + var request RefreshControlUserSessionRequestObject handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.ListOperatorSessions(ctx, request.(ListOperatorSessionsRequestObject)) + return sh.ssi.RefreshControlUserSession(ctx, request.(RefreshControlUserSessionRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "ListOperatorSessions") + handler = middleware(handler, "RefreshControlUserSession") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(ListOperatorSessionsResponseObject); ok { - if err := validResponse.VisitListOperatorSessionsResponse(w); err != nil { + } else if validResponse, ok := response.(RefreshControlUserSessionResponseObject); ok { + if err := validResponse.VisitRefreshControlUserSessionResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40649,25 +49605,23 @@ func (sh *strictHandler) ListOperatorSessions(w http.ResponseWriter, r *http.Req } } -// RevokeOperatorSession operation middleware -func (sh *strictHandler) RevokeOperatorSession(w http.ResponseWriter, r *http.Request, sessionId UUID) { - var request RevokeOperatorSessionRequestObject - - request.SessionId = sessionId +// GetControlAuthPolicy operation middleware +func (sh *strictHandler) GetControlAuthPolicy(w http.ResponseWriter, r *http.Request) { + var request GetControlAuthPolicyRequestObject handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.RevokeOperatorSession(ctx, request.(RevokeOperatorSessionRequestObject)) + return sh.ssi.GetControlAuthPolicy(ctx, request.(GetControlAuthPolicyRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "RevokeOperatorSession") + handler = middleware(handler, "GetControlAuthPolicy") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(RevokeOperatorSessionResponseObject); ok { - if err := validResponse.VisitRevokeOperatorSessionResponse(w); err != nil { + } else if validResponse, ok := response.(GetControlAuthPolicyResponseObject); ok { + if err := validResponse.VisitGetControlAuthPolicyResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40675,23 +49629,30 @@ func (sh *strictHandler) RevokeOperatorSession(w http.ResponseWriter, r *http.Re } } -// RefreshOperatorSession operation middleware -func (sh *strictHandler) RefreshOperatorSession(w http.ResponseWriter, r *http.Request) { - var request RefreshOperatorSessionRequestObject +// UpdateControlAuthPolicy operation middleware +func (sh *strictHandler) UpdateControlAuthPolicy(w http.ResponseWriter, r *http.Request) { + var request UpdateControlAuthPolicyRequestObject + + var body UpdateControlAuthPolicyJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.RefreshOperatorSession(ctx, request.(RefreshOperatorSessionRequestObject)) + return sh.ssi.UpdateControlAuthPolicy(ctx, request.(UpdateControlAuthPolicyRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "RefreshOperatorSession") + handler = middleware(handler, "UpdateControlAuthPolicy") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(RefreshOperatorSessionResponseObject); ok { - if err := validResponse.VisitRefreshOperatorSessionResponse(w); err != nil { + } else if validResponse, ok := response.(UpdateControlAuthPolicyResponseObject); ok { + if err := validResponse.VisitUpdateControlAuthPolicyResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -40981,6 +49942,123 @@ func (sh *strictHandler) VerifyInstallationBillingProvider(w http.ResponseWriter } } +// ListInstallationControlUserInvitations operation middleware +func (sh *strictHandler) ListInstallationControlUserInvitations(w http.ResponseWriter, r *http.Request) { + var request ListInstallationControlUserInvitationsRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListInstallationControlUserInvitations(ctx, request.(ListInstallationControlUserInvitationsRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListInstallationControlUserInvitations") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListInstallationControlUserInvitationsResponseObject); ok { + if err := validResponse.VisitListInstallationControlUserInvitationsResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// CreateInstallationControlUserInvitation operation middleware +func (sh *strictHandler) CreateInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { + var request CreateInstallationControlUserInvitationRequestObject + + var body CreateInstallationControlUserInvitationJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.CreateInstallationControlUserInvitation(ctx, request.(CreateInstallationControlUserInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "CreateInstallationControlUserInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(CreateInstallationControlUserInvitationResponseObject); ok { + if err := validResponse.VisitCreateInstallationControlUserInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// RevokeInstallationControlUserInvitation operation middleware +func (sh *strictHandler) RevokeInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request, invitationId UUID) { + var request RevokeInstallationControlUserInvitationRequestObject + + request.InvitationId = invitationId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.RevokeInstallationControlUserInvitation(ctx, request.(RevokeInstallationControlUserInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "RevokeInstallationControlUserInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(RevokeInstallationControlUserInvitationResponseObject); ok { + if err := validResponse.VisitRevokeInstallationControlUserInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// ResendInstallationControlUserInvitation operation middleware +func (sh *strictHandler) ResendInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request, invitationId UUID) { + var request ResendInstallationControlUserInvitationRequestObject + + request.InvitationId = invitationId + + var body ResendInstallationControlUserInvitationJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + if !errors.Is(err, io.EOF) { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + } else { + request.Body = &body + } + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ResendInstallationControlUserInvitation(ctx, request.(ResendInstallationControlUserInvitationRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ResendInstallationControlUserInvitation") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ResendInstallationControlUserInvitationResponseObject); ok { + if err := validResponse.VisitResendInstallationControlUserInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + // GetManagementAPIStatus operation middleware func (sh *strictHandler) GetManagementAPIStatus(w http.ResponseWriter, r *http.Request) { var request GetManagementAPIStatusRequestObject @@ -41566,120 +50644,6 @@ func (sh *strictHandler) PublishInstallationNotificationTemplate(w http.Response } } -// ListInstallationOperators operation middleware -func (sh *strictHandler) ListInstallationOperators(w http.ResponseWriter, r *http.Request) { - var request ListInstallationOperatorsRequestObject - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.ListInstallationOperators(ctx, request.(ListInstallationOperatorsRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "ListInstallationOperators") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(ListInstallationOperatorsResponseObject); ok { - if err := validResponse.VisitListInstallationOperatorsResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - -// CreateInstallationOperator operation middleware -func (sh *strictHandler) CreateInstallationOperator(w http.ResponseWriter, r *http.Request) { - var request CreateInstallationOperatorRequestObject - - var body CreateInstallationOperatorJSONRequestBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) - return - } - request.Body = &body - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.CreateInstallationOperator(ctx, request.(CreateInstallationOperatorRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "CreateInstallationOperator") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(CreateInstallationOperatorResponseObject); ok { - if err := validResponse.VisitCreateInstallationOperatorResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - -// DeleteInstallationOperator operation middleware -func (sh *strictHandler) DeleteInstallationOperator(w http.ResponseWriter, r *http.Request, operatorId UUID) { - var request DeleteInstallationOperatorRequestObject - - request.OperatorId = operatorId - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.DeleteInstallationOperator(ctx, request.(DeleteInstallationOperatorRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "DeleteInstallationOperator") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(DeleteInstallationOperatorResponseObject); ok { - if err := validResponse.VisitDeleteInstallationOperatorResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - -// UpdateInstallationOperator operation middleware -func (sh *strictHandler) UpdateInstallationOperator(w http.ResponseWriter, r *http.Request, operatorId UUID) { - var request UpdateInstallationOperatorRequestObject - - request.OperatorId = operatorId - - var body UpdateInstallationOperatorJSONRequestBody - if err := json.NewDecoder(r.Body).Decode(&body); err != nil { - sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) - return - } - request.Body = &body - - handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.UpdateInstallationOperator(ctx, request.(UpdateInstallationOperatorRequestObject)) - } - for _, middleware := range sh.middlewares { - handler = middleware(handler, "UpdateInstallationOperator") - } - - response, err := handler(r.Context(), w, r, request) - - if err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(UpdateInstallationOperatorResponseObject); ok { - if err := validResponse.VisitUpdateInstallationOperatorResponse(w); err != nil { - sh.options.ResponseErrorHandlerFunc(w, r, err) - } - } else if response != nil { - sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) - } -} - // UpdateOrganizationPolicy operation middleware func (sh *strictHandler) UpdateOrganizationPolicy(w http.ResponseWriter, r *http.Request, organizationId OrganizationID, params UpdateOrganizationPolicyParams) { var request UpdateOrganizationPolicyRequestObject @@ -42117,11 +51081,94 @@ func (sh *strictHandler) CompleteInstallationStorageUpload(w http.ResponseWriter } } -// AcceptOrganizationInvitation operation middleware -func (sh *strictHandler) AcceptOrganizationInvitation(w http.ResponseWriter, r *http.Request) { - var request AcceptOrganizationInvitationRequestObject +// ListInstallationControlUsers operation middleware +func (sh *strictHandler) ListInstallationControlUsers(w http.ResponseWriter, r *http.Request) { + var request ListInstallationControlUsersRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.ListInstallationControlUsers(ctx, request.(ListInstallationControlUsersRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "ListInstallationControlUsers") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(ListInstallationControlUsersResponseObject); ok { + if err := validResponse.VisitListInstallationControlUsersResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// DeleteInstallationControlUser operation middleware +func (sh *strictHandler) DeleteInstallationControlUser(w http.ResponseWriter, r *http.Request, controlUserId UUID) { + var request DeleteInstallationControlUserRequestObject + + request.ControlUserId = controlUserId + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.DeleteInstallationControlUser(ctx, request.(DeleteInstallationControlUserRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "DeleteInstallationControlUser") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(DeleteInstallationControlUserResponseObject); ok { + if err := validResponse.VisitDeleteInstallationControlUserResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// UpdateInstallationControlUser operation middleware +func (sh *strictHandler) UpdateInstallationControlUser(w http.ResponseWriter, r *http.Request, controlUserId UUID) { + var request UpdateInstallationControlUserRequestObject + + request.ControlUserId = controlUserId + + var body UpdateInstallationControlUserJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.UpdateInstallationControlUser(ctx, request.(UpdateInstallationControlUserRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "UpdateInstallationControlUser") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(UpdateInstallationControlUserResponseObject); ok { + if err := validResponse.VisitUpdateInstallationControlUserResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// AcceptControlUserInvitation operation middleware +func (sh *strictHandler) AcceptControlUserInvitation(w http.ResponseWriter, r *http.Request) { + var request AcceptControlUserInvitationRequestObject - var body AcceptOrganizationInvitationJSONRequestBody + var body AcceptControlUserInvitationJSONRequestBody if err := json.NewDecoder(r.Body).Decode(&body); err != nil { sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) return @@ -42129,18 +51176,51 @@ func (sh *strictHandler) AcceptOrganizationInvitation(w http.ResponseWriter, r * request.Body = &body handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { - return sh.ssi.AcceptOrganizationInvitation(ctx, request.(AcceptOrganizationInvitationRequestObject)) + return sh.ssi.AcceptControlUserInvitation(ctx, request.(AcceptControlUserInvitationRequestObject)) } for _, middleware := range sh.middlewares { - handler = middleware(handler, "AcceptOrganizationInvitation") + handler = middleware(handler, "AcceptControlUserInvitation") } response, err := handler(r.Context(), w, r, request) if err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) - } else if validResponse, ok := response.(AcceptOrganizationInvitationResponseObject); ok { - if err := validResponse.VisitAcceptOrganizationInvitationResponse(w); err != nil { + } else if validResponse, ok := response.(AcceptControlUserInvitationResponseObject); ok { + if err := validResponse.VisitAcceptControlUserInvitationResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("unexpected response type: %T", response)) + } +} + +// StartControlInvitationExternalLogin operation middleware +func (sh *strictHandler) StartControlInvitationExternalLogin(w http.ResponseWriter, r *http.Request, provider string) { + var request StartControlInvitationExternalLoginRequestObject + + request.Provider = provider + + var body StartControlInvitationExternalLoginJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + request.Body = &body + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.StartControlInvitationExternalLogin(ctx, request.(StartControlInvitationExternalLoginRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "StartControlInvitationExternalLogin") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(StartControlInvitationExternalLoginResponseObject); ok { + if err := validResponse.VisitStartControlInvitationExternalLoginResponse(w); err != nil { sh.options.ResponseErrorHandlerFunc(w, r, err) } } else if response != nil { @@ -43943,6 +53023,16 @@ func (sh *strictHandler) Bootstrap(w http.ResponseWriter, r *http.Request) { func (sh *strictHandler) CompleteSetup(w http.ResponseWriter, r *http.Request) { var request CompleteSetupRequestObject + var body CompleteSetupJSONRequestBody + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + if !errors.Is(err, io.EOF) { + sh.options.RequestErrorHandlerFunc(w, r, fmt.Errorf("can't decode JSON body: %w", err)) + return + } + } else { + request.Body = &body + } + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { return sh.ssi.CompleteSetup(ctx, request.(CompleteSetupRequestObject)) } @@ -44047,287 +53137,479 @@ func (sh *strictHandler) Version(w http.ResponseWriter, r *http.Request) { // const string: with thousands of chunks the chained `+` fold is several // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ - "7L1tc9s4lij8V1h6tmqfuytFjuPOTGfrfnCcZNfTScdjJ923qjdXBZOQhDEFsEFQjsaV/34LbyRIgiRI", - "kZSU7IfuyBIJ4Lzg4OC8Pk18sokIhpjFk1dPkwhQsIEMUvHXZRSFyAcMEXz9hn+B8OTVJAJsPZlOMNjA", - "yasJyJ5ZoGAynVD4Z4IoDCavGE3gdBL7a7gB/O1/oXA5eTX5/+bZnHP5azz//Pn6zeTbt+nkiuAlopvL", - "5RL6DAYf7/8Bfbm2AMY+RRGfafJqcqum8R7XEHsBisF9iPDKA15EyRYFkHoRwhgG3v3OC9EWekQO9Wwy", - "lXD8mUC6ywDx5cQLoGZeqOcnJggBXIIkZJNXSxDGcDphu4i/e09ICAEWALwj1IdvYAgZLK/6NYXgwdsA", - "DFYw8OAGoHDG4CYKAYMehUtIIfZh/B+ewmLs/Z/ZZRIgNruFICa4avFLPmnblV4HcBMRBrG/+wXuUvqu", - "IQggzcY2Hpvx58xZNuDre4hXbD15df7TT9PJBmH991/TOWNGEV7JKZcfAPPXZcRcJZRCzDwKY5JQH3pv", - "P4FVCm1pScuZHKeO3SyzYz9MAngLmXzjyYpLJJ9aUPVYS6x+vEzY+ipEEDNj0xSZTfzetGHKEMjBSQCv", - "1iAMIV7ByhlIABd++lTdNAYRn5//NUfEixdTp1V8gGxNAre1LDby4bolQZxsJq/+mNyd//Ry8qVyDbcw", - "QBT67PPtddXcVD2ySCiqnXJJ6AawyauJfLByxjgiOIafxM9VU8pnFmIMFzA5gmrAvPNJ9Wyx+LEDG90x", - "wKpHFT/Wck3DVpeSu/LckNK1lyPjI10BjP5Zf04R46FeZr0Bu01+j+cnjOTv/cyljrTqydQDvczGj1YY", - "V0NG5e+9zcVf73wWOYk1p7PpDsZxHQfF8vdewL5L7tPTr3pC46FeZv2d0Ic4Aj6snPJRP9H3fH8X4qV0", - "7L/9yrVHxDzg+xy99yH00jV4j2sSQ29FAWaxByj0NpByvekRsbXH1tDzldaQxJD+a6yerNKRCrC1guXb", - "VHP9axIgWNSO5XmIl2jFf/AJZhAz/tHQjuf/iDnIT44T20dPV5JRReg1DFIMQuOd4VajJ6td0a9gIxUs", - "59kjSiJImcKtJFnp6JpO4jBZyYsK48uYvJr83z/A7J9f+P/OZj/Pvjw9n748/6b+/PIv1pM8W+4fciY1", - "bnYCy9OpAjhxevL/CFUHyhvooxhJkCog/jp7fHyccSVjltAQYn7kB3UoyFREGx4K6l3zI1rralauppPA", - "AEc/LPbWhP+Gd5Mv36YTTLBvnzincjVqVtOCvtSsFk2VzmPlD63U1FM9r38XNMS89qb1K60RlRTrKu02", - "xWIbtvpEHuCYbCR/jaFPISs/MZ08UsTgRxzu0mUKolTy2xZStESQWp8QPFSiMjB30kIMz7GzpDBeL5jA", - "R7pQn8IAYoZAGAsmbM9q5rBWBqpgrQIDGaC0Ju9VCsRRE7oCR5WPCmws1kjCklJXHOwpHfME+FJEq/ra", - "EaPyxzanjNOwjxjSeI2iTxTgeCl5uZdTtDyyfQWpuo/XkCIGlKB1XgMIAsR/AuGNwSLKZJHnGqSmuA8t", - "1qrLMCSPnr9GYeCJfRF7jAgTTbiFHlujODW2PZtYjSEmbc2pHCl8k9yHyN9PrbEjQ+qzeXA/cYD4xqTa", - "WOih2KOQJVTZEbnOmWAusPhjPmAw8GiCGdrAmbAfrjyIg4ggzJ55d2KvScV1Seg9CgKIDTzVQn4LtQo0", - "BNX12DVXpOdOipMjHW9JCC/jGK3wRoHSy34qDGuf++7Dpxu9ofbQSNckZlbJWtpB9RbCabVuG4E4fiQ0", - "cJO5EaFM0RBtuKx9+dNPLyQN5d8ZBRFmcMWlzXQSQxxAuhCW59yBKb+x6VryjcpVszBebJROoIV+zABl", - "LIz5TWwjb3gLpo5sflerGMyumgvMK3iN6QqwOHLiHSMUrGAnhqhjxSsKAYPF0WvX8DkKCQiGWYEa2za/", - "oXALxi4dSrcwFgw81KGnxhdrywvg1F7gEf2Sx9RbFAYeYGSDfBCGu4kwwK1gb6sUg1mWdJXQmFAvEj+L", - "k/k+hJuaaSP5xL+3nF6Na1nB7bsr7+eLn/7iRfqZ6USokXFvwIvhtGXbugbCAEN4JQwtnjKEif2qhhD2", - "EN+HEcsZY/EWMcDUTbLF+RSgOArBbmE7p87OpjYhrGfKVPu6w6wsUEvKSmHAsnyZVluAWoC6DMlj3ML8", - "8i4kj6nppX5NxqNtlcIU+LYXLMKVo0XuLlKrVEwn/PheoLYzFchVnLZi2GklaA3kLRi9WnIzDOFKzgkx", - "1xPME95QDPT57/ZUyK9V9U9CGvMFLkCEFg9w1/A4hSsUMyoXWjzRI6GJawTCBeE7x+qxKqHxNSGMjxsp", - "v4Ll6pq7EDerPkXxUOIpZ/WmaBbKFqIHsTGGPGpfozBEeGWqEnmwONq3kBYtaedn5y9nZxez8/NnAViH", - "CAi1qLUaGRnzZnoXRREU47W56T/C+zUhDy2sAwW8pWtJ561G29Ua+g8ksbEBv+iGrpJG+9ekvU3KLQY3", - "cc6ACCiXBewRYSawokYBlIKdRCKS/gAnN8A052dzfCVOUk9nyzeKhjJ++HJaaC1J0jmRBpYuUjOFPj/M", - "1KRENSHfbiFm2g/eRhwCBhZd7ud/u/v4q3cnXvTOz87PZs/PpSsIYH1fp4QwyxW7MFJOofjJqlDAr2AT", - "hXDBF9tulR+SmHlbEKIAMOiBFUA4Zp4BtHV9ej5Fe9saG85Ri670/OXZtMpTsph9+bf//7//+1nxu//1", - "7/9ivQWKpZviLJVQk+fPzib5eZ7Pfv7yx9ns5y//xmfgH/7d2RNjskcZLwXKVHPnOwhYQtvy5pJCuOB7", - "aKE3Un3c2RaEifQUeCj20rc9gIPM5uMRtob0EcWQk17vZga/cnD8eDuZToS+bvN0PEhneAPtN5ABF04t", - "4SplmvrxMzBNeaQPo+nkzwRghthuMs0waNcOTII/wNQ7m5uimqgfROAcF/sywKoldUEYkkcYLKQtM8fE", - "f0zmm3TwuRksEs//ja+odLY0PF+2kxSOnryOXNi07ff6eaOIqHGBVdjyNNpvlCJ5eXOtgjPyeIVfI0Rh", - "zNXtAOzyiH3x8qdpZqN68fJlk4UqBPcwtBkn7a6a/MHfgPVv1SDyo9Ciwm1IwnUMhAlV+0Qu/cy2dF+p", - "Ngs/vSaUppMhC/6uAOGLHPFeWKDVLy7gV6k45NB8blsPV2VZKFjUWFIrAbGUYjSP5TolRsnd3/h2trH9", - "igIfck2TYKm01aOUf6RbEC58Tojc889rn08wyvmhAsCFzSOED5PpZEOwiHrZQUCFFqXEbFmwFq5BFHIy", - "SJ2YYLhgSAivkPgglAom+Lq4h2uwRSSnmYug0hhtoTjBss8JjiPooyWCgXhfKA6I7awYskBsFanKPppj", - "XoPzajY6JUHiW1TzgvpUVpeOkNOqaBqiuHzNyi3KuGWZJ2vl6WmNQkhyp0VAwZIf98BnkvCA+mu0FVSv", - "PharKWWxY9cehADvPi4nr/54yl8AxK1+cZ/4D1BckJ6K94MtYDD7/UvpRJW3hge4czD22K6e4khe6Im0", - "88x2A86rYdc4ZiAMxYk7EwdB4JGIzRDmepcnNqRHqKdGnmHI+L3Ju3uReuhim8+Ss3K2hsJtKn/c2q4N", - "Ig5/EQG2XsRs53qVb33334CvCzPx4n7HCvrM87O/vPjLxfO/nl+cTTMwEGYvLyZNJ3BxdGLmYKTjnwkM", - "dBha2FUWaANW0LLw87Of//L8p/NOI6uYYsugL8+fX1x0WG8nRWta3DjNCrbeiCCGi4SGTvaP3N5tnoLC", - "Vfny+9wBGGnRWWRbfW/julL5052WLm5aECi2yRtlYuZXa3E1UH6U9I7TyjM+nSxRCC284nJv73x3ixIa", - "kTinnhhbSxqH0D+NPdaS97coRvco5Nc6myFY8Xj5/EpxMc1jNbec3PA2kr7loNwxQK3aSIi2Kp44FyvI", - "D3fMFbx7wtYCAy0c3Sj1pKXmVOlD0N6EJOIMmjCyAQz5HeLPCojSK1ETTzO4KhHyG6RoabmBZeGH7mZG", - "Hchn8Otf66PkbQc4R/jCOVSseAc1l20Fegsxe4u3MCSt7YzAZ4Q27SqchKE8dyt2WSG/0RW3IInNdzK+", - "SOSF2z6tGUyJGQU+W8h0uNwODAHj4/38YpJbntXq4BNKYbjXUjoJpxbW7pJlsb0lcTrJ0NR0bvL7lsUr", - "8/zZmT3UODPINmJK3AbNJQRc9VR3xArTRFMQjLlcgdYUVjVCmVfUQqbl3NwCrhVtKzfep10E38Alwkhf", - "/Ep+O8BgsADMHeoW1v8mI375FrqV98+koL3r885iIWlh5q+02Ytpm9g9L8nsFv/ykeS8i0IQswXxxR2/", - "liCNTFx9qS1t1Jpd2ElYla/Nluuy5b0kClrzoQFGI58UY0OCzGxtsmTF/nJ2ZhQ5ytjpCjPZsm17NmcQ", - "aXdWqrvlYqvfLd85lX2mxSGYOVPSYQvxxZ6kh7iyM/iV8Rv71d1vnrYFTfkXAO+kP80TDkAxlnhD/Kkf", - "fcZn1H6IbMI662JRb80AtGH3PfFBWO28BkFA+RWlxZblAy7SpH97SGhL//SgzuYq73EltiwkvwKYYOSD", - "0Ht9deNd/MULAV4lYAU9BlZenPhrD8QexFMvgLOr/xIMELHZ69tn3ttNxHbeBgIce5jIULQoRd+zvH3m", - "hc1hkLmPLm+u71Jh006nRFuoAo0czNcgQuJS76KY+AAvpE/JvgFrg3dkBkaN7arhKqLGzq1iWgS3NI0B", - "oI0JPkaQAkbojQpZuloDlazW5mYuczwXZnR0zoJxfuFyT8HwsX4I85p+3t6kYQ7vgov3ZIXahkW2uMwO", - "CKqesx5cwyP6VjLXHWQM4VXrLWcosWn4DdlCSlEAY/tu8JOYkY08RiseyYLy7L/n6gW4zptG8BkpIpUz", - "5AL5nF4oxvNVPCYNg2Y4n/1BFfZlHaYo6y1jVoNbD5sNkBw9mpE/beKKIgsYwDZxqw4rL4bEZv6GBSW2", - "o+2TkZBO1G7/19gz35w9ogB6/HVxsHFdXGgyJrwzgsOdyoc340VESDyHPNgIkxRIAsQInUz5KF8cFPvU", - "qZZ+aHXbKbrXMPzKFr4Ij3e4HBdVaLGE/CBTC5IbiUVCJH3pIAyVg6tW6xE3BcsI36ZFihcLhjjqU0kM", - "Wh9xBjM76BRc8Ylb6ra5GfQQNuTWXYta+KHL1VYkXuouMF+qci/bJLbBx4XYKAsOYqvATrhFJInV2wGK", - "IxKnZo8s1m0DN/diG+ptmX5B4YZsLWpyeUlWpq7OwimwZf/QVYNSerPlvLmSG65VQ0zkFWp25BdRubpa", - "gG3Yr5D5RYE5hhS0L0+epndoha8tdrgT0gtNUD5H7oK7gIKyuF4iGrPqjABhH6v+Nb2t1q1B3WktUWRf", - "8qlhRddiRcGEADJFN4uzNi2xVB9fUj4eRCBOTSxc/mY4y+wPTdyqrM1yfMMkVajSYdCaK43x+kpoYm+3", - "7eM1i14UN69W0eHh8lYn+2/3WG2Ll7m3WG071TKTY6XJ/+8JTOCvhKGlcQtpo8UwBvz1Rl+5GrTMWi/8", - "PYjhy4scr97vmNWOW3Tc17rm61FV7bgurOuLg3rcTqTwhfgo0jHNzXJcFw1N4zFMWf68MZi05Tm+BRTx", - "Y63traHIi+aiK1kw2IMHlyAM74H/wFWBCkuZO9RKCMNg0Z6YokRG+xfLHpA/BUrEDo4iCuPYFjIonXta", - "IJfWXV7QtIApGzHKRRtqCUEwtEQYpjpvMbYwCz+3hBXmYuOdSEVC2OqSNq4aq5dnRbOsH3KQBOL+c05z", - "SaRjpJvm0FwasmJBFrgrgKyhWEatctqnq82/W3QJSNi6sTZKia247IvjRN6pHaMLO8Zyu7iKZbCeIxgq", - "tM9IfM/FSBTdrikJUpAtwRB5EBVWs4XVUD6/mnbbtTIC1iFagb+rQ0uLsa6ur0ugO7ytJ06trWmltCzH", - "ITPfFYy4Ree/MV4iwjWbUtnlsnubWw7nMLXdDl58sRoaGxcp9snKl3X0huwRWlarMXcJ64EMrJxipGrU", - "8dbxLpBSJ7PLHkG20n7UEdPy5aJnvcCqJm9O7TneHbLONaNaY8kbF04hCHZ7RRE1RB5bClOVNN8I4kAa", - "nsRylI+Iya+WAIUqZapL9I/cpguduLgPpG0CiboHVSurplnl2+Cu3LhT1wjsdFNY4otyUiCH4xqJJiPv", - "c5VxW4o3ksrEOibPC1ADUwtZL7zmmlqdIppB484cVXzlksLRaE8l2mJjDGpbnAV8G43yRZ7KWqtZp9Op", - "akiW9Ws3RDbUWq2vI2rujtcQUEjLe6K2tGhusNxibcgRYtMi4ksElg7EEUpfjFrBYoByFD2FdbtEhFrT", - "uis9vS1DbqQet4iN4JXaanc1cS/l1DpLX6NfkzBUQW4JDtEGMRg8M52vZ5VnUkHVT/3EzRN4wKckjj0Q", - "hp65PA9hUfPUVKfbLqawaUsYMBc7LeP7SyVtjWTlVsW4Ti+T2cxYPliKcgUVPseQ3lDCVY62hqvxPHb5", - "qqPNTtoyrLG9wFen3CAZmQQYo+g+YbB9KE4Lf680Naiq7BWX6wZCuEOG4gWhq4bZ+qVrzQERJzG/Qsjr", - "ubxLLOQNQt67MMG7DfonDPTNQt8n3Fll/zSCklVKUzI11BcoWMZyioQvNv9LDP2EIrYTdbNUsL/Qpy6V", - "EVH+9U4v/m+/f5oROru5/KTzGQT9pAqWTrBmLJLnjI6oVkpaecCbNANklj09+9vvnybFnP67NaFsFnKR", - "40kPwMyo9+8JfU4V/PIZkVef/52NqcKURe0lkAQIYh96Wf7JK5EmRcJnLnDp+L1KqOT6nce5IuQBZc22", - "fPln1r7p5xcL/ajKdc7GAhH6Be5kWVaEl6R8pMsy6Z7OAxMhhUIX9jLk5+IQRWBhiHyorgJIIFn2bZhc", - "RsBfw9m5qOqlFmh8l4UYGKT1Lm+ujdvjq8nZs+fyWRJBDCI0eTV58ezs2QtZKGwt+HC+hiBk63/yzyuZ", - "wy6RgAi+DiavJv8lfp8UChafn51ZUEAJx5qHuBLD97/J+5NXf/C9Abj69sfkbhczuJGH2pygwJ8/e4Rh", - "OHvA5BHP+XpRoKq5J1n4rHWBH1Hgv0GxT7ay01DzOj9GEF+/8XTdDi89vKvXey2Iw3bminXPDFi5tNdw", - "hfDH6zdX+ev4NNfisyLoJntknu9m+G3q9oLZl8/9HaOznutLsjOe89OihYvr0/k2i53eUm0Rv31xYY3/", - "gkD4nvg+jrkgE7WM+HFGxMH54uzckkJlUtfTk3g6L92NraaTSFW3z/PQG+ijANqYKGuGtas6q3P9suY1", - "PZO+tUIOsAPMZR9AGOFVCvuCEVmkT+SJiU4Oyi/eFzbzR+kfwpFdt2sRP4DiSF2o7Ti/Tp/heP+U2ja6", - "4LvYbcYJ07fvrry/vHx5rs5b2faonXT6x+ND/EyXIK8UnH/7/Zc7J5l5KTQ6ca6LnqycyIKmv8N77xe4", - "i1suj8IteYDVJLgVvx8I/eIlTy4xEOmPoTB/ewgrzbYdsKn1zQ7r26++SMrqCVo3GMXzir9oWnZ+Ormo", - "fli4eoyHW+GAa/Rac6pkx8/6oRbH+BXBGPrM80OANrEE4Xk1ztSoRrX/ruJEewJmOq1lLks/z598uSSR", - "FyN9QCj4Vk3/O/Ha73KUsnZgaRFpm6Bd+9mK3p5yKbM7tMKydGubQb+U2Na1M4K9R0czCwgbsBczIjpT", - "4MCLpAoqjxfFyp34wCC7qjGuqC4EQbW6fAtBgLC8O7TSmKV/7dt08tPZiz5WndOwt8/npr1v/pS/8n4T", - "uuxc3HLncVrvp5WSmu9TL8LJ7MIuqynUmV3qizxkEzixlUUFeYuTjVrzLAZL6KU1ckROWCTUF1fp1wb3", - "26y00HDIV/WLBsS+msF9V9czu+q00jPGQ7LSRQQGwfV7Mb7qqa/6GpeFwkV1G/706rGFut2L1kmkgXQf", - "6I2K/cOAzw/QD2qSLuqM4VduPAWK21U5MLx80qunYe6ZkTZLMPjGlTvqw7vL/nHptvf206r6QPEjvOef", - "8ZxEqdtuGGQLs83v8J6zsGgqlEuc7g/9z8usrGf1QBxDKrhWgSvUGxKBPxPo+ZDCDcE7z7AZDonxobn7", - "HcIoXo+A8ZNheB0HzWeCbGidTCf23fLJKnSzPbDuomEJOEfQswqIHZqzc5itUrzGYeiB8BijFZ4hPDwK", - "VdbpMGprMbW1Z831SISJoFUSjUOrz9EItPocDUKrF4ejlTIqxZUWhvcoZvyIvEmf7AKt6rXp5pjYi1c6", - "wC4ehnNfpccNeEnh8wiPkZ7KlWXbt4avykBPA+it4UH2d5LY2t3/m6X/bnEvWH0u2lcoPfsEy+Ba03MN", - "lY3aM9rzDcX6ivx6ygHNIWqGlA2+k7O5gMiBtUehMA6DQssNSUxU8EB+vn0vOVfsGHFTwgT7cDjErghZ", - "FSSUVVj/p3iuJGEOuB8PIc4Vtsbb0Bnav7cdrVA5xpYeCImWPS1nqt3UU7mjp2Jz353/9NK7+eXqbd94", - "Fu7QuUpiGA69t2qC7vpxXrdoneVRytk233fs4n8Ee+NeeubmuufbTJnJB7QN5vvnZmb9drNdB3ATEQax", - "vxNhhV+GuSkVmv060fG51UspA+U0nj2Vl5ZzQ+TdpN1pN39Sn7TT3H6wQlYmQrOrQL/jyXBdFc+iDlsR", - "KWeFaM9DszlsTcHgfsJq9EWEMhCOxvi637aYdTju7/d4kcWvIPUkslJnWg9c7AMGQrLiB3SQqP5cVn6V", - "4cFX8vEhbux66JE0vKxUbDx/Mprr89960/Om1uCX3Gy1ASoONWIaVck3Zk3cQd2YvxI8UycxuA+hp+AU", - "mWEiSkQez/0dn1lp5oGsgeXac215U3d6HunAtKzYPYakn/iJfIuSb8WkUyXMPEE7cXwxCnAsI5RB6JGE", - "3ZOvHoU+oYHhRWlr1ZxOLs7P21lBNRu+lWzlyIQix2ZmZPzNtEYQDxmb4YPwbTZnqiIdqSKX73vRWY+T", - "CViqMaeBch2VnSdj9rszMTeqJHcIpeGyGMrOv/+wu/RleyCXYBj1rKeSwwTHmwlJDQEx02rtUUbZfI5V", - "td2ydO6FcmJ86zaWQT5JrHz3A5hqRJqPvy6DL7NGixjon23L2alOrHthvYLw9z1VA2Ov+KcNnKtGMbDe", - "y/Jhd5k+t5fGNgxta9T0dOWDW2PlNFZVeh+6zJ+yXj7fnGSKAW8TM12rKH5PzaGFy0C0smuxRq+iHlTY", - "un0+DDNcVDOD2qTKeB0xtEExk7mRaf/zQRhlLuiqnGZHTzO7R1JB0I6jNeYBIxvkgzDceTEMoS9OzNgz", - "klb2wblO1h7QH6unaKck3KheJlzfldoCYMDLksvbag3OGInQTPeAqTxF9OIub65/kW1Wup4kHSITRj95", - "8tBOhrRrFqbqqhX/Anf6+BJ8IrtdexSyhGIYeKkjsQdGmT/Jptq1R5pMfbMg0nkbXN5cew9w16wcDyAj", - "067h+8lHZ8wmbD2XYbDaG1Kjz11nDx6bQtcR4PmT+tzIVp9xiPBDigM3lnqP8AMMPD2HJ7uSBN7jmmvj", - "EYUxpFt+pwReEgurVUhWSIfaj8p4Bh7G5b5iuIVofz5CtMV72WZ9WP0+i8WGgadiL+QhO+Nwln22e4tK", - "q797BJxKJ/T4SNXO70GxqtxFde60Dzvl+7hLNhvgWEpDmzHU+B6Fsl2uJ4CJh3GnfWkJ9SzKamM1Qq8t", - "FW2gF21QNQqi1NQxBOiNdz0LGANe+eowYDXWtPSvbaDMjJxJZ8woyamyQ+o4aRB8Pk9HctmTH/bY9TnU", - "jZJbKnE3QKLDRT3ypOpO2BpS7d7t7ZYnsShLfanryhhs+JsxYcaMTRxlvjUYR+VwMV7Osnp6TO5KC7zt", - "izfTmVJ/R8n5XZzSX5dLKO2ZQgqbU01V9qCwCG0gXaVWOQyVVxlxpT0tdS620TIJQy7EtxCD4uW34BUa", - "PDDmd72y6zd/TyDdtTj94deIyF1qxfZb8XONoclWr4FQUQQ0NTSpOQ58J0R4S5DffPvVj/Vy9x1fnSu7", - "itX2bgK86O691a/1goh+t0QP2Jg/Za0Lv9UrvRWYcau/84iVK1lNJ0UL2mwSuUliDKJ4TZgMs5MhCt4a", - "xYzQ3UGFioJyCHTPfS4ywz4cEC2AqLTJisW0IPNFddSAJrIEsHAkdgsWUDU4ZiAMh67DcRmGbp6UMJTH", - "aN9a5GYJzKIbNdLqw7tLs3DGKRopDWDnT/JDoyMXCfthCrwTtT68u1SmRi+Q749rc0xBG83iyDFLoSx2", - "OvNJADnpVxBzVMIhMxb0HLdq8isSQDf99BZGIfB1oJF82xNL79fJwlHDCIsGthN++vjp5i2mJAw3ELOh", - "bYUfde4Xn1b7plSls62o3cllczFyfQ/smft1aH96f9unyZ0+INFs9SM5rTTuApVkMCzjH6g6zq3R2XG0", - "2jiZJ186bltWyekL0+NWxRkM02dumHZnZ1nwt6eIMGz0IZ5FaaP0Jh3KbF98Y7zVz4VvO/JVrwoJ8ycf", - "MLgidPdtIAmtx68V0LrrQy4SfTKdaKeTaDoi2sRMJxtAH2T/uC9SbCes2pdhp+I4lr8MzdqP8R+eTrvw", - "KNwAhGNvA3AAytfZbctrEOECZaZKjjextqpwrp491RtCHuT5U9pt2iE0Jo8Dp4vCx0eclnTXxogt9FYU", - "YBYfJE4ma6891tUhLQM0dBa+LtAjnUFDb1c92wieoAjsXCz4N/qxE7WzRpBukErGFck4A2aV8uE/7G6y", - "GYfWbbKpvEB1P4il4ZKSEHrwaxQCrNqimWS4kp1rWnCLmZNbwy130AD8FEV5ZeJ2kxRvUxT3zq0A7iCi", - "OgNrNFmtGqDPZQWGRhYye7H2xEh3ugX7eHyUh3n+pBqkO2aA5BvSuvDUG9WIzPszgUmBp0zwq90nDXNa", - "xM/nGFJPApbvO9Q73h165Yhl9EWjeUAecUhAMILvw1h5Zd8ctZouRFK9vAj1YqMdmuoLXQrHyyjWFouq", - "Uf3QRRtSFMje0AMmYTcf1fmVOJYfgTFaYRgIx8yMPIqPaoA+6ZDjZg6BFjiH5+YrtZoyKR1EjnjUHsrS", - "AWfJfTp447mUe/ZEteE0NmaG8BYx4AJ4FrVivNIL/JkaelD450/ZH8pT4MOIDWSFys01oK+Ag2Al3uAG", - "1zT+KgM1jdkzsvr2vJGkpHTm36Pj2qaTLl354N6IlGQ6eUxcItkaer4ZFA1ij59YdB/SyR5Ps6wVdl2J", - "IfnQgCUNbhPM0AaqiSy1De6El3K2pBB6VD7s5Xt51pQxGle+tblnGRN8BxeuvW5bVagY5drlPvmZvXys", - "Do8+0WvY6d3B9qLYoJexkW9iZUSc+pXMQGhvN7PTu5bV0HXU+1mm4M2f0s9NIv2S+mu0LelODi41rvRk", - "mQNymKBS8as2o9VMbG1Fa8lbCCADKIyH0TrttxITwcPXcBlGsb2oU2xt+XstNddKhnQswZQupudKTH2W", - "dh2BNWqOlCKGxrv36HRPUFMDqmW6pwO7tKwMZUWPc4Gox0pgbSWjToipDl2TalCuvWjDtT0kKbfl2qHD", - "ak+NUWojdztt4GpyN5TF6o3yLUoPpIvtUIGgDOig5QcOrwjVIWtU+dFjkYNqLip4HE5bUxnesv7c0bJu", - "01R6U2w3cHPf1L/NQMUH9fhx2dlHYJZ+0Dx/SmJImyOONiR3w5VYb3mWyCl1DaxTRbx9BoXFPkRAYs0f", - "EzlgJQrckhDG43nXNAX5rB6VaxpWDKxRVMeY7yHYwnZ2F11yJ5vg1DlyX1Eg/GszkX2wlH0RT/Wg/KRg", - "MPbJRw6cYKMuu0S/rAfu1tSsNMwtjJOQDbNx2rjkUiwdtUOuVZWTyd7bYS/Pnh2jo/j1XKeulfBH4tPL", - "EbR/F2An4o/pHOwOf5MvcQ8uGdST2EySvnyMbcWJo/34O3FIZuFqfbkjnSl7KEdl/5tN+zUrmaNnr6Yv", - "lYd6QtTZ0AyctQ4DMV2HRlCSnoXQ1xBQrlf+8YVjV397RcgDguLbIeOXnFAzB0mA2ExWIxs+ioFPJsun", - "DW2+eYt9uhNBkATD2Zok1BOgqsJrOUvO3rQr5u12QP38SX5o5NcCCpv49Q3UeMiBfw+XhIqkNaRykPtD", - "wiDXxhQ7fd0Z29AoJKuGCD/+2Hv+VF8NGg9Lg65Imj+Jz05M/L6ynWWx6DXnW9WXTorcU2BYjYix+VUm", - "x6tw30FLRqtUeh003FKYG5MZA7m1C8rKoAujvBkhLJK4b365emsGmKWdevNe2x7P7NZEyirVu4YOc6hv", - "0pcOK2cOpqyUuyb0wuaJVZWVbCVi9KDG/NAmZ9kpQdZ4SDlbNyICYXgP/Afv8+11WjnniDhZ9VwYniKy", - "88FYJFF9Fk6UJk/6o0sRxQpx41YA05C3IC+h9RLytRaPRwrZT/Aoz1/1JYwU608nUijxVe4iUQOAUYRX", - "rQ9y3aY9QHGUsIZgxzf6ocOeCr2nWHZD1fxJfWpSQxXaJm49tukGhKInnBq93+v/wJE2GUbG1Uc1bZwK", - "jfdTZvzU2VijSmTK8k9NbKzQ1paN1egnxcYZRg7Dxk51nPqp4nTqbKxRNX9Sn5rYWKGtLRur0Y+XjRte", - "UGD3jOg5hcsEj+IzMgCYdml7X2cwvhVQDG0rfpeEoUeoFwEqKpZK3PVrIi5FdrYkstJFZ3DbKH+yAFfx", - "ijJz/djCKI+++ZP4V22UKAS7gWJ/9DSDxf2I8LidjeJuxdEYoTDI7mdivTK+bXdknN+K578fdq+XjwWw", - "B+2aXJyra9vk11kcvGS6zKJyXAyXmU4cW1DYqNFYhLRsGplOLs5+btetu1eGrVLQGsE7s1VfzCp6mATH", - "0LfV8zh+bU3B4OIfadycPZezTdFr9KsnNI1o69f1McwmEx1KsI9CJAsD0ASPosIaVO1dh1WYus1Bdptg", - "p66M+bdUgKSXq5ce7o6aoj01O2i/Na0kkS0g9xLU5vbKBSkdmgIVe6dJZyox5g9+V7Cgcf5Ek8ZIMvd9", - "fta4z5dItE6Lp1wXB4jGU+FsihlgyWlY6iTCDmOlM2wflcx/q575wVldIGH+JD80cbhhjWlhoFPWlFMy", - "M6foOAz/8m2OYob82EHe3GUPuxDmNUlwIKiyhTiBU0UeKV9CtIT+zg+hZyzhOAn2p+jpm1JsSclmYhJn", - "yRmQTV5NuM4rGqFNyi7ZisEYaT9UR0o718TtsSLuqUutHNLmT+afTRLMxKLb/dV44WRdDCYQg6F9vP61", - "RXD6vLEJGEpcMuCtPcdgEoWh1AG5AAqSEAb8Ei+IciT3jEZGEO10ZhFFPjxxdhCQmBPcUGQrpOZsZo0o", - "n4EhyRECRVzNcNImRDc0ubrFPVyDLSJUMtQSJCE/oKTHapE+xg8KHaBk+w2Ej2AXL1AaQIAJVsk1mdrz", - "R7bMLKqJKBZ3sQE3iVUxfK4JU7zD/poSzPXHk2B5CuNkc+LMfitgqD8hbQIsFVM56WVWFjgU9WTEZr1e", - "daWe+V7iqettkRLaof3pVypSVpU3Fzta9h+2tPtURLsP4UGjZhWvuPYTVB4fA5+N1TckUowegqIXoe4k", - "eFKRsW4tCEtXpAZ/yQDMWU2HY8gDsfDcnBLGb5lyvwzVm7Uz+ewHh1iyxKv097Xu7q5i621S4qAU4tt/", - "5dC45Y3x3GFPkh7b+NUfJRnIQx8nd0bNBaK72meU8eBXqTsanpnecdmVa+ZP2R+N4eh5jDZn9qYYUIYJ", - "iw3v6LiqIjzdRNK4RtcaYs1lz8iBpHC/MFdr9RyEOta6qGUtIEz34k8Y2PviHm6fEdFM2zWB8o16/MdQ", - "9UuADy2m5SweCAKl87/59c6LKCHLYzrQJQ/Mn+SH1k1rDFQ2biKJj14vwgPr9SlSRhbBZaL0GDYyKJz1", - "cSYdGefXO9n5S5Ro7DfEpOO2EfI5hM25L2/NBw9cC8NcytDS1phs+Mo26VTSeNBzLZs82jqzyfzJ+KtJ", - "9S2ir0n3LeFg6sHlEkq7itB7pUMbRBHEwYzgcOfJeLn4GJmrInkgh79xRXItJfl2ZYQOpRj3DHeNvZsD", - "MdTOtWfIp9woUaht5T6hwdFv4GGvQ6NRncNwMKJviX90NN9CzGZsFzVkZ4usok/ise+kyFXDka7hHTSr", - "Jpulaz6NWXdD5m9xWnoUrlDMID1URkm3mngGM+okPf6HYye6PMnaFCwxEJdrR9cns1YqP9Wr7q/3bjrJ", - "G7hEGKnkm1IH3t8gjRHhV3WJEUE14DPZoxh4ujip9wjv14Q8ePAr4N+cRAlBk52GbjcztPQozuIkPSyb", - "4G3G+EHKGZl37MQkh8MJ9mOWaCzlPdfexrbV97D+hNFbvIUh0axbdNKSJJCYmvH3ARNdO6VMOp0akL2l", - "f7ei9RICltAGbe6dfujA1nDAQEiGT5RW4A6qyuk5uipy6v3MnDOdXJyfjyx8M4K04jmEGaQYhGPVHr1W", - "8xmvdS9FWj3YN7emn/L1XMXRiITI3+mDVLrRVIhPLoMwdaRNJxfPRyd2N2twSHwQzowL+0zhs17kvOev", - "GTfVW/3Sd2Un7gmT8yf1qemwrsCqkxlVvOupiaSKjzabhHE29WIMonhNWJzGrBHsrVHMSG8Vw/s2ojq0", - "moAxG4xMfBRKtmPEAZugVDZClaupY5ABq6aqaTyFk4DfFH0W7nr0Ae9j9XIlKYUC5OOg6K1YzBgEvagm", - "qMTIMVgu3WlIIoiPhoZ8MQejoaSdR6gK1xepoJqwfGUw8JaEcr0EwcfD0xgThpbqi5lbLahfjVeOpSDU", - "SDZrG+hdeOruw6ebrNCTU5Dmh083WYUf4Vk7aHMVO9+0LulUidCmnWa+OFT9awfbstv6rcd3AISkKJXp", - "yuIC1xCEbH0KhhiD6kMbfvvagu10LUUsfd20E+3Y9+OcwXionIceOaDHnLtPMGaDM8x5dTGjWRxBn8/u", - "cdR7JpHMZpzHzDODBgr2LDdqQgU7HzTi4NUV9baI7eR1Pd+AIQsinE5+Ojs/CYdOjvoMbqIQMDjbAor4", - "EequAn5Sr/6WvulUJyVBIZshnN8TehleugyZ3Sh8oN4WhAmMT9lNZMV5e1T/gNq2Bn3o6M/r1D4XULBk", - "BkdKz/0xNDa0c9H8SX9sMmlW4rVp034qIoNvzsyiqb/t14g5qOJqoGxMxXUsbv4VPhr0kRx9Yow8V/FC", - "A2kgPTOA3VAsIXDbdhcu226YEKr+aRcpM9fp0u5GQjD45rUVcQFLKIJacQBlFXmxFOFHIgnzAhiiLexd", - "zg7ABcl9iOL1KXOBhKC/HaxQojzXEYUB9GEcE3p0e9tdO/3utdK/8xu7CXHrZvzNTfh7iZcpL9QpZua8", - "3wUE5RUUzWpKsglHE5yBR0BhpnFrB7muyk2oFydRRGEcw8C73/Fts4QU9ufv3H+zONYWNTHTssBozvAt", - "TBGMY4yp4sUeIwyE380lOZ4/mX+2udm0x6au5D/lOAX+WqS/GV9myI7TQximffAjsAsJCE7h1lNA6bjh", - "kw3knVPI6FD2xr4Br3ZCM7qrZ8Ymn5YSetJXzA6r5RHd9jxujAH/qJqNx0cQCt5jrZ490DV/SmJlS88V", - "ohoy2U/N2IMnpnN5q/2TCE1WcisBJ581a8Cp6m9HUU4loiRI/KbmlvqhHyNuXIE7aNy4nqNr3Lh6v1+D", - "Wcc4cM1DwknHPzV2/TQQ3KQMaUB7rcPdGydVehAVGoa23w7Lqvk5umabaQr2W32xR1adi2LETSLwCJpU", - "nxTb1grY/Qpqu4hX5HdPysn8bapM9TEI2eQ+RP5YqTbCtuj3kmhTNZRbpupX/hpi4U5aJ32PJljUgsxH", - "plFZV/S0UmooCeEMxDFa4eYiS7ckhJfGsz9GQbs81F3YrzCC0/7/HEMquigCf40wnKlKtZxeXkavnsVC", - "Pzw0f8r+cCt0Z0FxY0R5ARFygtMod5dDz7hGJk6r5k3+I23toUMNBKMeyzaN50/8H/dd6bQXP2PJ0TDw", - "/CRmZCPFVLolD1HMwWShyr5yVgDPKmiY3v44OBcHBGeIxnOSKYa+Kva+36oOhoPWEem4P2Ph9ZshaUVD", - "DWL6Tjx9nT38Q0Q+5qDeDV4AXszmKYrsjiEyrMQk8yf5laoprjoyDWI8Tyca7Gp+B9kbCYKF0M3Fw8Wb", - "nlymF8Owz3TRbtRycnobyG/p8zYriWkunXq+vN1PPdVFaqqLqYuoKM8nCQflyBS1lnglFKzgXHYDa2i0", - "JEfMIVm8/VG9fFjBqRZzYAzOn+QHN8WwAaWto3/eEepDObQK/XFpFNB7spBJiqq92gx6u10r0Z4GUxwZ", - "TzVnnEmwe+W/eUAesYgYGT5x3lh+1Zn0Rq2mD8pLO6QI2DJ6y0QUbQGD3ufb933TvxNN3LLdy4g4lpz3", - "/kSqc6eLAgY6pb4Xhmhdg1WRzyNbSCkKYK/J8H2xVOtE+Fokt6OuMPrTzaUo2A4Dff67nTg3xVR6D2Hv", - "JgRsSejm5xeHuWm6nFgNXNoYbC9ao82WFMKUw6KUR0/stNKQu7if+t3drfIbCmjOFXPbAPoAAy/B/fbn", - "GGZ/zyEWDTaHP8iLlLWK7be4UaI4BYNIqlA4k+AdNwn6y1PvgwSl/jSNJLDFsxl1DPmeuE/8B8i8LYrR", - "PQoR23lHtTmSiOuPcS8O87oeu1UK6mcxf+vj8laZeJpzM5yVG7USx+gyqHwKZnlLEMeQeUnUX0R5P8TN", - "XWB0sfLjuMBcqdU080ez8JOPHsf2SuKmK8rn+PCXkdH6onJghzaIi6CEXq3gXWOGBfGzCPI682qKmEbm", - "5tD1GuM5dPvSnsLZm1Th3lnrogL5vYZn9sRacxAEIrWuWdZcpk9+LzJnWLbbiyzD9gLrcWfVNQEbY2fd", - "JXEEccAvjbG4tki7UJqpJ79AeOWRMOu0e1x7MF1V0xa80w/+zw4cfAdqopxEylZDTpUD7xQsr2Goc6nE", - "tjquDtUlUkkZcKIkUhJsNDUkTiXmkWbMFcmrrIG7GdwAFJ4olT8rIDgJ3go4xqC1wJi60KYtEnvsnN07", - "iQldAYz+KbOnT5/SH01wxiC4ib8ToPt3sLF/O9i2BsEGYRQzvpgtDPu2C/dM4+9gZ/92JPv6SAmvmlfO", - "VCxeU4zv7/LxN9nTP2ILwTLS5k86mLHJ9pfH4M5Js1fvZAGTqmxn2v/vEPH/w9a9MdA57pWyibZzkVQ5", - "VNWbPsGuvl5yABr50B7jKPkvV/FGoOOAIc2KYk6C6wdJSlDQDu180XJJ+V9kAXARneNRyBKKYdBnj6u9", - "uGP+pD45RnmZKGzaF6l8HrunSeUiaw4RiIOIIFV7Jz1RjLyA7/A0yUg/tGNqiJ134UDME2xTbd2Zc0oY", - "YHAmxchAp2y/7GA/ZAUYikwyYrHVLtViVAwjJetxi9QhO9b0R6+eG9ZUyl9Lo5lPgK4gp6WKIRJtZoK8", - "RnVg2duOCwh9iCPgwxnCW8QcKhD/rt+4Nl74MdL6LaAPrpzpKb2MPjlNLeu9PIRo6ZhybOWq+VP2R5P6", - "Jp1nVfhujKmHOEB45T3akNero2Xg9Pkcwka+QWvcOUqDH04GjLfzj6HIR8YO86f0s1tWZx5jjTpxCjaF", - "jPO6zE6Am3tI4zWK4sydcuh6GZX3uWqAz+oA7rcM5LCSyeSBwW9jg2y5Wt7rt55jz1turnaDm2D+oB7+", - "TsTzCOzYL5XywcSOolISraXAzIRkvy7nE6Ld4N7JpMoU7xeJl9U7GzClr0h8USArTktGeoCRDfJBGO6O", - "VJSRRwzpjFGA4yVfxNMpHFYVDhmfbCFNKfKRQ8Y3Yyce0C9/0pj51kV+l4a5hXESsqF5IWHruQiUmMcM", - "UGlPsgfg8Z8/qllEEMd7skJ4j/K5EeUz6CpXaceuV08TiJMNX7ZPAq5IhAg/TKaTe8LWQrClgTBLQjeA", - "TV6pb6YTtotElSJGEV5N8mV3/1BPfUkfI2r3Ovf/KRSFxclGYWgWgyX0NA08fw3CEOIV9IDvw8iinbgF", - "EmTEMTI4a4IueiVP3QYTE8g53dBnkYcfU2wJltXRs1VXKHeMhWRFkhpOfi9+19M7HdzpWvUixwoBzeCZ", - "gTBsgukyDPVKqwOZL+yBzKQAYjwqjBtYF8Khgbr0ReEqp7vaVUIpxCyDK6JkiUIofaZohWdIdDVak2CY", - "TK+aW5INnm6bFAQB4j+B8MaQpksQxnBaFLAojkKwW8iD9mmyAV/fQ7xi68mr87Oz6WSDsP77eZMkzY3V", - "TaDW7TJNqrFywTgHRiCOHwkNavcYwnqNvyO2vtGvDCNk9VR6GinQBxO308mFtG11MtFU7gObFn61BngF", - "i/CNhEY5efc2EmoYVVpHiBPC1pDWSdBD+Igb+N0pnar5NDlUSlUdSPMn9cnNdVEA8rgUgtI13lqUU0Pb", - "uz2Fo5WRB4jnFC4pVI1qKy5V4oFGbJ45YNP0lEmH/NAMhHDMQBhKASMPBKcSaNfGe5cJWx9LAbTKG18N", - "oFnVGJd4rSrInfaP+bLHV8HponIwomKZrcFNY/YmNGahJ/uO0vfUFSErUdWan1KmQpSqT01281pktu10", - "oovw4DWkiAHhYe6NKCgbNR8DddBy6FYtQ7Vm6RW5bSx+TvjUDWQG92DkNr4qC9xByL2Wbx6LnFPLkVxQ", - "4wuuAWHQDlDFuTr3gjJ5SVFvOCbKsNqKiVpXdmyiSiuJVcJKv+eHyWlVhopW8DRUWkR1sA2weVrZ8ttU", - "UWy19fr1EtfzR6/mhV62TOdKfS0K7w2753yjLl+/CXduCN4ADFZwAzGbgQjVGRU/pE9e3lzfiQbxFXu0", - "l+PANp2l73/2mHd5c50XArF+qwdsZvM0myurMDW4yVLX1nz1pBXqe0JCCHDZtaOe7GaLtEjiAh0k6vuV", - "GDkSOPK0bAFXr61l416ppw+rohVZrUZLKy59UNWsNFlX3czgFdWirzk/6xAWwT0Ybv6UfbfIOrU7qHhW", - "kjadMWWMpiW3RTmWMPTI0kMs9oRxKvYQ3oIQDbU5XQwGNvz0bY7rRqTGDJ+xoKlP3SkySoscnjK7jJPN", - "47yhMGFpjZFZ+zv3r8brR9NhAbIkanXttkHRqUvCh0837Vok5FRW/nqmr/baIEGhpD0n7HVxrsRrK03e", - "XJjtCn0IE1/GYy4Xbjc8nHXCQ9ac57B4cDdcjxDsPcTm7mxftdPtoBbqvuRBVabnsNTvOXNzVGY5dzkD", - "RD7oIdNAe+OPSqvR8PLB0dDU+YwSlPIJxtBnaIvYrpBJaVqZppOfzs6PnYYMbqKQq+NbQBE/W7upgZ/U", - "ML+lo7SWmHolXroSeV8Fm4iPN2imczN+9kPLMZWd6aAeazCGTly080NAwZKN0+nWgQ/mT/pjU6UvJ2x2", - "2yJ8Y6DNJmF8n+hqYEMXYrFIbwMVh9LuxuLNX+Fj3vxd4M8tpHXx4gfm0zmg/hptoduh3DNZrRLnUi6o", - "/Sa5cN4kcoajI0VE4RbBx+MhxY1c0Kg7zOZtBksY7jwqmmWLboY2qmrsHRtRk/sQqXjE4yCqXNCA+0uB", - "POoG00O4q2Mf0zeOKI3ZUQfLJQWNpXelcePCSk3CsapI2Ok8f9If3fKgK9HXiscF2CoTWnnNhshCahcD", - "aiBiTGVrECZ0IsA4pRTyfGeUbOa8Z/wpxTwJkd8hIMasPa2DYmxBoiohy3j6Rs7YNiLqevlBENjSG7EX", - "n3XlQrsmspjkn5FH4Rkz62dLzOcsqM/Pj9VjHaMVRng1e4C7+pPqTj74C3/uFCL0TcCUI7cmBUP8noE4", - "6XTPUlN6D3AnG5+MLRN0X02iunO7ah65ZvzH04G+BahmC9F2R28O9tbC6x2hPpSDOvZCFw9zbtEG9LF6", - "mdcB3TYkXzSSzVx7h+1kbrRx7cgx84A8YtHHtf1x2dxD9o0afD8CiFuS7xHqxWtC2SxEXOOLqJAy3ufb", - "94fYfe0jMgotq49H2LjfdXroaF8cwunuU2ptX+hFCL9GJObnj+HkOShT7BWcUcZyu40pkpjo5nK5hD6D", - "gT7b3IT0TTGMw0PYuwkBWxK6+fnFYaIQOwr5znkUcYHfDi3nu6ZO9LBfWxkHi9tUXQRkjUdAH2DgqYZk", - "w3cBb7NB5zIWfKAcire4eYc7nIIaqRTOdOj6EWFw5CyURgxaRNuVEQHAOfI+8R8g87YoRvcoRGx36LiA", - "VoRIRE/9uPpmV3l8p43721HqVtkLLCE8XbUAtZIKHaAXG0hupsuErQnV7cUsqTQ3FKrK76is9SdqtQej", - "dU5x57BqlaJ3xf1KDV7HPQ6d8cWj3kgC37RE5QqTy4Jq1RvlUvyes/7VFIDvhStrp+yaf5QNkdaQk6Vm", - "CmV8UBwnvVbvqTTR5Cy19VVjck+2NqRiP0wCeCtLSts03f6S8nLmVKCrAhWKo/k+jGN0H8KcfVQeO2wN", - "PV9VGkNFe/q4fqx9uy3+CjYwcLvCmVPlC0j9fLAiEHXcWvYr1FcF4pxXQmdjSaBc88msaTR/CuJAdY5W", - "TD1WffN6KM4aoDiSKuc2X05teb09d8ItFA7Ab62pTsWLB/KVdN0KuXrAtXL90nxwILF+/EXObdxYI5YN", - "pA0slY2ZRoogaMNZ+UrTFMYkoc1tKSS7FHHYWM/UwITZmiLk8tiMHT+SBjNFlrKXxq7A39ChCXsycBth", - "mqfbqcvSao7ny2aEwv3DGkbnlIrSfwKc/bZpwQ0gv0B4pTdp//6A7lROAsRmIVm534Mu+Svv+Rsn2g+3", - "dOy1xplzTcU83o6xpuJhkdeuTmMVNjtcag5dp7EX4ThyZcda9I9V2dGJjCdY2bFP5LZxjjnhc7TKjk3S", - "o12xRxO2Yy72OOSlrQYHJ1EtMsefh6sW2ZoxW4daNBGqlWA8ggKSreBpCHwgdbAd24ac9ho30Wr/9htV", - "X89R45Sc3HPfdfb/70/UuuZGg271A9StbKKSa5dvu+fxO7osuZ/V4zX7NvyzMgL6kB2+W3BS+87eNfh1", - "be59fC293a6Kg/b03oNofMNCHAxlPuwX7BqjIcSBK3fVh0iU+4WI7ah7CvaapNB5F7q0AjbRcerdgPc1", - "eqVNeeUHt5yYMgLbKwe6P+txNOZ127MpjoZ2B1UgeCyNesQ81Sb+7FDU0wTlGIt69ucdcNfZDlcWNMdY", - "w5UFraqz0I2/9jKRdC7DVoOqfo0kBge62Eg61/y8hQHwWTHnOQfZkW2p6aHLfQ6xaTsb3fM82OuBMOR+", - "rSrleWy80HPxz1FZ59yFdXLFP4+ea3o0yB20JOjQZ1G/lruuJM1qlrgcYWm9kXGi3I2iITVoVcU/hE1L", - "hbcn8WAdQUa9VvYWe9UUDrVfBLkOiPqPQgD5BiA8VBx5S0y2qdNhwnakdTrGZsS9an9U4vN7rv1RB3RL", - "/VHi+niKf7T2nFWXC9mD7/apILIPBE01R/Yj/KFrjrgSpL0N6ZjLkIxlPzpUHZOcONFFJsgWUooC2G9f", - "md4Yay/j0f+UMunpzPpuSpmMF8TzIxc/2XOXd66HMlA0j6ygsu+2GL+Cyr5kOPqgqqHLsAxCnaxRoWOB", - "gsz2MFqpgi7qVwaXgZ62TVWNlooHLREg9kGMCDbyu4BR+Fp5+tco2hMRDUzRrg5ANnIfFQEqTTYtKd3A", - "1MPl/LflyIFS/LNprMn+vRVtHqNMwLi87pbon5ePx5ryPzozOsnXw+T6G9J1/2vQiCzYrSJAUSr3UBvg", - "wOx1JNn+RcGaR+yRylVrxYCj5OnvLeff3Ie9Zf+PTrsGV22lXnXsTtsKZ+3ox2bC2mlwP0rzjY91nTZG", - "3gPDO8RLsqIf13g/mIohS6L5PSEsZhRE1aUlX6ePDMNk6fi3cvDO2b+iJ+2M4HCXXbFVP6UeC0UWOt9K", - "NOYKmdZWI5Wvu1nAWRJ5euQDFRq0QlsdAV7nvBJDHS7qudwIe5CoZyvCYgZYUn33FO/cyWf2PFojyodm", - "SL4NtgCF2gquKnjcExJCIHZE2ugLbgAKFyFZIbyofSe3Mf8wxm8cLCshQpRDonyqS47PlXsVw3hqGGFZ", - "dd2ask1qJc5/U7/vie9GmF4nKAw8hJeEbnRp3Mr172IGNxyAIifeCw68TNha81sM6VafVwkNJ68m84nB", - "hxa/gQ/j2FtDELK1slkXVvYs06rVSji7Fw4kDGcMbWC+6mt6iphDCGKUR7D2AIyn+SKzU1lJ1LhhGCPr", - "wK3y2B+Av0YYyjMgt8LUWIDwSnKYebKuyBZSDLAPjWmMQ7M8k6HFz5IY0mI1FD5FRMkShdBc+rXwGnAm", - "Lo34DgKWUBhP+XtB4jOFhKz9ckSRnxvtCjAQkpVlsP+kImxOFP8jPgg9MW0ooPGUJDVHepv9HFuGuzFK", - "aIiO9LoOsM4nD9ES+js/NPGnE8AtTCQ+gNBjEAPMZuARUOjdvZhxcQ+YrDksA5WUd8nkK+UKKQ/7hogg", - "QSjCV6ceSdiK8MU9wvs1IQ+aqZIAMRN0Ge367cu3/xcAAP//", + "7L1/c9w4kij4VRh1G/F2Z6tcsuz2TPvFxYVatme93W5rJLv73evRVUAkVIUWi+CAoOQane+zX+AXCZIg", + "CbAIVsnTf8y0LJHMRGYikcifj7MQb1OcwIRms9ePsxQQsIUUEv6vszSNUQgowsn7N+wXKJm9nqWAbmbz", + "WQK2cPZ6BspnViiazWcE/iNHBEaz15TkcD7Lwg3cAvb2vxF4O3s9+z+WJcyl+Gu2/Pz5/ZvZ16/z2TlO", + "bhHZnt3ewpDC6OPN7zAUuEUwCwlKGaTZ69mlBBM8bGASRCgDNzFK1gEIUoLvUQRJkKIkgVFwswtidA8D", + "LD71bDYX6/hHDsmuXEgoAK+AhLySz8/0JUTwFuQxnb2+BXEG5zO6S9m7NxjHECR8Ae8wCeEbGEMKm1j/", + "QCC4C7YgAWsYBXALULygcJvGgMKAwFtIYBLC7H8GkopZ8L8WZ3mE6OISggwnbcjfMqCumL6P4DbFFCbh", + "7ke4K/i7gSCCpPy29tiCPadD2YIvP8FkTTez16fffTefbVGi/v2XAmZGCUrWAuTtB0DDTZMw5zkhMKEB", + "gRnOSQiDt5/AulhtA6XbhfhOl7gZoCdhnEfwElLxxqORlkg8tSLyMUeqfjzL6eY8RjCh2qapCxv/e9+G", + "aa5AfBxH8HwD4hgma9gKAUdwFRZPdYHRmPj89C8VJr58MbfC4gOkGxzZ4bLaioe7UIJJvp29/m12dfrd", + "q9l1Kw6XMEIEhvTz5fs22EQ+ssoJ6gR5i8kW0NnrmXiwFWKW4iSDn/if20CKZ1b8GzbLZATqWOZViNuh", + "ZfyPA8ToigLa/lX+x06p6dnqQnO3nhtCu45yZHzkSgTEF5BsUZYhnFzldeD15eUa+LHAdcmEAihFoikC", + "ecYVnFAMLbJA1iBB/+w+j7H20CjUvQC7bVWXVQGm4u/jwCpI+lcCEsokNM+6RDTPjMQEIUX3Qnzv8R2M", + "zPQcKi+jLdJdbvpViYUcXUgDqZ2l8oFRlssMNZi1yw8Rfx8NFnt9sGVjdUhaWTpXkLO4ddmZ+Psoy77K", + "bwpbqh2g9tAoUH/F5C5LQQhbQT6oJ8aG9ze+SRpG5Nsv7C6CaADCkJH3JoZBgUPwsMEZDNZMsWQBIDDY", + "QsKs8AdENwHdwCCUNijbQv8jk0+2Wdy1tTmt5etcSf0POEKwftcS1lVyi9bsDyFOKNvKrx/1u9by94wt", + "+dESsPnrBSYlV7iVTCFJQKy94w8bBawTo5/BVpjr1tBTglNIqKStYFnDEJrPsjhfi2svZWjMXs/+n9/A", + "4p/X7P9OFt8vrh+fz1+dfpX/vP43o11YovubgCS/W+peYeu0LI7bYux/mMhj+w0MUYbEklpW/GXx8PCw", + "YCbrIicxTJgBGXWRoLxwmOhQuyz0P6Js+H5TfT6LtOWoh/nemrG/JbvZ9df5LMFJaAZcMeB77fR5zfru", + "N7Ln0oI2yocykbu5Xr3N1e4b1buAstaVfd24prXdlQoquojVJ3wHpxQj8dcMhgTS5hPz2QNBFH5M4l2B", + "JmdKq7zdQ4JuESTGJ7gMNbgM9J204p9n1LklMNusKKdHgWhIYAQTikCccSF0FzX9s0YBahGtmgBpS3Fm", + "73mxiKNmdAuNWh/l1FhtkFhLadizg73gY5UB13Wyyl9bUvQhgSTboPQTAUl2K4RulOOu+WUzBrXbzw84", + "2o2GwzmBgMIahDY81P0g2UCCKJCa2RoPEEVIXpE1mZIes6qYIQniJjY4S8/iGD8E4QbFUcA3UhZQzD2E", + "8T0M6AZlha/32czoi9OFQQdlKRIX+U2Mwv3sIDMxhAFcXe4ntiC2k4nyVQcoCwikOZFubGak5gnTcOyx", + "EFAYBSRPKNrCBXdfrwOYRClGCX0WXPHNKSzdW0xuUBTBRKNT58ovobKZfHBdfbvjTvXcytKy5OMljuFZ", + "lqF1spVLGWVP1T5rhn314dOF2lB7mLAbnFGjKm7soG4H9bzdGE5Blj1gEtkp6RQTKnmItkw5v/ruuxeC", + "h+LfJQdRQuGaab35LINJBMmKBz4qJ6z4jck4E2+0Yk3jbLWVRoQ6JTIKCKVxxq5uW3ElXFF5xrPLXcvH", + "zLY8p7xcrwauthZLSbyimIA1VALhQcXXIHTj8TmNMYj8YCC/bYKvWelcuBsH5CXMuBD7OoDl9zluVSVc", + "OBkCrF4KqHyLwCgAFG9RCOJ4NxMn5U0Mtx2IpuKJ/3RDWH3XgODlu/Pg+5ff/TlI1TPzGbcDs9HIxT+n", + "Ah1GHDAFFCVr7ikJpCeL7x/5Ce7QCEOY0nOcUILjzxkzJ+4RBVTeBB2OiwhlaQx2K9OxcXIyN+lEBak0", + "zbvOlqZ+a9gOtQ82t/ucLRjnCa1E5hxWWd75hNHd70cqb08aRf7S7Zo0qfIYJXcra/u8fvfV0e4gy9sv", + "6sRwoAmIIgIzqSUQhdus17Uk3uAng8AEEAL4ZoUcAxitAK0cPRGgcMFsKNPxw93pfdzIuJ6t0kWHNlde", + "+XI9ZkpRdA8o/PTx04Wr8PQJwitnma+5SzQ0JYkdWSlCMqWAaSZJiOiuxQmQJ5S0/I0fNm7ctN9ZMUrg", + "cyNc9pdTbsXmcSzMLmHNN55U+qr3wRRnFMSrVl8IgWupNXs/pQWqLFdaiTA1A0mFn1tYT2nkTPR7SJT7", + "r3gBJfTVy1nTQqzrXe5ar4VO9VCcYJOUoCohS+mZl/FAhUuHXF8AZ9VdaKZ9VVQCv9BVmJMMEwtu14nF", + "gVc/Yl7n73lG3yYU0RiqC5HDauGXFBGYdclAr5gSns1U01jfGQ7zr6YFlJaNqxLKIwTbHM3sXr0Kixt+", + "18W9gZJfZYRkkGQodijLcnGM9Xk0W69Z9bQCS8xT7kEZirfMwNpL0lSIp3myH0CVNZMzOHpzddfsVE9t", + "AUIH+b+N8UPmEJ17F+OHIjLXjdMbvAXIdT8O2TbsPq7EtHij+OVe+ywr8k3UIZjCJBLWkgxF8FAMTzaF", + "UdPhzFmq4SI/eG1DOv/nToNZBzuBjBLm6jkurmT1sE31slpeO4MIZhQl4uc8YxdYuoFBBrYwwAStURJg", + "ErC/38OAUw0GMpxEdwHIxNNonSxQEiigz2bzXq2KxdGih1Q6XZ3zGYOyQn1Le/sFhDRg1mFGIYFR8F+f", + "Pl1czYMY4/QGhHf833O2KKGHFwIFtUTNQ1AsJ/h8+b5/STW+19fXgv+8lWk9QlJLEnDUMXlG8Vbcb1dh", + "DNB2dQd31W2jGSGvXtb90HpywNnif4tcgNWzxfV//puJ2Vvw5b347ovT5v6KYAzXggIwEVrEeCVSzli7", + "p2KYZT1PQpIxcq1Aivj6ux8XMkUEonX3qhAmxU64wuwOed1yeV6VPK/AtMik7haJgc4kwN1SMFoJ5KKq", + "VZRz6e01KmpFD5bHi/4WwTFsymFftOFHuDMpbfPF0RhuH3DgOjjrLa4G+93J72yMWDd/Vvexr8RFyyVV", + "y4z4jbiSBzZElsoPjCgTJrukUamj2Fgk0mrsu7bdflOaLdqmPwLTZcqVH8N6rxjpM4rCYa6/FSw9Dpk0", + "gUSk8MQUKZQvpQRHeWjzArxnH17FIKOr05erDc6JxVsxA6Knxlq8k2CKbtVOugUozgm0eE0qlVWMQxCv", + "ZAKoxXvsoBrube3+dpZnDC0Y9T9KMRUpRl2PNRJw2Dua/62EZxK2B3izwfjOgaaF8swcMRNErXygKXNz", + "o+i2ctIoTW3iYlhtiwwbt2UeoYEhlVAZTU2rJqSYGNImeQRvJf3B1fqC+SzbZRRu+VEIk8j+2OcxevvH", + "KSBrWDqpbbyEJYkuYSjzGjz7JiL8kMQYRC0JhL22wBD76RbFtFNBtDkFre0uwsm34u50C5XSYU0RCKKd", + "ZkDNZ0z4Wz0pFcD95glj+GXhWHZgdbs32iUjSX6lA7UBUti7XYfeYPbc680bkDMK4QYka5gdma/d4Oh2", + "XlkpTxaPFtVPNo9LNej2dLvSbN4RSrGYK9mrfqdC/x5Z928ha/vqYBZyTjei/NnVSNuWbxWrLXSmSsaT", + "1zQV09yCNQpX/CY8n60xXsdQXu243GOaCssC5HST8J1aJ0rFtTO2E6hORLXEFrAmGG001pMoXRToCIoK", + "xPENCO9sywL6am2SW7TOSRvVlQ6O8Rr1MMh31LGSWdoELx9ow07+mRnKGhMsjPo7uLPVcGwjQGYhlOeW", + "BYAxdHyqiWNR1VTdj9d6AYh6BiUZBXEMpGrVUan6aMTmhWBrSwv3gKbpBCjWVdYq6Y59XSjaZLVvB09w", + "LGjq4pDnQlGIpBpVOBumMkhCsVWLiqo5Wr5rwu8HuEbJr/CG4ckjyrKmwN2lPiRzUcTbnBfVm21YWdWl", + "drg4rikGNzBuNEcxJZs6rKSJLYpjlKwvCL5FMZzigiqiLiuZiDhU+bWHBHpftRcR6/Q5zzlvFHzxp4L9", + "psd15ZOUsjfMrEIrDXOLCJm72TUkVsWbd7Ummk5n/GwhBRGgwPl268s2YX9NzfXPMkmrxV7d04JpuoMK", + "Z3CRRzOfQULYMTpwCylPap9prZ6zsuN7jKOSaPPKZpjrfWmE/VS1mXQkLPbl23v3DE1AKdymIrbQEihp", + "cwo4xWNBRleCc1ZZzgSHMMv2zOcretOIZbQILYEhRPeOYtTluSyQL32W8xlaJ5i0ei+bmFZorwmKjq2t", + "SHg3oo1yeChjuobM1Is/9LoHh15vCd7abwACb/MkylZblGCyutmtREeccGdNt3P5wice+DN6n+5hkkOf", + "IMS2ElGDDnq1/74nDlrnUfMXeOAFnHOLv99FqC4+1VffJVP5dgtEbY2DQN2Il1epdmWJ44+3s9e/2e4o", + "/t7X61ZdX2Lq2bBvhP2t5E9vttWbeNNlnNdJWUfIyDuMKbvRprKrmvuVUesV0p8ZVa+8HJ4bVr/Hl4io", + "j5iWew6SEMYVirtaQqsUEoSjlQxO26QZFhWcZyr5y78/RMU2UVLRQM9774AVYJXvXJuXlqyhTtALgkLX", + "szRl77hUgRAsPfw3cAPukTgxiwxQedNbFY/xVAgVkjT8DcQPYMfWeI8Rb3uc4AQ2rbACTTMlYHiHcyr7", + "9DmzWLw9NNA/6G47Qt0V/CIriYpe01amuxOrhdGr9Te08uE0bG+cilZNeJvyXtrVtEuvR4PRzdJeynEu", + "UbyCNE9dt5LWdEN3NZ6c1vLQT60KeA24ySvxHiG0auGCS4aEoVOUWx2+UzjMuRVKGWiqkL5/VSnhhdor", + "9oFU9H9wXZcW2XEC3tp6ziyZnHjDQ9Ra7Nns5irD0Z0FCi1/lfJoDoEbommdtlZ7nFwLppcge+h1gWMU", + "7gaTq1tSS+z2rwJppYIWZTfAM3y8gyJv2VevVMqeS+8OGKP7olmrOvBvMG8TW+nMKPP75+KP13sYlx32", + "pFiNlr0uxWHI0g7TZURrqDJFvGi0C4BTwiGOK0c0b8XD22dsEbMJtnB7I36RR4hKx3GHo7nMOhYFWFQa", + "EeNEzNWCK7TSvXs4hn2slE1SvlmO6jGDVR97FVfnzGq8trBq9RBE9Sxx2c7Ogcmm/8xdbk0CJQWoVW4a", + "Di9ZbLn1csQXVwbEb+wNf6rLbfweoLg9pOa5owvI6CrfN/wwOK5nlS/UE3MqgM81UvYmZNbFZR+bbYjJ", + "ZRIgE55Hq8Cbyquucpp7sMKVCqI9J8H+ha37iHfxkZvddDH7Y6kvNRl0/Rc5kf/aRrHmWZXcYEB4+VCz", + "h7pauOHqM05eOq9g3a9zzzi2mUOFrajcV31wV7VG8ZriGlcbqI3e4FdvIYpxN3sPWZp1yKEClxo2U678", + "ONYrjj7ha3fuVsFnkKw6/YL9SimBD6uRXYuV1rj65y3J8RNeO/cHcjgaPK5WwexeMT/59u2NWLhIKrJp", + "aJVY74Ha54YVrfAKM7/Z0+T68fTrv7V0UxCdEB09v0WfxJ4Ob/NZW1/XPidstWtiBUzvy2VLxd5usmX+", + "Z91R66ZKpFlp07Jw1dp8U4rZnn239B5alSbsL9y8z8V32lEdNc1UWQ+nJ6evFicvF6enzyKwiRHghoKz", + "/78rT5K3Hrcfb6Gy+uzfaQQry7oL8Y12mqrYpevZwqPptlVM5lChU8v+eTEcsKvULQT8mkgfUEKNFWsD", + "ws3F+DrH4KC3TBMxt2RI4mmx+upn5jo7O0RF1O467ro4xg8wWokJaEam7TNmp8Lf+SxP0D9yKHtmye2k", + "MBBjPyoYNPVz/+faIpjPX1lHMOt8LuofedKxSma5Hn6c6Q3Rqivu26m9BOgYVyUPJX2RHcI0gptiwG0f", + "JZVBE6fffX96IgkqfvPixFzmZ7pql0EoBdfi8r2/Y7dyq2yn8JuiPdzAprzIXEhSEO/FqwrlXrV0qlFj", + "guwvYeVoIdmQquyDp6Rf/vO51ZYd2JPBfYiX1gfORu/X+31Zja6sd55Ro+L4Ehsz43Tyt4vK8AbOqkyi", + "R85aHNlDfHCj2BK3ENCcwNU9iPMBbSMGWBFR7mQSWDe1lt1v3Gg4ZcZTe9pqhzzew6QYZeySIQAoWA2Z", + "l/XfVx9/Dq74i8HpyenJ4vmpmOUKEjU/i2BMDSOval+y4Bf8ArZpDFc2oZ8qlh/yjAb3IEaMuQFYA5Rk", + "NNAWbcRPwZOUH6AGDVYIt3ZaRp2uFtd/+ve///1Z/Xf/YW5yKlDXr2blufr82cmsCuf54vvr304W31//", + "iUFgP/yn9ShVXTyadKlxpl063wnl4Vw+AeGKbc+V2qP1Frxq4nTwsIFJwFUT3zUByoLi7QAkUTmDLcB0", + "A8kDyuAzzfqg8AtbTpjdz+az36uNhEq634lp1j28HxykLISm+/vlMnW1oi7W89k/csAOJ3a0FzQwjyLX", + "GX4Hd1on9BJEO1OHx8p6O7F2tPXVqsDL2TJDrdpi27w6efkXtq3bTTdru9fdROnvQupED/t8LM7GDyAB", + "a27I7HVbLe+KBVF/my23xceXlZjt8k8Mo8a9tuf57rvXnjfNQRfHvrtdO9l/1voSfoLbNJazjp08ShSu", + "scjuKxxoMMyJ2PyywoXtAgKSTPST4iUfW0DuIGV/Y9erDd3GK6qhUKXAifFIlqqw7Tx7trh+PJ0/Pzlp", + "8WrjEIg7Xdfu+Ek8pdtSZixtTmSm4dvefy5X2at4CQI37PyzspfqEwlN+rZgoWGNdZzbZak+WNYxCb54", + "2/mW6WJzj21Ay754151NnQfeErsKxzRydXKEN3w/u3j/I9wN9iasIrCr6tQXr76r+BNe9c38NLVS4fc9", + "c6sBF2+fueRBrB8TCuJh1T0DHMgiPcHW57C/KJbmthRG+8udvroK4h3CNKBIDGxxnlBRo9pfVVsUVJWj", + "gpqNH7VSYU2WqjGrFyYXrnxxBb8I+lYoeGrsJl16V4ZOL5L+CnsXmryj/MJMX5NtsSZMoWQwxElkUajM", + "p0bd89hivXHr887n8wRVhq5H3En3AOEdO7lxwnP3dxCI3B55DjcNxFrDQMLsAhkLwwlcST8HP4iLPjt6", + "fWDZbySM80wkAsIv5c95kqUwFEN5rsWtBEWI7owU6i+kFMehnO1bEV5N8rq2CHcXOZdHVPwQzcvCEYph", + "G8NjlDVjr215DPoVtfUaalElGBFwS/UO44CEG3Rvasqh3S/b2XjJS+v3VHXNO1znxttrGJ5EGzu3D5Ns", + "tBwvMWhk+3FEEhoNjPQWRZWT0slDobr72Hnrr/iw8PciA3rnL2aGslWx91ymwfdmwTjbRJ1WR59LoD7F", + "vI9eINnJHhQVmKJH000e3kGeWvBYj6zzKs7i79emnOosW2l1oo5Vntw3sVKAYBKlGCVG1tSHlpUp5wsu", + "aVGAU7pASXCLScAPTT7XS3x5kUDK5Di4ehEoIJnmWNbLOTQcamZq7dZtCsFgEsJVCuhmldGdbZqNc17O", + "FnzRW8aubna05th5fvLnF39++fwvpy+NLrNOdVv/upC9+vfFfXzAp0VNBNqCNTQgfnry/Z+ff3c66MsC", + "UdNHX50+f/lyAL5DM++qG6ffYaw2IsjgKiexzRWpunf7QRgT+mxquUW21arc6nvXccoDothpBXLzmkIx", + "Ae/ViZ/TGIPIPeRL9SwW19AriqFBVmy8XsMLpnKS4gw2yiPE1hJpVeif2h5zlP17lKEbFMvTuJHWI2W8", + "aUYWtJhXqVpBp/L5dpYOqeIV4wwBpQTd5HRAINwlVsEJXow+NVZd3CKS0ZW1HYGyFSbrnm/yWj3rT7r6", + "csdMFRf5I22ouiUI9xlFv4ocU1fjkbcc1KbE7JVJNySDsdu39Gthfw+6vzhq+/1Do26ak2eKrZxyjByv", + "rZV2eCPfWw1+Os0HVysiuH588bU/rK+1qquAN61tcDbcsPZKYiDNyn6apt9yxNItMIKjvLsGT629vQhv", + "zyw5x1JFU11emTcnV68l0NlOsCwFyntRmia7h6pJe4OyNKdwAqUwYLvpimSffmOywGDPTtmrSNCqvZ+w", + "9USncp9ZCHUhuC4OZ8lX/yIs5edQ8vtWNXM/49ejAUE8mACZazqkXQUvf3DJGN0jjC2Tbhw8soVbsymB", + "OCdhNfbCPs9zLkhZ2SwnkujKWuS1+wloS3epRM6mUQXDs78dKyV5SHMCo0v++JDTscVvPFm+gEPsX9BE", + "OwM1Me/cQ29r03ddbhD6UIW2pskDIkrV5ijlXm0DYaW0FC/qwtRsN8IF0f7DGgFFjosByLhmT+Vr+myL", + "CsHKlRj5z+6Uw6qSx2+/NkoXubGaxomAd1KJdMsuLqqfS57ykh6Kt4CiUFQCOVWXtBQBScDzcl2t1PoF", + "EnS7m6ABsaGM+i+V2+1fbJwhbqP3XYc7vd2mdHcJsxQnWb/pswVf9N+emD5Y39NTFtI8sR7AtuU3ex4F", + "Lvfj/bvZCNU59PYg364f91uQ5DzLtTIfvNbffVbmPKkWOcdcEdQ7akqnRUNY5rWtoi/32mJfer/q2Bzu", + "09x57mFC3yb3MMbOlVR8eG+fGuodutCc3GV1fIA822/aF04oASFdNW8vaQwo+973L+rzpYzfIQTGe6Ey", + "yD/ssAkbtVPutVL6Ja832TSFoaGHxvNnJ0YCaiVn/QOm0RY6zPC3mkOtozufabpFfbIpKxKRhuw2aC15", + "27rx/OuZyvY+qJL5tEvhG3iLEjSRg92h0LOvXrNp09yLDMm8ltjS7rN0qehsLc+EajibE88NxZ379jXF", + "IfcY7mcMtaddNjSWhc/JSWt39P4sEzqPZOCmKkyFui1nVDTWdat1idJUXuEh7prlWWzoaRRYTXUcTI3J", + "qNUeTTNqIb+90n6qX+tC2KFuFSfQkNioHAkCUj2vUetjygVWu5QbchxtLv6VSO8P52/evvvrf/33jz99", + "+Pnib5dXnz7/8uv/+r//9+mLl9+9+vNfvr9+/IshDGwe7RHBVXHpr+HwslrWwf7ZbFonitQfX76whOjk", + "HNKJaKuL93J/VMlhFiBxdT/L6UYJ00CZH03cexEd4vBT7aWs0wWrVdWGljYD2m9rLdmq+PSO2Wosf9i4", + "ttsYP1SLvUpn5NzSaSk9pNc8T2qNktWmnvzbugX28nVWXu6i0cCc+HE7TY84AWucPvNjtIvv6QtfZ4B/", + "26HO8UMZDsOagQyROFMDkfaOH9YDL+ylsbU6b988uHFM8Z5GIkku+6oVh5LWT8Qo/m1NRLQVd0iE9y2g", + "JO/Aki/c746TXwVXhEu3JRVYen3txbPcH8Vnq4UwZ4FYMS97YTsmwCQ4v/olUGWNc/YLkOxEj6WAN4Xi", + "3+Jv8H+qR58xiKo3TQmwq4q2nvtdLtBIXZSgbPMrvGHnfnIOCdzixPlgk6+5OF8rY12Hd4TQQVe+alrs", + "f0EQc+tGXtwdlmgY9ngn0vminUV6RPskxvJipazjS5jJWrgB1qfW3NQpH7R/iOt8tr0Fq3qcdsBAhz0s", + "tJYWrpVWhD12bknvS5i5d+7xmz/LDTGGldP3CVtItCrm6+w5TaKChPnrvVmr7+Wc20F5nJGaIW7pF5Wv", + "pQBFh80BHRim3uCMoSFnAw+dzzuk2bSE2JJB2poWOumY8/HSsTtjwbWs1lIGezJbpaR7N8PUjjqUGfbf", + "v/545V7uMnzuWrw2bzHjb+9aJPiOmjeqOSCQZxaxvjveJuxO5ffz0d7saGW2v02OaLNUxmwX8NqvgV3z", + "gUiec5rlPkbnfMd2tVMmg3QOVue01vIpzlKmIp1rk/TOJ66J2IZoEkfCGEQyW5dzMwI2Cx7m61NiliUg", + "zTaY7p3HMchB1kJ0Z8N0zxwzWyLskYUhZHgwINUdevAHBlWUGKanKcFmX2Tf5j+K0RDxFLPyxxq7Vuy7", + "zs53dao3+GiQIYc9693waNMVhzJEfipKp6tul3OQ4ASFIA5+OL8IXv45iEGyzsEaBhSsgywPNwHIApjM", + "gwguzv+LO2FSuvjh8lnAk3SDLQRJFiQ4YCITpIUaeFbtM/LC1Abww7uzs5Ci+yEhXTHowalxX4jvoRy5", + "1FU0Yhzi32WNlKg0oJhY8eHd2duE4Dge0NHfedX81pIhnKBkbd20cOhoI50Q8iMGDFpo8qGY3OHZVT91", + "hEc50vdT/ypLJkKZHOKvJdoVkQZMU97B7wbkdJO0uM6VwlWKuCd8VPDGu9IspeBQarLsUH128X6Qy1Mw", + "aiVKwCyaN4IU8XY5NhszBMlKtK1umeCdCNEw/lFMV+3oCtVT0iK/XcFiXl9uA4y2wG56j9QR3L5MvtLA", + "e5T5xiMMlu9Ij6ts/HFMMcN8qBpF511O+Drz/OuHurQcTE3wMVDZBqUD+jHuP2OqdbaU3unddStRCrcp", + "NfSQPRnLCyyL4PY8Th2Pb0iIlSS4dxciMESpUlr9STbNrf2PHOZQ2ErqmC9IxO43AAmFm+VpSmCWyan4", + "QJ79sln7yhz5Nx78+iv6AuyNAV3CvO/3ijgfaq9XVlzxcgycn9DSfKvz8N5b32vd/6vg7Jc8Kbs1Sh8H", + "4wdOta2XWLmXSw0Jt5VzOFeqHq9NspRZsV+lqd44wNAX1Fpl1zqItrexbfbf0ma47NskplIpvqWpuZKh", + "3m0Yaa1cZ1WE6oURX4XOh2TlkKgs3xg3L6uzO5/66x6y0ZO5qJqFqFbLOlGqK67Khu1+nVhnyXUdg8b6", + "mzAu3NaeaB/YKwwjTZveIEwdYOd9Q18eu5ujjKIwG2bnZqvS1Oq/o6t3pEnW+0JlWWJFwrDuLKfv/mZ3", + "RlcHxLlpzc1F9VF84OSoMY7ALuNpyPnYGEM1QR6u8xwqpwkI5rlV/ZOpxq6zsymrE5cPSY/KXKqyqM5S", + "CyiZnFTNFxvhGNR8QQEC7xF8cCQC2wh2rumOCtbiVmm/SXhGvOlb9qKkQ61ITlF4KdPu+RpNZPx4ltPN", + "2GPze92OHl2W4q9l9Kabq8ZCPZcR+PPZFoQblIjg8IEcpinO6CrGa5zT1UiD9ccb0e8USyt6xItBXTBa", + "Yeln8OAOaHP/6gLQs2e861x9fx5K1QoccDIg59lqs7bKtd/tNET5jC9zRYyhx+eoM2EiqZMcP5jYvX9z", + "/gZlIpVgr5oG+3hfvUx7JaL52SrL0xQTKu499vIi0srYbwd/AkWixnqVoTVPHwDxWnaaGvzJhBKcpTB0", + "pg7KshwSmyd/f7jLbHMtiGxytx+hCLzHoTvDxQYcClTP3xr8EdeotGgPjpJbPDyULTk5b9sqhiB2wdIO", + "jrVTxFaSjapAdyMeU3JM69FFIEX7BvlUjLQpsnG+9nFxHdQghiNTFqF29G3RufhWRF6uIKUoWWd7+FOK", + "khR2ThAk09qa5qIcJcNbzrQ8ElVaqzT/XnGv28JV81dWbKOxW0PYAUE9HMMss3tBDj5egRQVc+wNj4n5", + "UgSuUUZJx/cexNQV42fqefGGb7Yvt3ttpoVU+NFP/HmfVNRFQFtsn7SKVIcBU6gIjleOwyQilKUx2LVb", + "xQ7Rkt8xShzVwYDEjM6MnSzPUphEMmwfQ2oaVlon1bxYUoUaRTP3Ds9Yk23+reWmpBzMZtZQGbJuLXq3", + "UpJQzZX+tIGBqGqjwYVsesbTnv9HFuivLx5QBAP2DZ4uzZbLa9T1bbzASbwLxDi4Z1qPl7rMKVGz7xgx", + "mH/HwTkco9B5bKo4UVeZdqTarrp+GjfnRjbnN89+ZiwVme95EqMtojB6pg+iax8JVhv1yMTHEkAAQoKz", + "LABxHOjoBSgJ6AZWxMsdGUP83EZl55n7VqvTtjvuVVDIoX1DBYL6hEn0uixAh5HiDYnRmTtvymeT3IqS", + "PWYk0w7ZBqWfCEiyW+dzOYEPqwGDythn4D3CeSbfZkcTzop+omXbquKILFpkq18QuMX3hhLDJkpWCx/U", + "7sHD0tvX2Xhzz8lazoNYalMlqki0Yte5YBNrLqRtez6kSZ08Tlf6pMZ+RzmTmTFnOxon12lI1SB2UeES", + "ZpAOaYQ3/hCOCkrf9HiJcSd9dg2r0CB1kfwKrZP3ib/h7x6Xq2Bar/Nz6m+d1ZGzzZwK0PnXA06LHUbU", + "3YCKwGOY4jewCNwlLVRvuTJ8+F91iODRtG7Zt+2KVcsVKV7eXQJKjA91myxH7vE+IK7DBIu3HVZcH/K3", + "BV/khDk1qVj902oe3d6Wn74ICxINsqUJf6kzn9FQg1jHxOscNYViNwmGzIMaOjpF1tqv2kc6+o3Z7DO4", + "smhjoZ2N3xnHtI8yr6ndrarmFl9PMSmpdZTjcN/BGDM2u1pnlDyWU1Uaw1LqgmgYPtCblFHbQP6PldqG", + "Pfzx8mNzLv2rxlx6rZX9v//973/6f38Tzeyv5X+frRbXjyfzVy++/vvr1j/9x5/+/fXf//6n//i//sM4", + "IOhCho/OLt5LlLwPUPfbzfEGxu3m/t7tGMYZqd7QRtUp6iLYnxJ4i75YFmeKddde1ZKkbEefV8XhXPDX", + "+XxDqqz0iLp8tsnFEI56YFAPX4ZOixDvzQue9PN8Cl2sa5yDqWJMKIivYGHQuNj5/F3bLK3iApkJYOYL", + "ZMtUCf2luQ7YuCaRxz9C4Y1jebqjd/oeEMQ4mu3XiLr8jJkYg7vhtvtD+kNhalynrJ2dZN5rp39F/XEF", + "vwh+mEef6E39BqKuOqgfwdTX1oEG0sFcjLyHjDxCleIEriSFufdPhmFEL7m92koaa64o+LK6gRtwjzCp", + "VgKHcZ6JF+CX8uc8yVIYioLb6xHyz0Ql1VY09C4kyCQvNVybMm6UHk0eWren/8OGHLKB7wXBNzHcuioh", + "Xg8Po5VV8LoMmhhaplDpLDfcsnlHQWtfpl5KyhjdYSZVD8RF6dXto6q8j4rv601F2galXYi9OcVQyupg", + "yf6WBv8SyjRGWUezhfFnx/AmniPsfVsNfYis4MpkmoLA2m4oyNqndLuTQeTemUABiz16MBWc38Qo25zz", + "DNa39wMqsWojq+3C2PXp0lYJrEM2i1ZbW3et9rQOV9q67oLS5yeCxT+VR2m1uP7Tv//978/qv/sP0+Bp", + "s2Yvq2tbJyzxxhP7NSID4WYL65W1junHbEfdgAy+elnZyDc7ara/5Ssto6vns1sUwxa1Vp8dpJ6sfXVe", + "x6u/7b33pmT1JmKVuPfzigC+OJpLYwXpVhGM9pDBWxDHNyC8497GfXsaSUMNRit3ZmY4vh/wYlevubKZ", + "3HV3f+4G3k2E5jVKmZhxCUOchChGnBFnYQhTd4fkkDEte1z3VN/da6d+Rr0NbKqkuMydC7rwNuVlBHs5", + "wAeNN0ScIBZXGW/tGQcwlsAUIJv7V0YBoaNHLMvuzSRPEvFTwcKyweO1vVBpjChX1xuqa4idd5OxKeiH", + "Mh4vZT/2c9X03c2D6qljvEWX+EsYQbh1GCA+zmQ7XgMu+76RukVw+he7Ud3PVv8fH9Y9f35qNyLcZmBd", + "FTMzyW4JzDafVKDFidX81TLldK+J2dWvtaCaJ9EfqX6G87uSoud04hNO1DaH2KA5LC7zTFyS8QT/J9DD", + "XMwOp3zTGITwV5XuIioEL3HsropxDFeNyWidS8cxNAUnTSl3hvbaq9YRY5ci4C/DjueqXbaTshH5UTIu", + "6Frc1HjdiKV7X/KbHMW0Old/0H1HXiUtmaPu1K5T08bN0zwdkqfZ6ACr93itZPiOmD3WnISntU+V2Vw6", + "cWQOWMHcbp8iY8xZlqF1YpWKjhP48Xb2+rfHCk5FIdfXefUPZfOf66/Xnf2SrKx7tk1dKhWnLb9S6PWT", + "2f8xUAHHTGJywEPBhMwerbUm6ag9hVQ6L2Tc5GmRMt0jtM2cx1cvOlIea57mx5P5q9OvxiRG9vFJ9sHh", + "5D5PmHTJ9mKd8USzTzLGD70rPCtPoHcxfpCA9FYsnWMGKn1KOp/UW584PFlP3ig6SyJ20YUrzO5UvV63", + "5idbEDKsu2WRHRwbxC2XsU7DqgnYJblX4Bsy59TITLa5GRj+Fkismi1d9YsWJnLTWyzjSjytVlLPia+C", + "0wZPzbWOX/VU+OoSJVVLxDrEooqN4xg/8EU0uV+hLVjD1c2OwszySs/eTQm6B2y7iLx/59fFoge8rQCX", + "uY37TUFQ38vTGIOoR+dItEeDLT5nAdrc/an+YvtqTFJ0xZu9nheTOkbtLjqgu4FsPnsPYhStbjFhv8BJ", + "ZOM899Ditr631TBJ4/tm8iYRJO85cekkRRH2Vc0Oda/Zquit4TQNZUCwpGsUSH+AQi1WzeooEde+3M8o", + "7yZgTS4OZQwOS1oHIcWkUammdxCTzW60wjVmKWyJY4/yskPdAWKNfstIULqSE9itXMGqvMfchptd3sBa", + "ekoGXLc0hlZoVSGCqeKxIUkTbBwhsYfbMTRPz0X0dMjOCZm179BRpAzUlluN/anETR+8KrmFEnPCbSO8", + "ZBE/5FVG9b3+AwQEGiZCVtZXh1f5WAVZfZmtRB+qq9wpPqhp5FOmfXXB7RwYNIj4HqC4PbdXAWe6XrX6", + "7iP5uXiHXSc/yDfqfBO3mhivUbLqxKBOxOJZqw+24G+koOi47F4aC+I1JohutroQXF6dfvfK6ND361a8", + "a41q0r7Dcr9ae4rkNpFtnVvSVe7EeVaQzH6iaMkf/2dYKQoHO8YoIPTTx08Xjgstql8r+RgnJrQMMLmn", + "4g1+SNi9dIKq3pzENv6le5ShGxTLC1rDJyiv002JY5+vmUjap67bSfCxyLSeeIJZX3bxIDuZgrWVDduR", + "uuwxX29w8YhoOziQ0uLl+tFdcwxV47SGhkyDLtDKLWSUfYuLBoh2+6lx9E83T2JnxiJDR/WtFr8q0hWH", + "ldUIp9jKQp30rtSlQme4ljF4OTTpqnx33pH0r7GlUvrT3XKlQuNejeb/5Kzoz8MdnhyLocOY4xg/FK5z", + "fXpI0zr+lxnc7DB45RaTEK5SQDerjO5i/7OeXQ+cahNm56iI/q6QOZe39wnnDAjEeJ6DLfbITR7e2YwS", + "bBud/cJ4UZLn5A3I4NDDUn3CHj8C161ByD0HebffntQW5fljhRd8PhMyfb3nzO7JjlC3Gd7a1CRJdIPq", + "0I4/XQ20asB5m/Y2bKC2/dimIdp3f3euXO00muoMPviU8Roeg5xTo/Ti6NteHdnaHev6zO3UM70EwbXN", + "fHHLdDKpFK6rDQSRbBvR01qzEcIpV2NvbrdZ6jaX+N5SCKzqhbWPmpAzLN/MI5KHlKmEIVnkuur2kUeu", + "XSI7uecBcHfFbEticguN85tKqwynSvskhPEK0FUKCcIR09Mt7ufBhSn1bw8MTFa/lamO/QPNaO9VMQSF", + "cOW1CrZMq9H4f2ydsscaQ9vZQFXR2qGyV98z/g0BfYMeygpQXel+6a/pNx+SqXjQLTMhJZjyzkourzX7", + "8slvzEsszEvMqN5EYKDfwaklQ7NQVL5rRBDfweS9PtHWPaGEmVJmF8jAZJNez0kz/zXnz5XFJPUn7Fl9", + "3TslH35JLa/YqKZiOp7MrGbDE2WydJuFVQtHv6CadK2ZKJUAdreISRlola9LOe/We/z/qQbyTZTjR5uN", + "7H/mx9lZmZHkYm1Jl7ZeOmfRNSjEeUJl7Tlvhdoo4b5+bKnSiFECnw9oVMTeO7XqHW8qB7QAkOKMgnhl", + "GD70Xf/LpW+oDrW5scAXqVgqnXJO9vS4OBT8dXkkhDD9gOIYJesLgm+RcxGoQxprG6sciHYMRLI70rco", + "0X/7vDk+tMeZPTgc6pJeLaf6ruzf+dpKofMY2ZSA9hGG++1gtFoTUO/oVTh0TO0e6tpXnuqaf1C0YO2/", + "GisMnNuEmz83UEMRGCHC7hg5QVUk+swGm/L1Nh6WCVuDBqtyDyzZrpr9TA05kNzhyrt0dFZxbMEahSs+", + "4M2qFs2hMMOAghGe4ePXfTQsO7GI1DfX605ygwGJULKWyWr6BlAqdo3xmnvBmREtI9LdWH3OIDkLwwFN", + "COqztp3EuUb3yrfaKcl7N36SxpgLqoCClbCPnbVnre1rr/0Bv4BtGsPVIFWtXh7e0bFZM6dbZ88X31//", + "drL4/vpPf//7M/7DfxrNNLvuqO3C9V4LgHHdMdYp6aJP1E1TpH52qoqew7d9oR9AAta8++rZxfthQ6dt", + "1FKvjql6GXQfoqvp5qwt3ZCznkXQKwmAwjUmlZScDIY5Eek0N8I8Y8JNQJKBULppmDondyIjiR3/G7qN", + "V1RDqqrGTox7vHD+md+z6rwKv7S+/1zC7fmEaoY5TLO1y/Qf09QPPk19z+ng7VtxWLv02hnou9W5lQ+7", + "pbd52ffWujG5ffPx5rEYEXBLRR2Ww/Fo1VupTwE+2b5H7XS5+vDpYjRTYYMzOoA+vffwoQ4mpwHlKSYK", + "eaE0Xn333Yvv+sYCZrw2deXggpFv2Hti4qzRgoOHPmnMU3G2TEkhuqLyds1UVHvT6zYxcMzS7PUgCLfs", + "HdwpL5JTb8a5U+JnR0JkzbQYniHZ6yqyTmTslieXpMb+L9klOPZ/pzfZsfsTQ/dvI6VxQF5ifx6inW/5", + "uc1NUHQ6KIV/UFfSli36ORvjMscHMqwApQTd5NS5q7tyGXU1HqiPgO/VcChbYbLu+WZlbnzvJ927tltP", + "yu24qGd5ljLtLka68rKMlSjGkHmnum6ur6E/5N8hGMMCB5OO6tfXPnitvwpn+d77oNM1Ae+ZVX2LYipv", + "Jnv5nq3GFXasuMik2XfNe08GcjLrjCvK3AtAhk3tHkfN2Rl07hpxv+4yjrpy7407VOHNZyDByW6L/sn/", + "zn+vatHsdcH+ae+N/mGKk8VAjBoHm1TuzCNjUv0+ucWjNIaxSc5x2AFhDND28NIPtijetUvkGt3DZDyB", + "nSpnpzng3SRtGp/bpMd79iFXvIfKOvyFycbuw7uzga2JxSDCel/iyjgGY2/iDYhjmKyh0wQx25kLVfDu", + "E6Ir2LVQjWm9AYpFtI0G5rtNiLdbRFtqqpRPu0sFd8uEVhcrAM1LdAoIpuX+Cm/OcrpJzhVdXKPekMAt", + "TnYDmtC4pLOL3NM9Z2HpuJaf7B1Gbmv7jjB3UxXpeCxiHWhjOxlLProcDiykt7wENIwX8WCVWhqDOuTk", + "LLxL8EMMIxEsdU+Ahtyp3h+TLB7tQOYNjBFTl+5zBeE2pasiWaJnJO+gGbMcs1HE2cGM99XBgx/Gimz7", + "rIjIFOJVaf73x/O6ulMUhC7bUrBfAnEjUFlwAxv3C7teMaHyOX3aS0Wcersc1WTXu5VW3yuHMtgkHlOt", + "99Dr/AQzOnDEoZRpJ6vDUVPsMehQ2w86op2XWXt30yh+Gr/911oGaI8/Ilv0mHFsgniIOddVRGtzr7VG", + "N13J2IWInPE4x9uEOp/r7f4Fi7LN/XsRoSIvdGi3jfFmW3UXZtbdQ5x/nFXbG/5DuZTCsTbWaBLnQ1iW", + "2VS+YyFA/s8Zk8Ae7NCpDlab4DY3qqwOuvxMPMWp8oES/LxnSFyNM9OJpZSEg0vkdCs+0FrFNZ/nq14x", + "lKS/jJcWnsnRLOJf75Rg//evnxaYLC7OPin/Fb8Ki2rEAsCG0lTLf5bFisavOXzmHOM7BEWl0uz1LBT/", + "VGbILP3+xaroqMs1W/klkKIib0ylS7didREDynby9y8W5dMLgWs1KfNqgwldMFMyCkSIYqEV9wS87id4", + "QHQTlF7v/7P85kq8E4AkCkAeIZiEMEgL6K/lap710+grP8WFa7SK4gVP7wj4p0BIg1tMAl6VFJTLDPRu", + "URkDF6MQynpZxJcjRunOzlIQbuDi9NlJSXftd0yMEWVCqhExOLt4r5lQr2cnz56LZ3EKE5Ci2evZi2cn", + "z17wmha64UK43EAQ080/2c9r4bNi+4xj+D6avZ79F//7rLyY89dOT05kjj5VPp7SEF/+LnMaSs9u1+4U", + "EGRrIE7hGmUJZkIWoCwATAQq+2n2+je238A6Y9vxapdRuBUJmUuMonD57AHG8eIuwQ/JkpEBRQvVKqro", + "7WJc90cUhW9QJrztPpf/8f2b8xKQYf0fU5i8fxOoHLmgMJfb6VDMrNAooSrnYOuSf4BrlDB0qg2NmLQQ", + "sIXCY/qbeTXlI8uPfIQU33H8YLV74VLWvH2+fO/wjuAJrxOyfemKR9usn6aA2j99jiNYRhIGvSUrxr5e", + "exS5Cn8V4U2i918Q8NFnTK1lTIOySx4RFRZMsbw4OW1qwsrXA7WIgJRwLMRWlGk3ZfQNDFEETULKjmWY", + "0R9w1DpStnwEQUn7ylfYx9XgiiMiPjATlGEDUIKSdUHbFcXBwwYmwX9fffyZKUy5YhiNxa2q2fIbj392", + "aR1UdBzhBWpGnpZdSRhfPxUtFYbwk7+tTcryyUlDSxUDGy/fnQd/fvXqVFopmVAoTqr794e77JnCrfW0", + "+u9ff7zyeVDx7xsWeMazcrhxpUYACPn7Fd4EP7Jbj9tqxQSbdnERQ7Wflqi83aZ0V3RHMRCRIxPI4T0B", + "JgGIeVvtACUy68mNiEXjEzMN334JNyBZj0VF/9usi3YcD7m9SPHcfPZSIGF6mAe2tIedaMsu9uoS0Lob", + "P6uHPFKmyABrtxrPcZLAkAYyIYtT5Xk7eyWiywuCb2K43UP7q3ZoCxkSy5bsCp3C5WMoUEI4UcMlUfS1", + "XVSv+GsqZtMwRvkVlV1nyouSCcBMv7eLm31r3glvIsU+K7pLlh8WqCyu0DrhFWlOH71u7DBbGfha9ToU", + "mUCepKoljm+QMV6kH2QUExhx/Z+Kq5owN+T2GyRomlzJ7itSrLhSbL+tXkIQoUS4JI7hwipGI3ydz747", + "eTEGMSoX3PvnS71UdPlYDYZ95Ve+JY9wLIumlW53OW1GNLvLXbeZ5W8ZED6vZjZYzHsO0AKA1XY4HQ1y", + "cTMrYrWmnZDkW0mPRQZuYVDk2QWgfM3ykHHhK0+A3XlmrMik9MlZCcFe03VvJG4yZGNTvIx5ZUsoDSiP", + "lJcQ9OfLoJsnXkiYGqCJD58SssLlEmZ5bDx+ymeLTSZcvEGm+Ysvfjx/u7jBOff96nfdEEfsnivy7va1", + "jMaUrdJ29yJYlzCCcDulWAmIhxOq3hvEWTnEVkiGHHTJLmIf3p1p2vxY5CXGa5x7PNB/4t8/F52v1VTP", + "BoteNu9X8pXSU3gPg0y8r663okhrn9VrMyj9LF8fW+nZF1hMx7SwKmT5YACq8rotPjGqjG1vgXf7oizS", + "8KN6yu+PbVscdv8z3jzAG/ZzstSqA/xwiUeGVKlEVVl64lsXRCtOPh/zPlwrETFsVfVQALIMEr4rJVe4", + "SYJT8I8cBqoCI9CCvT4Fw/fufYcSlG0mFYwqyHNJ0G9sd6sOMgwSpL4v7xcS2iUD5vMSbwD0JC7znAsT", + "XOlrbPe9eyvs8HrHN0E67rt+wYoMrZMFSvxz4Qqtk/eJZwZIIN+otuS8ytNpePU5nYBXn1MvvHpxOF7J", + "sFDW6sL/CWVUbyTr/QJWGcpnOA6ucp7keJvHQVzHrQghPrNOa9lLMAcQmj8MJ3ZYQh4h9OWkFAO0GAgF", + "89hPkxozPBt03LSakg0c4KUAMvX1rIGH0cHHiFHz/36+/EnkDPOUHH5NS3j1tTfmi57tE27Fv3KAf+zF", + "TnZMsRknZcTR70ZBjc7tOBd7cc635dXpd694HGdsWeCRlqUcH+Iz4iIA+Iqu8K/LRKxj3XuyS/sy3MDw", + "Dud0IYMCHr2W57xo7VwCLIMYbtDeR3CbYgqTcMdLW679cLGK7NTbtk4kc1aLqD9QHAxkUWAlnFPN1hku", + "FctH+ZNKDjPeFf4KaZO93i4LFkRSjwSitlYmxYpU6oCXNhhptee1oL/OQKJsf4dQjEkxoSCebLOqUVsc", + "6pPYsVVUJ962BuD1aGxG8RaSQPCxiMSOsHVDQEGM18yeinLZKtq4SUVl3Ll43Of+lBMPLO7xqY6S1R1e", + "oT/RFT6CMVyrP5b/4H8b7fowN2bPVqB1ZrhaFEj33lDeFNA8pzRpgI4t++RnnCykDQpuYhhIDvC5IzyR", + "lErTbixbjDdo8ajL+Y7PNkL58CRhZx1+KdkzkS43YDxxZIoDfZvcw5iXJ7ap8oDzjtsVlWlHAc7pDf4S", + "EBhiEmkRKld373z28vTUzT2sxPCtECtLIdQy3rp9waZENb9OYRNEW++wEdvaEVMcKqLufIRDpduqMiL1", + "AYQblMCZT+PINeXvuV8e9iSRSqOIby6eXR38I4d5zUoqeeYq5cvHSv+fr7KRFxRDwUw1bu05mn1ZeBei", + "V1dQQjQm3+kC2HbBskTi5KCsiyAFKPazucxmUrWX075m0r6yxDMGksiTSTjuWtu9ZGwJluJ26iHjnCNA", + "+5VE0XeEYNqiMNgp+v2wU9RRwfAm5QttLNtC+VIyn9nBIYjfljALt9WRXtU5vofyrdWJVfHMm9U2Z2qg", + "MVUV8lftrfLv1laXaCTYduy84b//sFNjgm2OGvlsIOcs8M1Q2STdSd/tB4/MJP8sJhN4LaI129sikT3P", + "ZJKmh3A+b8QTbprLl4ObaxQYf2M0J/lYbQ6TxSHeD2Sjtr1y/LdwCaKIwEwCbL0bfNidFc/5tEgEEMsr", + "gIZUi90/rgR1GP4FKl6tfAVjahNfB1vTSeJPRjfnPsK4fJQ/9tnvhSLVyN+3g97LTg+BhKE0qifRMZt6", + "5frGsPO6lJtv2RRQnGTTdLpJXki1JiLUOKVoizIq+r2FXEuHOz9StuRCISdHHz3DzcVUcgVu20FRHlC8", + "RSGI412QwZiPgg9AFmhdUfahuZoU5bGUTIFwM6suIMm4Yw8o+wpQEJSTrVztLGuKpGihmra2nrsKubOL", + "97zBj8+gTgWU5RFcw08/hgekv05+bFfR93p210BNHb+sQD8vTusGf3+Eu4p7TkxNKapxgyJvbwTJXz6K", + "8cEWDjoDo6z39dnF++AO7vrvRx6UvpyPPInXilGWV7iLNaFek/59+aDPjlwyUU2R2tq4L9Hzb90PJPDy", + "Uf7cK8afkxgld8Wi7ET4J5TcwShQMAICt/ie2UYbdgFMCcwguUfJOgBBzucFBTFeI1WmPKmga3SYVtrr", + "Gd+MzFMkfDPe/JFiWunoAKNApn8LS2rBeNFMPt37+DAmF0/Ad5FN+wfjTYxXmcZeOS9z5bqyFD/sZHbV", + "Vb7dAr8NpWuQOlybEnF2juGchDDgVMr8JCleO5JzkZazxXvJqryX/sla8ZO2e4wL2qbF8z5o2utjMdDH", + "l6vFRKABHpcuKhq9y455i1soWqctRF7YJJ3xzjko7/3xnJxdUxfV8/iooHlbKf0eOrjC0kma4gmeei2b", + "l/6iWuORAXtKJ764QGO6gUSlA4/mPBJcEEO55Yqn2F6/aADLTXZIadcx8ibtFTpP1whSPv2UJL8YE78v", + "3fWIe7cXoxKc9+nHuL2F3BVeAWhSwOpBcbLqS5nLXkXcyb6FZF0EOhIoc5ARu8YXA664CrnN45gdzPcw", + "AXX3Wy01wXt9SzHh6f2bv+V8joq1uQm/pFhoKCM33/I/d/juT8YWegHRmB6CCeX+FBUTgOrRg3qfUHKP", + "Udjv11OP+W0fymDYO/MkTi2uvOkvP810Lqle+6jbkmXkldotMK2p34ZzCzfGVSojsGT5KH/qK1JsXeoB", + "uGMcFvCQyJwzuSCh/tF2mwuFkyUgzTaYiopGUXQQbFBGMdkdVPHLRflg6DJkx1o8RtzdYRGtkUGOjIMg", + "dWSFKyaLBdbMomFZhbIh7QLEse+mtGdxbJdAEMfC1Bn7lrO9BXoH2g6l/OHd2QRdZAso1oq3xOt4Ylga", + "VZeP4ofeLCvEw0vFaqzE4sO7MxmJCiLx/rQhqWJpkwWkGGUJFAMGFyGOYLYkcA0TRkros+uFgnEpgZ8z", + "2D53QhWQaRgXTGMQqpRq8TBvBJ+Nm0vASE4xTT2Hfj59/HTxNiE4jrcw8eVaLCBNHe/58O5MW5zJbEnE", + "8OeAYadyQuQcmns+yY+ddvW2C3uwU1dMvhPzxtMTfXl5k0iRDmzqCuwP784k+JZKMi4/ip+R7NrhVzsc", + "qHn3JVyjjJLJWndX4B114+4yl1Jkmjm28B5LHKZt2T2BOOzdsHsaFWCSA3uNIKaujlRukGBaeNkXKYG3", + "kMCk37/2s/bahfaWR6qaQVpfQ1owbnP/3E/s+Gnjw/IxBBSuMdl99XT2q+93Hv0wybeMLpU+ELP5TKWj", + "zGeyNc9sPtsCcgepjJIz3ZDT9pwBM1u85g60gNwv6lOyTOUN/M9ANVAJCNwClGTBFiQRaLqx7h3dH5hp", + "74Uck923U+XUb/msz9nyGiDrXVnB7nj8A1UKLx9DPmHeLk+7uigrN8HHh6SYeq58nvcwWBMgqDJ90nax", + "4MkcB0Vjdd/9alXLc5FT4bmv+rlDl1qTE1V+ZoJ0ihTsbELNF+oxn2U4Aoa1ElE4HU1gLYVki2RvSd4h", + "wWMrQ/b5D7uLEqIviS4gcJBT29Q18O2DGssHgwiGSOwRHmEiOIYB/JLGIJF9nfZohbGFS71PZceOuYIa", + "XzxRR8Kw3jFXpfI4khO3tRdr32HrMi/wym42oJcTtVzWZEdqRjEBa7jEN7/DsFezX4mnP8qHfUqrDsle", + "Ziv4tUiufGhKwa0SefkofrAt2q+sykqI+ZtMig0Nw/Tlt+cH9MD0xGgTkz9nkASCYMEWUhABCvzwsz8w", + "LrAci/fLCD8kMQbRBCF9DfM2M+GNxGZ65ivIxrOat8YNMKkMUU4Jd4Q1qmVKWXDlT54yDLw3lC6I+5nD", + "89iH1FxPrh5BsKC+xMSn57sC6UyvdzJ3docZWicw4ukSC/zAf5RYjsnsymZUQ5aPYzOeS2ya8nJATcxR", + "MCcvD+BFflN8vNfuqDzrkwYaIHurQ8fuaC6YRXL0wrazLbsi8oSsJ9DX1oSr9662zqTvo/ev5YMe6VxA", + "saZtideBOwVrqHhtO1JCmTomXAVciwEW9Q2q1wh3UtANDEK9KhFkATskyT7OCj24lE2UY9piyCiBqOXJ", + "if7QC+F2XuAk3gUUbtOY2YE69kEEmZFIds9m83qSEkwi+R09wuNJtP7GLl8VOBMXQnIEoiYG9Xb/Gu3E", + "hZGb23ma8v5f0V5NitwiV6VXdCEiG31tn+TTfxUPT+Jc5LDsGz9VMByp89OYvaT7bFVZiVWu5CrnFuKn", + "XQr3+sDQSqr+d2pUv+Kzj2y6XOlvHfRqVsOFv+i58VVl7QbJfiOGRpU7VMQeyySTCSc7OJ5tDa2yhKr4", + "sKtKpqhQPON7epKqSQmqs16S4BiKHLAsxCnMnooqGaxCRlMd1wPF5ZH/17oH215q5P3tB95CQ+iNXk9v", + "y64swhdMNL7fXzTa9khztVOdwA46aso5DEpSpongiMFhixAnt2jdN/FMPOSz3CFPKNpCCchkHfGU+MUt", + "gTAg4uFA4J4XKbmtE8+mvcbznnGhfpdfPhY/d9ZXXok3q6NKqtdY3xf97sukGk5yJKeGYRPphJ5mI/Wy", + "eyn6DvRxvTYhqiC6fxOiBsrigpLZoHyEN5bjEBiHwLm2hOOOoLciehyh9L3i6G1rmySgbg98wniOhtRT", + "DbA/vej6ASXhYGH2iWPsTRL/EWy3CLZrEEeLuT+9gHuH8HwTkfcsV6pS/rSiuxR+Lf+pTVu3uOJIh8wP", + "RY3PAdvISlwaTTq5p0yL0QeZ+sYeBu2Yw/JNqaAac6yqrnIxlKswhLk8dH56MkvZRuKsOtk1xG6ypnYl", + "HNvoT9aF60iXqtGbG33bgsgwc73Af+bveB73N/iuzrE7vmky9txYPrL/uLvTDjWE8RJGQEx80u5OYiLj", + "UZDevNEkjafZZRbJTz2+sqNJhupxkB2db8yVQQaPdpsP5YyEG3TfyMeyqFqFkd6nVXzGfep3J+CJPOhn", + "ps6zwpmePVlnZ2/Hft8JeAKOYwKeQdTK+IapKb9jxsDgMEAtr/MY3f6xCUXfeZ7H4rbvYKzVhN+SbMc3", + "6LeJm+9k9Gn0U4err77kf7G5wqXOUz4P0DFp2HEwicVWcZw/bOSW9Rjih9bFmgYTPyEZP/Tk44k20TgD", + "kNtFfoRZPK4i77vn4lOTss62joN2fzu7e4Yvj8Z5h/FfBbLHNAWsSUGvI8AOf2Xp4sKRzxpr5ZVf5WZf", + "IFim1D6FEkETtt/ARce6ZK5ctle7WAMztWlsEo9uJVjKemWAN59gZcruGc1xoG2y5WP5D9seNm1MtZ2x", + "8GCigKnJzRPaCS0zlnXaHtqr0MH1JYEZTKInazqOS+f2rv2MSJbyfzrm4CYJhSNAXZSKbNebBQTTFgUz", + "n708/X6S2qd20dzC7U1XQLR24n+Qj0/hyxSw3M95ieMfzkzJ22p4tf2I2eJKaEeQ0fF+JkCq4fvf1pEy", + "VgC1pdGxnALS4MAljqEvb4yEaYQ4cd/Gutx1qlolZrwGkohFRF4V5AalXbvnJwjuoVtUVI2ULgE89W2z", + "r77i7SsWvHP4LSRPwCRqtVc+yTVom/kjWxwXowF5w8XL6sOzlq3YbUk0PlN0R/Wwcdy6OJQZGUffzqEV", + "1afX10Erjn4KbSCGtXRo49cfvR1aa0PH7vIwiX5xKtAfTSjcKvX7aTxVzX4HAQ5ZvN9LoGNRlQev+m/f", + "GS5VqcWyjrsmtQVN3xWpjmIxMuPcSlvNJJqksNUW9ITFUqUeOZKiVldTy7EGdpBQTVkdO3z9fcW0B5O+", + "g5XS9jN7rCJbVwVoaYn/UZFrX5FbtvAdqx7XWnwOVak7vq5Qhb2tEvhUynpzulnyQcIRWzlDCy5DEMc3", + "QA4PMmdfsef4sDH1qK0/+cvi4eFhcYvJdpGTGCYhjmBUXX1KGDCKBO3YA+y/vFTw9SyjBCVrtrEgIZgY", + "/5JRmTzX+Asvqmr+gVFI/AYXZK1v3RciDlhPI80oiGNR3v6AIhgo2gV0A9jlK8PxPcx4d129uuuW4G2Q", + "EkxFthkf3BZwvOUUTnFbkQOEQIDVEOiLGFBGve9fBPCLGM6lRQc7Ol0ZJnNVeb/GeF1jvtk+4881mP9N", + "kyoU98JuPdiVxKeprIkym/p6s+glRhoZBCIExz9AQNhm+e2aaUz5y3OM7xDkv/TZRM2K3EuQR4gu4JcU", + "E+q//QcD9pbD8jU7XIMwdcZTCfoShpgYLdC3SUh2KeWzgOFig3MScA4EggOV4oA9Bare3nmAPCwfxQ+9", + "G7PGV18b04bCb6CicIWwN/AWEz5ADskBrmOR10sEsKD7WG4rF+7HeN3TNY099hN7yje3BZ9te6QptGoe", + "qCPh9FBWLB/5z1ab8Ce8nognxqOR7zjC/170sjz2raaIO/VOEyOKZXPYvU/drrR7OdBYtZh1vIxrwLQP", + "WSXNs+eZFSitpUo/WW53Xvx4/rZip5aGqJ5WP5pp5cyi0rS3bSPJ1nxRvOR1L5aA3JtIVtAcV18ezJJt", + "3sJH2Vq50XUhRJk3JYOKkL5y+QtgGtOmTgVrwm5ei2AgRsAUO11m2BaX1M+X7wMCaU6SI9rZ8tLuX1bE", + "pf8PYVHuj6cpLY/qx+7wH8rATQxbNK5VAFB3NIDqSapQCCIBJjoqvW22s9Kq3He3KpNbcj4Tavx63vA2", + "uh0OsmhvGaEszWlPJ4k36iGPO0TCsDy4FUbjHtSjTz4cxovlo/yp74YjqTABW8zDuMgWxOifMAokvmO6", + "/zxX+ZYUnvaao3iNknuM+qYuvlcPeWSwhGG57xRG39S+U7zgVW/sp759J6kwAVt69p3E9wntu5LCh9l3", + "Kdh1N27lw/rUQz6zDAUM2+F8EqNvat8pXiwf5U99+05SYQK29Ow7ie+x7ru+BHWB/ciMWxJ4myeTZPNo", + "C+h/uGNqqykkd8lX4bUJgQQxcThOh1oV7Hd5HAeYBCkgFIE4EIwcM/TWaP/hKG/yprSA9726u2xvwl+R", + "rvJJ2tqUAC21uhHXb0vFVzm3fOT/leoijcHOU/2cAuOx1p9hb2KglSvjimLCMy2l24LjK2pEd0e15Zw2", + "25T7bNgWO9rd1X0o1Vbh9XSqw5r4mDKCr7L4h7LhlNg9pb/0mHZO6RjtLY0QTksTl3t75jQdnwNKskbc", + "Bm22e+/iTqYUIX26py5GCQxNsz2P3aCXK7CJfU+jSsywhvaaK4Rc71iDSVEtM2Zs3M/uXxIY4iREMRKp", + "qiRPJrkoaYIx+k1JUuqysrLL3GuvoyqwszCEqeC7YfyF/qSsGQt42wYQivrueHfEAsMz7XcTy0grx3/h", + "2Ox1QOl7t1JGcFj6t2zMPpO3IfVebd8GNDfrt4nsN3XJNLBw+Ujy3vR5ewXmkZMWuusW8b6I2ZxdEAEi", + "2VzMiZONJY7e5y9YcRh/v+aUbN3Sl/IZr2xnICx3rcTnG9ujfE3LR/FD39bUvLBeOdLj55ee0KcTXiuo", + "e5jdxlQSyigKMwu9e1U+PMEszhKYyaOA8yTi/L6HSQ7nkvFCz8boFoa7MIZBpn/k+EThHzkku1IWbgne", + "znS23zLBprPXM3ZZ4tVss2YaUcvHKHb/1EAZ0safduvtq8qTPqtjNUCWOryC2zelySv84ZNRi3/2aXWd", + "KFPxq2X6bjlh92nGcPUleOPlMgRJCOMJLqH15YzprOBraIieB/d5E9BQh1dFQAUTRI1zwIBFeQyjABNR", + "KHIUt+heQeKF0ouUoBA+cXHiK6mcCAR5mzjYBm3i9HUnhcqZHAiOiwT2bJeEG4ITZlM/AWElMMu3T1xM", + "L/kaug9ck+Ip1EtF6+gtfw/DO1EZ0W0PnstnPG4E3idCwLE0BCVSx1pR1u3iF8h7DTdLEBNHmTU+mnh4", + "LutwtKkrGY8YFuU3AU5CGDxsYKLKNW/kmKrD1OTI/bF8FD9YRpw1/vY2AhckYaSQQw5FzxTR1dRb3U3b", + "VaIN85OJRWS8om7P1UaFXHR6hhpX+J5oslcFUQEx1JSWfDp89bRhhy7F1JWF0C2eUuGGM95sWHCUBVVF", + "FoXXmzyHcK73VzJES/hkBZ6QLQsoTcr6gKxnWnhtMbTujfacz5quAoxttV2J17h2jNYTy68hU67AqzGj", + "gZnYoKlDrvFT6+5ZdDIrpdKmk9me7B26X5aP5T96yyGrTPa+e8zdlgqiSseiIYYAj2vvtFRI6nSfNpzU", + "wf+l6Dzv6awcd83td3O2hC5pbel+vS4bxUhMIbuY8L7zWWVC4qE2Lt4ClFi3hnkjH5+md6GA5t4ZRmL5", + "NG/wjXV4Pf+a0A43ZVVHoLaV+F8CEEXybv/m56sgJRjfHo/FKGRu+Sh+sOutb+Z1r2IR1BjRxef5JluQ", + "ZOJDqcmSEZM0va6zO6tzoNj8fBVgNalr1ITOgVuGn1gx7K/ufqs/6PHo0eC4DO7S0Ru5b6O+cN8HjwbM", + "65Gjw5n4sKkz2NzftnimPp5qdIYO3i7LR+1ffbesOmMn2j1WxJ0H8PYWCvc0v2iJDC6QpjCJFjiJd4FI", + "/s+Obz+1FLJWGDPtidcpIksQ/Z5nvpyWIy+7TVWd8TX4V1VNOEPd2WeaKIvezYFgxFYUEIeYREeuXJYE", + "ZhQT+LRF51IsYgLZES2GQbZHPpEuNYL6Kq7/NOTFo8tnMnFha3iK0nKPwyMTlnuY0AXdpT3d03g3hk/8", + "MZ92ioJia94XWB1pU/Yes16h79eoL6BMbdIrwG/gLUqQzcgT0bqDiWNA4BplFJLDVOEPm2+h7SbVnYX9", + "o8/jdEbCDbqviYNLA1eNbEB8Kxp5G7ReYNpxPplakH6BJEM4gZGkB18bCKkaO6TGmQUP8GaD8V0AvwD2", + "mycwsEMXpTGO1a40FN9aqQ5l6Mn6thT6qJCLMjflSekMi8PX/8Hrcuh+E1NQGn20Ol01976dNAzA2+Qe", + "xjiF5iw5nEeCUgv2PqDoJoZS2T2VgSijNRNz4vQtBDQnPTbuO/WQRyZLGJZbTWE0crgUUBBj/422JPZe", + "jVsFY2LTtgK21gBS/Kl0Tc9nL09PJz2ISgY7bRKUUEgSEE81Oei9hKe9NnyQUPvHrIwJ9XplXlCKYxTu", + "lEkhUkVkanalA0uRLDKfvXw+MauHxfdQco+oRRKlztHyFQV0mlSTErB7ukkT6SefeVIuSWeDL/1aQjtg", + "9kkdifaLMCbl8OygFPJK8QncAhTLHlbHsQV5r3z5jz5fgfB99spDbycpyNvg6DQaMeXNpujEbQkn08tV", + "+denU5hSkaNpTewOeWZHH0wiT0GHcdfcEaKCSeQmtKdjTrCQwDgetEdeK8YJrzERqi/GoWzGU1WCzET9", + "/inYLXwBCy3MtJBHX7cZ8xN7TQuTXKqXPOqZFpiWNkwbxkedxDQSK5eP8qc+l0wLkQ7AVRNH+aOBXIrw", + "QaPtNqfs/hBkCUizDaZZUQSKk2CDMopHGiA9djpNzwuSDt7EgH2F4PspGgnoS2nNdRHYdAngEYSj/Ym9", + "WH9bCaGQeMmxKIBfQEjj3Whp4PvEu23FjcDfYUiPRNouOTJHLmyGS4aSBEHMwyc72DMfpzA5GuYzZJ4i", + "8wXT2Z1c9D/hPQGVRLBFwSi4xYRdPBF8OLRwJJiiW/mLhd3Ejp+1VyYZ22ECaGlQGnF9klkzppUM8Rhf", + "ffh0UXbT9+jJMiJs4tiHTxflAAWeERkdLi5t3g/OczhaudWnP/QX/YwktkhvscP+ZHJRuYQR4Mq1Mbal", + "rGrdQBDTzfFHhDWB8p3aYqc6RsxyqeqYaW12Z1lScS6zTB23JlpS6K1+YkQBHbEp3SeY0QnluRWclVSf", + "epHqv6kYTkOmFXaLLIUhez5g8hHokjRiBMijWHstih1Z83aUxQ62ArhNpGZJ3SO6E/6ynG7YNU5ysiyY", + "nc++Ozl9Akl/Fd5TuE1jQOHiHhDErBv7W8cn+eovxZseD5QmMFP39xzFdIGS6l5TSwyKJYo+gDz/NrgH", + "cQ6zp5tHaOSmOxMnuzoqgAOujgWuT/7qqFbiNX3CCHDiRIp2HGrxwyI4ERFwS7U9K/LqRy22Hk9rZstH", + "9WNfvKiV/RPuORPlP9UpzXRjGStSvx0zPOT1RqfxY8obnecd3QHwSHf0z/BBEyOxq5/UZl7KaiZP9u/I", + "cmqOFIoV2KkegwHc1A0+CrzG51wqvfpPl3MXYgUTapguiAd0HhXmYhGoaVqM4BbyAuckgmIWO3+UZz3g", + "nAYRjNE9HPns8iC0+U2Mss1TFlqxgvHUjSSJTCBLCYwguxtgcmSKyP66NV2Ezv169U2U1VXYYjnGTifC", + "NLPsWiAaZxhqngzufqJsK1M5NDSgmII4+1b49aj/0+VGNRWzelmkJpnPGaNAuOHdfLRflhzMigMKJiHZ", + "pTz6AXYxBtHx37JqfJo227tHZpYEUuLLbT32wtszbyjZdUt4X9xaTkoXWS70kPYPBjndLEKGe1+5uRjW", + "oZ70PhVEALI8LCu4HW3//D04s3zMMxn7qQy38Nm2SUIcIbg5eGTG/u2gdMmwG8IjntWn8Mj5O0fQ/DuF", + "ZIt4L/KFQKp7WJf45kXx0l/FOx73bg2W7QAvM6JHWpTZH63/yNcJtAVd5Te/w1B2NtnjA3bwf1XFju/f", + "/I3PGLZ4p0b8Kzn5vm96mZFzM1cKX0oNYEhzcE7gq+HCX/Tpdq2v3dQNHREY0qDcvfU+tQdoBjCs0qqh", + "gJZFN9iuC4GE9lY9e8a3v9e2KTVQpta2RR9bgovQc4jTcWLOE6qbwWpmNPVyvacQPfL/2hU5j6Ry3t9+", + "4BEkoWN6W7G37GC9x8PJoWol5337rkmrqQwAB234BOqolZROe6lOCY7ysMfWu1AP+eStgGFp1CmMnmaX", + "Iom91zQQBWPiOHEFbCNBkv1pzDDwwK5DSuh54iP7qc/nqDPMr/x3EU4OJDsqSW/N8pRk9Z2M4XcrVWEM", + "LUtT/BtzhumIgr/kA9/7TgD+iFf5RyG01v4MmyPV/VPsiM6zBYXQ88mCQjj9uVIAbUsh5GJ8DKdLfhOj", + "cKqOdjz6Ho7Sz67tU3atcb+w1xCNdyJ+HwYkT/ic0mqZGBHTfp9S5zp2g1+ALEPrpH861SWO4Zn2rEeV", + "WQVlqTtr+D3N3nTVRQyR9doXfKquKqhLPoXBxKjPGSQBJsEWhBuUwIWchc2kLyilb1QFN85+WD6W/7Cb", + "dGjgX29tf40MAsBTmHdYIc60t3vue+xVV96VlINqesIKyavRxQFMbHOVMA1b8emFF/hmWD6y/9hrKSvd", + "9DkRexxGQZhnFG+F0i5U1HH6b83LO5lGfApfBqPNy4PRxoO6l/Ll2/EhubdPXMKXv8ReV7Wd84MnajwZ", + "ZZTxtPUFErkaqOeUvuJPvy8f9rhtK7B2lkd3HcEnWapZXbnX47wGauKD3QS9xl7+RCDFc3f40q3Gflk+", + "il+J2d7wFuSxr2YcBSBvrrsrSN+IJRhksDd8LN4MBJpBBuPxOt8N45VV+r1G+mmy780Ae7q7qx0wD0Lh", + "DZwHNyiOUbIWWd2qyigIcc5IdVR3FkeuYQLWcIl5soZV8l+Fovztj/Jln+eTDsktB7AV33GPK/ntAzNw", + "+Sh+sLvr9FDI2dJ8h0kIxadts2DYw+M2ydEZ0ZPF0rHwaSS5d8wEf6qoKTkqObXIOS0ywEaT6WWEHxJe", + "NuO/aaqGftsR/kZic3h5UpgYUwlEaAaTINtgQhfs8IqClKB7QGHw+fKnceVqEK/tGqE2CTxJO9QaLPfx", + "QHVkj/XosR4OVFvQoLao1U94z6quo9yjeqVgBvgeEoIiOGKf1LG2inOP1E4GukkOjxKT7RnPeIaRMgHt", + "Tv2LepfVACXBRQzoLSbb718cwndqYzX0yP80ysd8cQ8JpItbAmEht2n5/FOyGdQybbIgXPTRmL1WTQyZ", + "rmOGjTzUZKAyWXALyB2Mgjwpuxkeq0pbwoSphwlsvbrYGU/Bt0mvEp2K66qYqr0jaUDgQpDvmBk8XtvR", + "MRgseoi6MNhU7qnNxGL77SYP7yAN7lGGblCM6C44oo2Xp+zSkI2SsNZf1Nek7GcO/6DVfVVMJrBABaSz", + "nG4wQf9sbTVxQaAML+ujYkGWQRrk6VitI8aRn8oVna1cmaGHv6KfS2z6RfBwLh+BwjHohTzru4J/zjxf", + "thkAyxs2x+VomzN0q0SGu9doIwcwcYyxhGnIchwxnDi02wEX77LzRVekquCPRzFvJdWIRT/jCbTXnh59", + "dz2P20UDMDR/hTNtxEqfkeR7CaKIwCyD/Sr9rHjSZzBWAHHQ7gVax6rl/W6KvZhPIHdZHncvn645yAx7", + "j/t+jOFzV3mWwiSCUcDoEUiSR0W7N/ELlKwDHEdBBnl1enZMKqLAqU9DXKkHvaahcRgOCkJh9Yd+GMz5", + "J9Hzq6cp11QCKqBFEtQ5zs0NKc7iWLX64nohK6X04B2/GmIgVNgTZb9UwEd+THD7MCvOiqPsBFeXCxkg", + "2C34CP8nKh6f5SIYA97ydRy5kHBiS09QqIpnt/j+SGUDkzVIlBPz6YvIR305Ry4pOumPXmC+AVXyy1NU", + "JCDaogRllK3jHsbjxp5GFo5vQJf88vQ1yVFKzAO82WB8t5CJ932VU7+Kx9+UT3u8ElSB2dZONVD8FgYy", + "NNm0fFS1En3+9hoZJ+SYiVvykbLSQ85Ek575Q1Sw+m3yr7FpWq9En8wsee8YXy3+x1x2u4eCLaBXvs3V", + "EUL6Ku39OTkOVucl+WWlgKfQu2769mnWqErkvYaLFYyJI8YVsGYdLOPGopsyz3QNCKQ5SWAU4IQ3CDvw", + "Xlg+yp8s87B1fvbpgOIkkqnSI4ttz3E8wQbuYj1MohQjOTuhOIu1UtNv7hwuBcl3RN2vUqnCGHo9acjB", + "4B4RR6UilgRTQOFCaDNPps24kmS2bPgyJJNEEYLf6CCDUObXdmkOdVBwDMXZccyHxpLC7PgFoT8h05CQ", + "axadTzBrP2NOxz5jGLSzMISpyM9pDsYGZA2ZnMiMW8aN8rxRtckHPGvcJExNU+gx0svHfJ7yCoqtoV5g", + "9TSbwhX4+7XWCyhT2+tVwDXlq/54BP0qy02wfCx+tmuLUGVhr41SLJpAypggqqzg9gaSbIPSrIzHHLbt", + "Waup377ck6nlZsxu9347vuky5d1U96xT6lAGm+sFH8fsej/y/l/KrWl3Nn6QD0+xNQQs13NSYni8o+18", + "b55xxaJaHWB5UAgeOB4X5RExZsT+CXHOe4w2b/PGh3XWlR2Rx9euXRAnrh2vC2znWSzkU46yUx38A0Dx", + "FoUgjndHqdzxQwLJghKQZLcMh8encPa3hI1CfA9JwY+PbGVMWwxptlK8/ElRpkXMui3TxmcuYZbH1K8k", + "5HSz5Nksy4wCIrwk5lxQ9mf5nSJP5ye8Rr4yMNQQSgaHA7fbz+O5N843II5hsoZdzo23Sb6VZFpk4BYW", + "nVZEbnKovhGA8iMVdtolcJRs0or6O7JkpmQUByDATq1yP+E7mFzKrxvrvKvc4JtDJYy33aPtOaL3TlVt", + "LfuMm89JjJI7JdxfKCQJiJ26k6qXSlErmsrm/OOHceF3lXUY1LxGr9GNVMabGK9x3qHPfuJ/1/aJFe2r", + "8qQEaZoE83JVCxDHfSs7i2Ntce3lG4ZFnsVxYFxoNuFKtzYTinkVY8gbxfq8RBqgGXTNeU4ITGiNdCnB", + "tyiGIsCO1skCJcEW0g2OfFQgd/g5Wkjmy+HRRrMh0/6MBJ2mIliIomBXvzye5XTzQT7tXx51aKY6qXuA", + "Yj7HrbaZu6XQni4pyLIHTKJOVYQSTRJ+RXRzod7yajaKRhcCkjB+nqZpws7x54PP8VZFYbq8n29AsoYG", + "+k3HKYHCcEUhPyPbSXKdi+kGkt7j7KDmknFvNXt6fV0y485w6zYPx9R79ZlNK5jkW4bKGuM1H33CeAln", + "DMldytv0U4KSddc9+icXW3a8QJmCxTSgdje0tpMZIQN+4Z3kADEys7xvHw039Tu+ol55czwuXqpTrIWL", + "9syxqtG3MqUPVapvQM5bxX4XBZeP8qe+O7Ao9G6ifXRXMJuLbLlmL/dYyuyIJYG3BGabdkvrUjxgQ9OD", + "2TiacSOTzFQKmV8hRUlGQRyLFTKiLlIco3BnadBfiIenseclsC5ashWwpcqC1FS9Mf1dskYdz1fJOnn2", + "uUkaaXjIBFgH6bVs5/9ee4+Tbopm/jogy9OrFU9fQXd7+mrmmkXhQdtCrE41/eWGdNY7unsOZU9jgXbp", + "l05S+lIzrUCHahsrnmaQUpSss6ryOeD8TqNrQA6cn5oxBVx3fvjRaSZ9ZsVmNbLfc9pWRZnJsWoDzosf", + "xJuTHBk1WANOjTq24x4c8utic3TkJndg5DVbuQ5r4pxlI/iODSKF0tfOKLnltDOcp730cdvpbGjQZMyD", + "XpffttuO02pOppQdffoK6qLZ6FvdKbPJZbLK9IpCwB2kKJxFd8Sw3Ch7efAUDIehFn6VQajNvBizX4wd", + "eVFyj6hIFbQ2HzQv1Hvt9Wki9CXEAaaEGXOP6d+WBoURL69mhRnixMZFBxJdjsZSZiv9DXS/49jlqnYW", + "ubaZlo/lP+z85Xby4OY+1yg1ogfdzbdQocPYPnRb8rOLtblRq3eMO5p0wyQ6lBaouF5LaCLfhG3Br1Or", + "c6d9P2JgwW5rb0EC1nALE7oAKeoKLXwonjy7eC9njXmkpQmcgZLlY8HZxfuqrZ2pt/amZQmlP8jQRidf", + "sl6BN7WTaRiXBGPGtLkrDLKU9zBGvJK+yzwsv3sun56EmAKYpSHYwHFcu68u+x2mXx0Tr5ZeA9jERp4Z", + "fqvcC2mzaFw1fRBvj82zfCx/txK/s/REGWWlzwps0rOYFsz7p8dxgG8DRLOA5x9k7GgFMfKjZmyMRBN1", + "vNqK1izq7Tc01Wq6GwnVxeQ4Ogo15XCK3kLW+zTBtOj8vXAPo/ysvT5JLMUEcIAXxIj3yGP1Ic1TJxeI", + "CalBo/E/fLoofaAezzUjwn3hEYadFhwebyy+pLe7tO8VGmllmpNLVEfMFCSZPmJeiq9NSMWOCieHlTwz", + "kbeQgghQcFgi2yeoTNAwxl0pjTkfv6K9pr2jjihWB0x2GUsTtnUV9CucI3cJPJAsM9Dt0jRdib+Ow99k", + "I0KbA5q3MDxc58LRRLg1Nupfw1qGUwcbEJxPIU4SGFJ0j+iuFgLSY6nz2XdCqI6XgxRu05hdM+8BQczs", + "GXYL+SQ/80vxFZ/lAQ1gfZtLrTIoVin8O2Cbite9Nf3sp/x+BJ/s2qcA7nntK/D219N/wL1PYeXVH2oE", + "OLFPtB0Hm90TEXBLx2wTuseuWT6qH/uG1FgxfcIdZE9vpqPQdptTXm0vp9n4bYdvOKA1Oh/qCuR5fwrg", + "T2l//gwfqqHU2h69h6SrFdFB9+oSkHCD7qGdeTiy9BkPhzOBkLui6HMwlTtZQDgyRqQE3iP4cDyMuBAI", + "HUgNSOjD9YBny0tyy2R8gVsY7wICkwgSGLWohrT4wDHJYH4TI1mBfBwyKBDyqAzkkifUBvqwyGz5qP9T", + "MKGoW3bLZdYHZqp8ZlOdlzhg9aeL8l43gO9vP3D7gUHyZwkYEB0jqX2BH3i0UZ/caagQfn56nMkFGVon", + "KFkv7uCu+856JR78kT3nMw5cgLG8k2p4HaIGWKefDO539F3gfy8x9tkpRYNiY2rKdQR3cCcG4k+bEMku", + "QWANl/jmdxhSe+/JlXjvo3zNp2DqkAb4S6qYjhwfF992o/HyUfxg12C9dSnO2v4dJiEUH5Ua32L4JuRC", + "qpzoY1LMLihbX/I0YtZfQJxlkGph13EJ42g2cJRNo4ptpXAZ4YckxiAaYLOUwNtMwDfy44dkq8LBmJ3O", + "DMgwwCTINpjQRcyulkFKuCoOPl/+NL2mcE9ikt+fJH+pBmu4TvaVtaRvJUv/dQ2jQSlL1U/wF316t+oo", + "m1ggHqmnKgUPiG5wTgP4JcUZsz60iNsBpX2vJKYmB900Ge9iQbZnt7cwpDBSlo3dSXlRT3cKUFJ0wfv+", + "xSHSnAeetFNkPtlIrlZRntWk+LDH7dAi8l4NM2b+kYnA0/nbhmgmeWcXk+MAuYNRkCdjFlKPopOWMGHb", + "21Od+tukX6lNxbT26qZC1xG4EOQ4Iv5M3Eeglz+Gs+Jcy25h0n6Th3eQBvcoQzcoRnR32JwXJzbkKbOq", + "s3bPS6ul9Zm/6XxKX0olZsifG2qwSUwmMNUEpLOcbjCRLkvzBoNyCC9q3jlzie2BOF25NrKVKvts9Gvj", + "ufx4l+wczhsgUAimP6DyzOVaqJVoT9XZY79+HgfxJXOaLh/l31b20w9bFuEezSI4hmoEoiyWHH+Wi1vD", + "hxo1pkxWqZNyfDP5QzF48hLHcJwmS5yHU0x91RtkiIFl7eevmIo2ZUuKLojHNt2jRK2Y/MZ3n3HqB8qy", + "fNRhH1YMfopTCUqyNucTeJtQonWUKq8wZPI6eatBCQrDxQ0I77idV5NDkITQYmhCqwRVUhQ6rYWPlSed", + "MwiSMM4jeCnGvpucZePt5koeQYuRccZtDHQTw0pigLho0Q0MQjn+C9U195Q9w/SVDPE0/wy20O+FpYKh", + "gc7636tjkL4/UE/krg3QzNHp7uPFhLnBoz5boEIS3p4hpOgeBuwpmERAdCqR+2RcWWtz73av4eQw0hJB", + "CtA4YYbhg75NqVZd1um+O/YS8uP4q7MgEf7iQVKZhu6tyuDqzrPnTH/wmI8eDVHL662+NI+NKfcW+o5T", + "SlvCcR5SOoImW6D885iZ+6Nsi+o8dwIznJMQ2p1Mdb70DorV6CAPIH4+xex00kstp3E1OAqpefx8C/V8", + "Oyn23BIup0CVa0/7EGiXdoY0xQTunyw9uZy0dQNly9lvi9aSNMQvULJWG3TsbI3hPM4jRBcxXttfMc/Y", + "Kz+xN7zOAokQvYQhJpHlcW1E0V9R7X7HtjOXrKdRVclwvNOoWvE8WlNrL565TbhqI86AW+xhJ1yNcgJM", + "PBOrk/iO5kKRk5BsIEHcJzjgBtnGRFR+9WlMtbIn7b/OVCsrTk801apPp7kNutJXdvyDrrqw9Tjoyuf1", + "v2NJ/+KTsiqb7lCTspx3m3NydZ8AOJ1CBx+e5bSagw3Pwl00Oy71MR81U3p6bTPuuK1uYZ9i3NaeCmFw", + "5uz+ctGRa+tXB00+s6uPR7ZjvCo0P/7ZXS3oPtG4iHk1f4z5MmVVicLhw831cthw7qO+OgSht14MJhFT", + "RZNP9hrFp+J1FtgeLGsfD3aEy+4eKGYrWycH3d76ntZGQUQwRveQ7EbsGzB4h29Fpq/1cSozg6dKlxHg", + "BpyjEs9vxeEt2bR8FD/Ypd836eFuFAp4Kvf+KWjfgkK+o90t5D3abPxq4tRU2fh9kj1gOo2+kKc0naYX", + "72ONqNob/N/sfJvK5vE136atvd6wPbSXR3Nwy/oOQo3p09SE28aleazDay5hBEJa79NXIdtRqYL5oefW", + "uCubf7G5NR37b8Tj3qemaptJc2yiOvIUmwNJ9tOaYtOU7soUmyMX7BFjCAedbePbUBgz2DCUoWWXYhv7", + "ougwPE15n9YmuIOost0v9y7Lur48E1cVz7NvPXtDRsuK7ktU3q/KTaUq/89akdsWoMRPrZsjHV262+or", + "O+7utu2YeuyjOKn879Uxt5U8327H3K4lH65HTkVXCA4eS8tc55yF9ia7e8jyPn1391lBX6feQ4rT8Xbq", + "tWW0u4/3+Jv3dmF7tIeOvVf32+z+W9G/qokqvoeEoAiOObV8tB2zl0f3jwbAoxgOfzQAPppE2D9aBh9p", + "y+A9FdvgLsKecm1F3+Hj0AXH03d4XyYffUK17+bFHnizLbxyli3OSjfet9fsTLPRt+3L7DLPy9c0pnQ4", + "QY2CVT70TXY343s6QzjRWjKAWofIbZHAtCeNe8TcrZFZ+eUxWpq1+nMdhahnmz65tmWue8hTn7ISjLFj", + "2WiDIafodTbtFrLrV1Y9SL7RzmXb1kWOeYr48erUj6FvqX2Zdgbt70mYcDcNa3NWP7dGaHh2YKE9kiZm", + "9TOiStgjPSKMjdCOUqa/tWZm+j4cra3Z5LzryXNptTyPPeOlJdNl8sM4p27G6L/KrPKPXYPJJ94D/vOJ", + "GrpinMyicSiVQZqnyxuMaUYJSNunZfxQPOJHyIrvX4qPT13CfcUIcSVGy5iDLjRPFziJdzUHR6beGW34", + "BQdVZ1FloFTnVCjxuq/OXzqMr5JHvtzfDIiE2MWVQNFmwA1gPnt5OvEUORN32yvhuuL0/FPfbNlVZYKQ", + "r7IrIzcyEWhps4uEqhDP+Bb/9piPEP3mSJ4Yr1ESgHuAYiDiDraqBhKuyNqW/Yv8u8clSxDvk1tsWvIP", + "OYqjACVssco50LqyXUbhli2tLiQ3XDrOcrpRwpBBcq9O/ZzEs9ez5UwTEkNCQwizLNhAENONjPXUMHtW", + "3k0kJkwUa8d6AhcUbWF14kpxFuufEOq28YUK57N5dbDLXIza0O5n2hdV3nDzmx9AuEEJFEddBbPC1YKS", + "Nf92pXBtje8hSUASQg2MZnI0IWl3oAUX3VqXRgYiJfgWxVBH/T2PsjGxbnzxHQQ0JzCbs/eiPKSSCGi7", + "zSm4iWGQEhRWvnYOKIjx2vCxvxKes837weMQxAEHG/PVBFJ36l96W/45M/FK64KXwLCcvaN6L8XoFoa7", + "MNbpp9olGYSH/wDigMIEJHQBHgCBwdWLBdtWgIo5PyKxVEZjdXmSwcPmZ99gnqEOeeXEPMA5XWOG3AO8", + "2WB8p4QqjxDVly4KLb5ef/3/AwAA//8=", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/internal/httpapi/admin_assets_test.go b/internal/httpapi/admin_assets_test.go index 831524f..16960ed 100644 --- a/internal/httpapi/admin_assets_test.go +++ b/internal/httpapi/admin_assets_test.go @@ -3,11 +3,14 @@ package httpapi import ( "crypto/sha256" "encoding/base64" + "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" + + "github.com/supaapps/platform93/internal/platform" ) func TestAdminHTMLCSPAllowsOnlyExportedInlineScripts(t *testing.T) { @@ -26,3 +29,13 @@ func TestAdminHTMLCSPAllowsOnlyExportedInlineScripts(t *testing.T) { t.Fatalf("unexpected admin CSP: status=%d policy=%q", response.Code, policy) } } + +func TestSecurityHeadersProtectHTTPSControlResponses(t *testing.T) { + server := &Server{app: &platform.App{PublicURL: "https://platform93.example"}} + response := httptest.NewRecorder() + request := httptest.NewRequest(http.MethodGet, "/v1/control/organizations", nil) + server.securityHeaders(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNoContent) })).ServeHTTP(response, request) + if response.Header().Get("Strict-Transport-Security") != "max-age=31536000" || response.Header().Get("X-Frame-Options") != "DENY" || response.Header().Get("Cache-Control") != "no-store" { + t.Fatalf("control response is missing hardened headers: %v", response.Header()) + } +} diff --git a/internal/httpapi/apple_auth.go b/internal/httpapi/apple_auth.go index bb4407b..04b0b72 100644 --- a/internal/httpapi/apple_auth.go +++ b/internal/httpapi/apple_auth.go @@ -49,9 +49,14 @@ func (s *Server) startAppleAuthFlow(w http.ResponseWriter, r *http.Request, forc kernel.WriteProblem(w, r, http.StatusUnauthorized, "authenticated_link_required", "Linking Apple requires a directly authenticated user session.") return } + if err := validateRedirectURI(request.RedirectURI, true); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "redirect_uri_not_allowed", "The redirect URI is invalid or unsafe.") + return + } applicationID := chi.URLParam(r, "application_id") var redirectAllowed bool - _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM clients WHERE application_id=$1 AND disabled_at IS NULL AND $2=ANY(redirect_uris))`, applicationID, request.RedirectURI).Scan(&redirectAllowed) + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM clients WHERE application_id=$1 AND disabled_at IS NULL +AND $2=ANY(redirect_uris) AND (NOT $3 OR client_type='public'))`, applicationID, request.RedirectURI, isNativeRedirectURI(request.RedirectURI)).Scan(&redirectAllowed) if !redirectAllowed { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "redirect_uri_not_allowed", "The redirect URI must exactly match an enabled client redirect URI.") return @@ -81,7 +86,7 @@ VALUES($1,$2,'apple',$3,$4,$5,$6,$7,$8,$9)`, challengeID, applicationID, request } query := url.Values{ "client_id": {provider.ClientID}, - "redirect_uri": {s.externalAuthCallbackURI(applicationID, "apple")}, + "redirect_uri": {s.externalAuthCallbackURI("apple")}, "response_type": {"code"}, "response_mode": {"form_post"}, "scope": {"name email"}, @@ -120,7 +125,7 @@ AND (locked_until IS NULL OR locked_until 32 { + return false + } + seen := map[string]bool{} + for _, value := range values { + if value == "" || len(value) > 64 || seen[value] { + return false + } + for _, character := range value { + if character != '_' && character != '-' && character != '.' && (character < 'a' || character > 'z') && (character < 'A' || character > 'Z') && (character < '0' || character > '9') { + return false + } + } + seen[value] = true + } + return true +} + func (s *Server) internalApplicationConfig(r *http.Request) (applicationInternalConfig, error) { return loadApplicationInternalConfig(r.Context(), s.app.DB, chi.URLParam(r, "application_id")) } @@ -186,3 +220,27 @@ func (s *Server) delegationEnabled(r *http.Request) bool { config, err := s.internalApplicationConfig(r) return err == nil && config.DelegationEnabled && s.organizationSettingEnabled(r.Context(), chi.URLParam(r, "application_id"), settingDelegation) } + +func (s *Server) customClaimsForUser(ctx context.Context, applicationID, userID string) (map[string]any, error) { + var configRaw, attributesRaw []byte + if err := s.app.DB.QueryRow(ctx, `SELECT a.internal_config,u.custom_attributes FROM applications a JOIN users u ON u.application_id=a.id +WHERE a.id=$1 AND u.id=$2 AND a.deleted_at IS NULL AND u.status='active'`, applicationID, userID).Scan(&configRaw, &attributesRaw); err != nil { + return nil, err + } + config := defaultApplicationInternalConfig() + attributes := map[string]any{} + if json.Unmarshal(configRaw, &config) != nil || json.Unmarshal(attributesRaw, &attributes) != nil { + return nil, fmt.Errorf("stored application token claim configuration is invalid") + } + claims := map[string]any{} + for _, key := range config.CustomTokenClaimKeys { + if value, exists := attributes[key]; exists { + claims[key] = value + } + } + encoded, err := json.Marshal(claims) + if err != nil || len(encoded) > 4096 { + return nil, fmt.Errorf("custom token claims exceed 4096 bytes") + } + return claims, nil +} diff --git a/internal/httpapi/application_config_test.go b/internal/httpapi/application_config_test.go index 138dead..eb995a4 100644 --- a/internal/httpapi/application_config_test.go +++ b/internal/httpapi/application_config_test.go @@ -29,19 +29,19 @@ func TestApplicationConfigurationExposureAndEnforcement(t *testing.T) { defer db.Close() vault, _ := secure.NewVault(make([]byte, 32)) server := &Server{app: platform.New(db, vault, "https://platform93.test")} - operatorID, organizationID, applicationID := kernel.NewID(), kernel.NewID(), kernel.NewID() + controlUserID, organizationID, applicationID := kernel.NewID(), kernel.NewID(), kernel.NewID() userID, keyID, delegationID, sessionID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() suffix := applicationID.String() statements := []struct { query string args []any }{ - {`INSERT INTO operators(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Configuration owner')`, []any{operatorID, "config-" + suffix + "@platform93.test"}}, + {`INSERT INTO control_users(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Configuration owner')`, []any{controlUserID, "config-" + suffix + "@platform93.test"}}, {`INSERT INTO organizations(id,name,slug) VALUES($1,'Configuration test',$2)`, []any{organizationID, "config-" + suffix}}, - {`INSERT INTO applications(id,organization_id,name,slug,internal_config) VALUES($1,$2,'Configuration test',$3,$4)`, []any{applicationID, organizationID, "config-" + suffix, `{"registration_mode":"public","password_enabled":true,"passwordless_enabled":true,"personal_api_keys_enabled":true,"delegation_enabled":true}`}}, + {`INSERT INTO applications(id,organization_id,name,slug,internal_config) VALUES($1,$2,'Configuration test',$3,$4)`, []any{applicationID, organizationID, "config-" + suffix, `{"registration_mode":"public","password_enabled":true,"passwordless_enabled":true,"personal_api_keys_enabled":true,"delegation_enabled":true,"user_invitations_enabled":false,"custom_token_claim_keys":[]}`}}, {`INSERT INTO users(id,application_id,email,normalized_email) VALUES($1,$2,$3,$3)`, []any{userID, applicationID, "user-" + suffix + "@platform93.test"}}, {`INSERT INTO personal_api_keys(id,application_id,user_id,token_prefix,token_digest,expires_at) VALUES($1,$2,$3,'p93_pat_test',$4,now()+interval '1 day')`, []any{keyID, applicationID, userID, []byte("key-" + suffix)}}, - {`INSERT INTO delegations(id,application_id,operator_id,user_id,reason,redirect_uri,permissions,exchange_digest,expires_at) VALUES($1,$2,$3,$4,'Support','https://app.example/callback',ARRAY['read'],$5,now()+interval '1 day')`, []any{delegationID, applicationID, operatorID, userID, []byte("delegation-" + suffix)}}, + {`INSERT INTO delegations(id,application_id,control_user_id,user_id,reason,redirect_uri,permissions,exchange_digest,expires_at) VALUES($1,$2,$3,$4,'Support','https://app.example/callback',ARRAY[$5],$6,now()+interval '1 day')`, []any{delegationID, applicationID, controlUserID, userID, "/applications/" + applicationID.String() + "/read", []byte("delegation-" + suffix)}}, {`INSERT INTO user_sessions(id,application_id,user_id,delegation_id,refresh_digest,expires_at) VALUES($1,$2,$3,$4,$5,now()+interval '1 day')`, []any{sessionID, applicationID, userID, delegationID, []byte("session-" + suffix)}}, } for _, statement := range statements { @@ -52,7 +52,7 @@ func TestApplicationConfigurationExposureAndEnforcement(t *testing.T) { publicRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{ "brand_name": "Example", "support_url": "https://example.test/help", - }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) publicRequest.Header.Set("If-Match", kernel.ETag(1)) publicResponse := httptest.NewRecorder() server.updatePublicApplicationConfig(publicResponse, publicRequest) @@ -63,7 +63,7 @@ func TestApplicationConfigurationExposureAndEnforcement(t *testing.T) { internalRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{ "registration_mode": "invite_only", "password_enabled": true, "passwordless_enabled": true, "personal_api_keys_enabled": false, "delegation_enabled": false, - }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) internalRequest.Header.Set("If-Match", kernel.ETag(2)) internalResponse := httptest.NewRecorder() server.updateInternalApplicationConfig(internalResponse, internalRequest) diff --git a/internal/httpapi/application_config_unit_test.go b/internal/httpapi/application_config_unit_test.go new file mode 100644 index 0000000..e6b6701 --- /dev/null +++ b/internal/httpapi/application_config_unit_test.go @@ -0,0 +1,22 @@ +package httpapi + +import "testing" + +func TestValidCustomTokenClaimKeys(t *testing.T) { + t.Parallel() + if !validCustomTokenClaimKeys([]string{"plan", "account_tier", "profile.region"}) { + t.Fatal("expected safe unique custom token claim keys to pass") + } + for _, values := range [][]string{{"duplicate", "duplicate"}, {"bad key"}, {""}} { + if validCustomTokenClaimKeys(values) { + t.Fatalf("expected invalid keys to fail: %#v", values) + } + } + many := make([]string, 33) + for index := range many { + many[index] = string(rune('a'+index%26)) + string(rune('0'+index/26)) + } + if validCustomTokenClaimKeys(many) { + t.Fatal("expected more than 32 keys to fail") + } +} diff --git a/internal/httpapi/application_flow_config.go b/internal/httpapi/application_flow_config.go index a59c9d9..284e91d 100644 --- a/internal/httpapi/application_flow_config.go +++ b/internal/httpapi/application_flow_config.go @@ -5,9 +5,14 @@ import ( "encoding/json" "errors" "net/url" + "regexp" "strings" ) +const maxRedirectURILength = 2048 + +var nativeRedirectSchemePattern = regexp.MustCompile(`^[a-z][a-z0-9+.-]*$`) + type applicationFlowConfig struct { OAuthClientID string `json:"oauth_client_id"` SignInRedirectURI string `json:"sign_in_redirect_uri"` @@ -73,7 +78,7 @@ WHERE application_id=$1 AND client_id=$2 AND disabled_at IS NULL`, applicationID signIn, signInErr := url.Parse(config.SignInRedirectURI) invitation, invitationErr := url.Parse(config.InvitationRedirectURI) if signInErr != nil || invitationErr != nil || !allowedApplicationRedirect(signIn) || !allowedApplicationRedirect(invitation) { - return errors.New("flow redirects must be absolute HTTPS URLs; HTTP is allowed only for localhost development") + return errors.New("flow redirects must use HTTPS, loopback HTTP, or an approved native application scheme") } if !strings.EqualFold(signIn.Scheme, invitation.Scheme) || !strings.EqualFold(signIn.Host, invitation.Host) { return errors.New("invitation_redirect_uri must use the same origin as sign_in_redirect_uri") @@ -82,14 +87,65 @@ WHERE application_id=$1 AND client_id=$2 AND disabled_at IS NULL`, applicationID } func allowedApplicationRedirect(value *url.URL) bool { - if value == nil || value.Host == "" || value.User != nil || value.Fragment != "" { + if value == nil || !value.IsAbs() || value.Opaque != "" || value.Host == "" || value.User != nil || value.Fragment != "" { + return false + } + scheme := strings.ToLower(value.Scheme) + if !nativeRedirectSchemePattern.MatchString(scheme) { return false } - if value.Scheme == "https" { + if scheme == "https" { return true } host := strings.ToLower(value.Hostname()) - return value.Scheme == "http" && (host == "localhost" || host == "127.0.0.1" || host == "::1") + if scheme == "http" { + return host == "localhost" || host == "127.0.0.1" || host == "::1" + } + _, reserved := map[string]struct{}{ + "about": {}, "blob": {}, "data": {}, "file": {}, "ftp": {}, "ftps": {}, "javascript": {}, + "mailto": {}, "tel": {}, "vbscript": {}, "ws": {}, "wss": {}, + }[scheme] + return !reserved +} + +func validateRedirectURI(raw string, allowNative bool) error { + if raw == "" || len(raw) > maxRedirectURILength || raw != strings.TrimSpace(raw) || strings.ContainsAny(raw, "\\\r\n\t") { + return errors.New("redirect URI must be a valid absolute URI without whitespace") + } + value, err := url.Parse(raw) + if err != nil || !allowedApplicationRedirect(value) { + return errors.New("redirect URI must use HTTPS, loopback HTTP, or an approved native application scheme") + } + if value.Scheme != "https" && value.Scheme != "http" && !allowNative { + return errors.New("native application redirect schemes are allowed only for public clients") + } + return nil +} + +func isNativeRedirectURI(raw string) bool { + value, err := url.Parse(raw) + if err != nil { + return false + } + scheme := strings.ToLower(value.Scheme) + return scheme != "http" && scheme != "https" +} + +func validateClientRedirectURIs(clientType string, values []string) error { + if clientType == "machine" && len(values) > 0 { + return errors.New("machine clients cannot register redirect URIs") + } + seen := make(map[string]struct{}, len(values)) + for _, value := range values { + if _, exists := seen[value]; exists { + return errors.New("redirect URIs must be unique") + } + if err := validateRedirectURI(value, clientType == "public"); err != nil { + return err + } + seen[value] = struct{}{} + } + return nil } func (s *Server) loadApplicationFlowConfig(ctx context.Context, applicationID string) (applicationFlowConfig, error) { diff --git a/internal/httpapi/application_invitation_integration_test.go b/internal/httpapi/application_invitation_integration_test.go new file mode 100644 index 0000000..c6f8a3d --- /dev/null +++ b/internal/httpapi/application_invitation_integration_test.go @@ -0,0 +1,203 @@ +package httpapi + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "sync" + "testing" + + "github.com/supaapps/platform93/internal/database" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/platform" + "github.com/supaapps/platform93/internal/secure" +) + +func TestApplicationInvitationRotationAcceptanceAndPKCEReplay(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, err := secure.NewVault(make([]byte, 32)) + if err != nil { + t.Fatal(err) + } + app := platform.New(db, vault, "https://platform93.test") + server := &Server{app: app} + organizationID, applicationID, controlUserID, roleID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() + suffix := applicationID.String() + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email,display_name) +VALUES($1,$2,$2,'Invitation administrator')`, controlUserID, "inviter-"+suffix+"@example.test"); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO organizations(id,name,slug) VALUES($1,'Invitation lifecycle',$2)`, organizationID, "invite-lifecycle-"+suffix); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO applications(id,organization_id,name,slug,auth_config) +VALUES($1,$2,'Invitation application',$3,$4)`, applicationID, organizationID, "invite-app-"+suffix, + `{"flows":{"oauth_client_id":"web","sign_in_redirect_uri":"https://app.example/auth/callback","invitation_redirect_uri":"https://app.example/invitations/accept"}}`); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO roles(id,application_id,key,name,scope,permissions) +VALUES($1,$2,'reader','Reader','application',ARRAY['records:read'])`, roleID, applicationID); err != nil { + t.Fatal(err) + } + tx, err := db.Begin(context.Background()) + if err != nil { + t.Fatal(err) + } + if err = app.EnsureSigningKey(context.Background(), tx); err != nil { + t.Fatal(err) + } + if err = tx.Commit(context.Background()); err != nil { + t.Fatal(err) + } + current := kernel.Actor{Type: "control_user", ID: controlUserID.String()} + email := "rotated-" + suffix + "@example.test" + createRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{ + "email": email, "application_role_keys": []string{"reader"}, + }, map[string]string{"application_id": applicationID.String()}, current) + createResponse := httptest.NewRecorder() + server.createControlInvitation(createResponse, createRequest) + if createResponse.Code != http.StatusCreated { + t.Fatalf("invitation creation failed: %d %s", createResponse.Code, createResponse.Body.String()) + } + var created struct { + ID string `json:"id"` + } + if json.Unmarshal(createResponse.Body.Bytes(), &created) != nil || created.ID == "" { + t.Fatal("invitation creation did not return an id") + } + var oldLinkDigest, oldCodeDigest []byte + if err = db.QueryRow(context.Background(), `SELECT link_credential_digest,code_credential_digest +FROM application_invitations WHERE id=$1`, created.ID).Scan(&oldLinkDigest, &oldCodeDigest); err != nil { + t.Fatal(err) + } + cooldownRequest := requestWithRoute(t, http.MethodPost, "/", nil, map[string]string{ + "application_id": applicationID.String(), "invitation_id": created.ID, + }, current) + cooldownResponse := httptest.NewRecorder() + server.resendInvitation(cooldownResponse, cooldownRequest) + if cooldownResponse.Code != http.StatusTooManyRequests || cooldownResponse.Header().Get("Retry-After") == "" { + t.Fatalf("resend cooldown was not enforced: %d %s", cooldownResponse.Code, cooldownResponse.Body.String()) + } + if _, err = db.Exec(context.Background(), `UPDATE application_invitations SET resend_available_at=now()-interval '1 second' WHERE id=$1`, created.ID); err != nil { + t.Fatal(err) + } + resendResponse := httptest.NewRecorder() + server.resendInvitation(resendResponse, cooldownRequest) + if resendResponse.Code != http.StatusAccepted { + t.Fatalf("eligible invitation resend failed: %d %s", resendResponse.Code, resendResponse.Body.String()) + } + var newLinkDigest, newCodeDigest []byte + if err = db.QueryRow(context.Background(), `SELECT link_credential_digest,code_credential_digest +FROM application_invitations WHERE id=$1`, created.ID).Scan(&newLinkDigest, &newCodeDigest); err != nil { + t.Fatal(err) + } + if equalBytes(oldLinkDigest, newLinkDigest) || equalBytes(oldCodeDigest, newCodeDigest) { + t.Fatal("resend did not rotate both invitation credentials") + } + + code, linkToken := "ABCD2345", "p93_invite_known_"+suffix + acceptanceID := kernel.NewID() + acceptedEmail := "accepted-" + suffix + "@example.test" + if _, err = db.Exec(context.Background(), `INSERT INTO application_invitations +(id,application_id,normalized_email,link_credential_digest,code_credential_digest,application_roles,workspace_roles,expires_at,inviter_type,inviter_id,last_sent_at,resend_available_at) +VALUES($1,$2,$3,$4,$5,ARRAY['reader'],'{}',now()+interval '1 hour','control_user',$6,now(),now()+interval '1 minute')`, + acceptanceID, applicationID, acceptedEmail, vault.Digest(linkToken), vault.Digest(code), controlUserID); err != nil { + t.Fatal(err) + } + verifier := "abcdefghijklmnopqrstuvwxyzABCDEFGH012345678" + digest := sha256.Sum256([]byte(verifier)) + challenge := base64.RawURLEncoding.EncodeToString(digest[:]) + responses := make([]*httptest.ResponseRecorder, 2) + var wait sync.WaitGroup + for index := range responses { + wait.Add(1) + go func(index int) { + defer wait.Done() + request := requestWithRoute(t, http.MethodPost, "/", map[string]any{ + "invitation_id": acceptanceID.String(), "link_token": linkToken, "code_challenge": challenge, + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{}) + responses[index] = httptest.NewRecorder() + server.exchangeInvitation(responses[index], request) + }(index) + } + wait.Wait() + successes := 0 + var authorizationCode string + for _, response := range responses { + if response.Code == http.StatusOK { + successes++ + var payload struct { + AuthorizationCode string `json:"authorization_code"` + } + if json.Unmarshal(response.Body.Bytes(), &payload) == nil { + authorizationCode = payload.AuthorizationCode + } + } else if response.Code != http.StatusUnauthorized { + t.Fatalf("unexpected concurrent acceptance result: %d %s", response.Code, response.Body.String()) + } + } + if successes != 1 || authorizationCode == "" { + t.Fatalf("expected exactly one successful invitation acceptance, got %d", successes) + } + var userID string + if err = db.QueryRow(context.Background(), `SELECT id FROM users WHERE application_id=$1 AND normalized_email=$2`, applicationID, acceptedEmail).Scan(&userID); err != nil { + t.Fatal(err) + } + var assignmentCount int + if err = db.QueryRow(context.Background(), `SELECT count(*) FROM role_assignments +WHERE application_id=$1 AND user_id=$2 AND role_id=$3`, applicationID, userID, roleID).Scan(&assignmentCount); err != nil || assignmentCount != 1 { + t.Fatalf("invitation role assignment count=%d err=%v", assignmentCount, err) + } + redeemRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{ + "authorization_code": authorizationCode, "code_verifier": verifier, + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{}) + redeemResponse := httptest.NewRecorder() + server.redeemInvitationAuthorizationCode(redeemResponse, redeemRequest) + if redeemResponse.Code != http.StatusOK { + t.Fatalf("PKCE redemption failed: %d %s", redeemResponse.Code, redeemResponse.Body.String()) + } + replayResponse := httptest.NewRecorder() + replayRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{ + "authorization_code": authorizationCode, "code_verifier": verifier, + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{}) + server.redeemInvitationAuthorizationCode(replayResponse, replayRequest) + if replayResponse.Code != http.StatusUnauthorized { + t.Fatalf("invitation authorization code replay was accepted: %d %s", replayResponse.Code, replayResponse.Body.String()) + } + + if _, err = db.Exec(context.Background(), `UPDATE application_invitations SET expires_at=now()-interval '1 second' WHERE id=$1`, created.ID); err != nil { + t.Fatal(err) + } + expiredRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{ + "email": email, "code": "ABCDEFGH", "code_challenge": challenge, + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{}) + expiredResponse := httptest.NewRecorder() + server.exchangeInvitation(expiredResponse, expiredRequest) + if expiredResponse.Code != http.StatusUnauthorized { + t.Fatalf("expired invitation was accepted: %d %s", expiredResponse.Code, expiredResponse.Body.String()) + } + + revokeRequest := requestWithRoute(t, http.MethodDelete, "/", nil, map[string]string{ + "application_id": applicationID.String(), "invitation_id": created.ID, + }, current) + revokeResponse := httptest.NewRecorder() + server.revokeInvitation(revokeResponse, revokeRequest) + if revokeResponse.Code != http.StatusNoContent { + t.Fatalf("invitation revocation failed: %d %s", revokeResponse.Code, revokeResponse.Body.String()) + } +} diff --git a/internal/httpapi/application_redirect_test.go b/internal/httpapi/application_redirect_test.go new file mode 100644 index 0000000..55e4d34 --- /dev/null +++ b/internal/httpapi/application_redirect_test.go @@ -0,0 +1,56 @@ +package httpapi + +import ( + "net/url" + "testing" +) + +func TestAllowedApplicationRedirectSupportsNativeSchemes(t *testing.T) { + t.Parallel() + for _, raw := range []string{ + "https://app.example/auth/callback", + "http://localhost:8081/auth/callback", + "http://127.0.0.1:8081/auth/callback", + "sampleapp://auth/callback", + "com.example.app://oauth/callback?source=p93", + } { + value, err := url.Parse(raw) + if err != nil || !allowedApplicationRedirect(value) { + t.Fatalf("expected %q to be allowed", raw) + } + } +} + +func TestAllowedApplicationRedirectRejectsUnsafeSchemesAndOrigins(t *testing.T) { + t.Parallel() + for _, raw := range []string{ + "http://example.com/auth/callback", + "javascript://auth/callback", + "data://auth/callback", + "file://auth/callback", + "https://user@example.com/auth/callback", + "https://example.com/auth/callback#token", + "/auth/callback", + } { + value, _ := url.Parse(raw) + if allowedApplicationRedirect(value) { + t.Fatalf("expected %q to be rejected", raw) + } + } +} + +func TestValidateClientRedirectURIsRestrictsNativeSchemesToPublicClients(t *testing.T) { + t.Parallel() + if err := validateClientRedirectURIs("public", []string{"sampleapp://auth/callback"}); err != nil { + t.Fatalf("public native redirect should be accepted: %v", err) + } + if err := validateClientRedirectURIs("confidential", []string{"sampleapp://auth/callback"}); err == nil { + t.Fatal("confidential native redirect should be rejected") + } + if err := validateClientRedirectURIs("machine", []string{"https://app.example/callback"}); err == nil { + t.Fatal("machine redirect should be rejected") + } + if err := validateClientRedirectURIs("public", []string{"sampleapp://auth/callback", "sampleapp://auth/callback"}); err == nil { + t.Fatal("duplicate redirects should be rejected") + } +} diff --git a/internal/httpapi/application_workspace_invariants_test.go b/internal/httpapi/application_workspace_invariants_test.go index 3bdfd5a..2eafad4 100644 --- a/internal/httpapi/application_workspace_invariants_test.go +++ b/internal/httpapi/application_workspace_invariants_test.go @@ -104,7 +104,7 @@ func TestWorkspaceOwnershipAndClientScopeInvariants(t *testing.T) { assignment := requestWithRoute(t, http.MethodPost, "/", map[string]any{ "client_id": clientID, "role_id": roleID, - }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "operator"}) + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "control_user"}) response := httptest.NewRecorder() server.assignRole(response, assignment) if response.Code != http.StatusCreated { @@ -139,18 +139,18 @@ func TestFinalInstallationOwnerCannotBeDemoted(t *testing.T) { vault, _ := secure.NewVault(make([]byte, 32)) server := &Server{app: platform.New(db, vault, "https://platform93.test")} ownerID := kernel.NewID() - if _, err = db.Exec(context.Background(), `UPDATE installation_operator_roles SET role='admin' WHERE role='owner'`); err != nil { + if _, err = db.Exec(context.Background(), `UPDATE installation_control_user_roles SET role='admin' WHERE role='owner'`); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, ownerID, "installation-owner-"+ownerID.String()+"@example.test"); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, ownerID, "installation-owner-"+ownerID.String()+"@example.test"); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,'owner')`, ownerID); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'owner')`, ownerID); err != nil { t.Fatal(err) } - request := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"role": "admin"}, map[string]string{"operator_id": ownerID.String()}, kernel.Actor{Type: "operator", ID: ownerID.String()}) + request := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"role": "admin"}, map[string]string{"control_user_id": ownerID.String()}, kernel.Actor{Type: "control_user", ID: ownerID.String()}) response := httptest.NewRecorder() - server.updateInstallationOperator(response, request) + server.updateInstallationControlUser(response, request) if response.Code != http.StatusConflict { t.Fatalf("final installation owner demotion returned %d: %s", response.Code, response.Body.String()) } diff --git a/internal/httpapi/auth_provider_config.go b/internal/httpapi/auth_provider_config.go index 9d4464e..151a81f 100644 --- a/internal/httpapi/auth_provider_config.go +++ b/internal/httpapi/auth_provider_config.go @@ -9,16 +9,19 @@ import ( "time" "github.com/go-chi/chi/v5" + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" "github.com/supaapps/platform93/internal/kernel" ) type externalAuthProviderConfig struct { - ID string - Provider string - ClientID string - Credentials map[string]string - Scope string - Inheritable bool + ID string + Provider string + ClientID string + Credentials map[string]string + Scope string + Inheritable bool + ControlLoginEnabled bool } func (s *Server) configureGoogleProvider(w http.ResponseWriter, r *http.Request) { @@ -55,17 +58,48 @@ func (s *Server) updateAuthProvider(w http.ResponseWriter, r *http.Request, scop return } var request struct { - Inheritable *bool `json:"inheritable"` + Inheritable *bool `json:"inheritable"` + ControlLoginEnabled *bool `json:"control_login_enabled"` + ConfirmAffectedUsers bool `json:"confirm_affected_users,omitempty"` } if !kernel.DecodeJSON(w, r, &request) { return } - if request.Inheritable == nil { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "inheritance_required", "The inheritable boolean is required.") + if request.Inheritable == nil && request.ControlLoginEnabled == nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "auth_provider_update_required", "At least one provider setting is required.") return } - result, err := s.app.DB.Exec(r.Context(), `UPDATE auth_provider_configs SET inheritable=$1,updated_at=now() -WHERE provider=$2 AND application_id IS NULL AND organization_id IS NOT DISTINCT FROM $3::uuid AND disabled_at IS NULL`, *request.Inheritable, provider, scope.OrganizationID) + if request.ControlLoginEnabled != nil && scope.name() != "installation" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "control_login_installation_only", "Platform login can be enabled only on an installation provider.") + return + } + if request.ControlLoginEnabled != nil && !*request.ControlLoginEnabled && !s.allowControlMethodRemoval(w, r, provider, request.ConfirmAffectedUsers) { + return + } + tx, err := s.app.DB.Begin(r.Context()) + var previousControlLogin bool + if err == nil { + err = tx.QueryRow(r.Context(), `SELECT control_login_enabled FROM auth_provider_configs +WHERE provider=$1 AND application_id IS NULL AND organization_id IS NOT DISTINCT FROM $2::uuid AND disabled_at IS NULL FOR UPDATE`, provider, scope.OrganizationID).Scan(&previousControlLogin) + } + var result pgconn.CommandTag + if err == nil { + result, err = tx.Exec(r.Context(), `UPDATE auth_provider_configs SET +inheritable=COALESCE($1,inheritable),control_login_enabled=COALESCE($2,control_login_enabled),updated_at=now() +WHERE provider=$3 AND application_id IS NULL AND organization_id IS NOT DISTINCT FROM $4::uuid AND disabled_at IS NULL`, request.Inheritable, request.ControlLoginEnabled, provider, scope.OrganizationID) + } + if err == nil && request.ControlLoginEnabled != nil && previousControlLogin != *request.ControlLoginEnabled { + eventType := "control_auth.provider_login_enabled" + if !*request.ControlLoginEnabled { + eventType = "control_auth.provider_login_disabled" + } + err = s.emitControlEvent(r.Context(), tx, r, eventType, "auth_provider/"+provider, map[string]any{"provider": provider, "enabled": *request.ControlLoginEnabled}) + } + if err == nil { + err = tx.Commit(r.Context()) + } else if tx != nil { + _ = tx.Rollback(r.Context()) + } if err != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "auth_provider_update_failed", "The authentication provider could not be updated.") return @@ -82,12 +116,13 @@ func (s *Server) configureAuthProvider(w http.ResponseWriter, r *http.Request, s return } var request struct { - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret,omitempty"` - TeamID string `json:"team_id,omitempty"` - KeyID string `json:"key_id,omitempty"` - PrivateKey string `json:"private_key_pem,omitempty"` - Inheritable bool `json:"inheritable,omitempty"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret,omitempty"` + TeamID string `json:"team_id,omitempty"` + KeyID string `json:"key_id,omitempty"` + PrivateKey string `json:"private_key_pem,omitempty"` + Inheritable bool `json:"inheritable,omitempty"` + ControlLoginEnabled *bool `json:"control_login_enabled,omitempty"` } if !kernel.DecodeJSON(w, r, &request) { return @@ -108,6 +143,10 @@ func (s *Server) configureAuthProvider(w http.ResponseWriter, r *http.Request, s kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_auth_provider", "The provider client identifier and credentials are required.") return } + if request.ControlLoginEnabled != nil && scope.name() != "installation" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "control_login_installation_only", "Platform login can be enabled only on an installation provider.") + return + } if provider == "apple" { if _, err := createAppleClientSecret(externalAuthProviderConfig{ClientID: request.ClientID, Credentials: credentials}, s.app.Now()); err != nil { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_apple_private_key", "The Apple private key must be a valid ES256 PKCS#8 or EC private key.") @@ -115,31 +154,51 @@ func (s *Server) configureAuthProvider(w http.ResponseWriter, r *http.Request, s } } var id string - _ = s.app.DB.QueryRow(r.Context(), `SELECT id FROM auth_provider_configs WHERE provider=$1 AND application_id IS NOT DISTINCT FROM $2::uuid AND organization_id IS NOT DISTINCT FROM $3::uuid AND disabled_at IS NULL`, provider, scope.ApplicationID, scope.OrganizationID).Scan(&id) + var previousControlLogin bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT id,control_login_enabled FROM auth_provider_configs WHERE provider=$1 AND application_id IS NOT DISTINCT FROM $2::uuid AND organization_id IS NOT DISTINCT FROM $3::uuid AND disabled_at IS NULL`, provider, scope.ApplicationID, scope.OrganizationID).Scan(&id, &previousControlLogin) + controlLoginEnabled := previousControlLogin + if request.ControlLoginEnabled != nil { + controlLoginEnabled = *request.ControlLoginEnabled + } + if scope.name() == "installation" && previousControlLogin && !controlLoginEnabled && !s.allowControlMethodRemoval(w, r, provider, false) { + return + } if id == "" { id = kernel.NewID().String() } encoded, _ := json.Marshal(credentials) ciphertext, err := s.app.Vault.Encrypt(encoded, "auth-provider:"+id) + var tx pgx.Tx if err == nil { - result, updateErr := s.app.DB.Exec(r.Context(), `UPDATE auth_provider_configs SET client_id=$1,config_ciphertext=$2,inheritable=$3,updated_at=now() -WHERE id=$4`, request.ClientID, ciphertext, scope.inheritable(request.Inheritable), id) + tx, err = s.app.DB.Begin(r.Context()) + } + if err == nil { + result, updateErr := tx.Exec(r.Context(), `UPDATE auth_provider_configs SET client_id=$1,config_ciphertext=$2,inheritable=$3,control_login_enabled=$4,updated_at=now() +WHERE id=$5`, request.ClientID, ciphertext, scope.inheritable(request.Inheritable), controlLoginEnabled && scope.name() == "installation", id) err = updateErr if err == nil && result.RowsAffected() == 0 { - _, err = s.app.DB.Exec(r.Context(), `INSERT INTO auth_provider_configs(id,organization_id,application_id,provider,client_id,config_ciphertext,inheritable) -VALUES($1,$2,$3,$4,$5,$6,$7)`, id, scope.OrganizationID, scope.ApplicationID, provider, request.ClientID, ciphertext, scope.inheritable(request.Inheritable)) + _, err = tx.Exec(r.Context(), `INSERT INTO auth_provider_configs(id,organization_id,application_id,provider,client_id,config_ciphertext,inheritable,control_login_enabled) +VALUES($1,$2,$3,$4,$5,$6,$7,$8)`, id, scope.OrganizationID, scope.ApplicationID, provider, request.ClientID, ciphertext, scope.inheritable(request.Inheritable), controlLoginEnabled && scope.name() == "installation") + } + } + if err == nil && scope.name() == "installation" && previousControlLogin != controlLoginEnabled { + eventType := "control_auth.provider_login_enabled" + if !controlLoginEnabled { + eventType = "control_auth.provider_login_disabled" } + err = s.emitControlEvent(r.Context(), tx, r, eventType, "auth_provider/"+provider, map[string]any{"provider": provider, "enabled": controlLoginEnabled}) + } + if err == nil { + err = tx.Commit(r.Context()) + } else if tx != nil { + _ = tx.Rollback(r.Context()) } if err != nil { kernel.WriteProblem(w, r, http.StatusConflict, "auth_provider_configuration_failed", "The authentication provider could not be configured.") return } - applicationID := "{application_id}" - if scope.ApplicationID != nil { - applicationID = *scope.ApplicationID - } kernel.WriteJSON(w, http.StatusOK, map[string]any{"id": id, "provider": provider, "client_id": request.ClientID, "configured": true, - "scope": scope.name(), "inheritable": scope.inheritable(request.Inheritable), "callback_uri": s.externalAuthCallbackURI(applicationID, provider)}) + "scope": scope.name(), "inheritable": scope.inheritable(request.Inheritable), "control_login_enabled": controlLoginEnabled && scope.name() == "installation", "callback_uri": s.externalAuthCallbackURI(provider)}) } func (s *Server) listAuthProviders(w http.ResponseWriter, r *http.Request) { @@ -147,7 +206,7 @@ func (s *Server) listAuthProviders(w http.ResponseWriter, r *http.Request) { items := []map[string]any{} for _, provider := range []string{"google", "apple"} { if config, err := s.loadEffectiveAuthProvider(r.Context(), applicationID, provider); err == nil { - items = append(items, authProviderResponse(config, s.externalAuthCallbackURI(applicationID, provider))) + items = append(items, authProviderResponse(config, s.externalAuthCallbackURI(provider))) } } kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) @@ -169,12 +228,12 @@ func (s *Server) listAuthProvidersForScope(w http.ResponseWriter, r *http.Reques if !s.authorizeProviderScope(w, r, scope, false) { return } - query := `SELECT id,provider,client_id,inheritable,created_at,updated_at, + query := `SELECT id,provider,client_id,inheritable,control_login_enabled,created_at,updated_at, CASE WHEN organization_id IS NOT NULL THEN 'organization' ELSE 'installation' END FROM auth_provider_configs WHERE application_id IS NULL AND organization_id IS NOT DISTINCT FROM $1::uuid AND disabled_at IS NULL ORDER BY provider` if scope.OrganizationID != nil { - query = `SELECT id,provider,client_id,inheritable,created_at,updated_at, + query = `SELECT id,provider,client_id,inheritable,control_login_enabled,created_at,updated_at, CASE WHEN organization_id IS NOT NULL THEN 'organization' ELSE 'installation' END FROM auth_provider_configs WHERE application_id IS NULL AND disabled_at IS NULL AND (organization_id=$1 OR (organization_id IS NULL AND inheritable)) @@ -189,11 +248,24 @@ ORDER BY provider,organization_id NULLS LAST` items := []map[string]any{} for rows.Next() { var id, provider, clientID string - var inheritable bool + var inheritable, controlLoginEnabled bool var createdAt, updatedAt time.Time var providerScope string - if rows.Scan(&id, &provider, &clientID, &inheritable, &createdAt, &updatedAt, &providerScope) == nil { - items = append(items, map[string]any{"id": id, "provider": provider, "client_id": clientID, "scope": providerScope, "inheritable": inheritable, "inherited": providerScope != scope.name(), "configured": true, "callback_uri": s.externalAuthCallbackURI("{application_id}", provider), "created_at": createdAt, "updated_at": updatedAt}) + if rows.Scan(&id, &provider, &clientID, &inheritable, &controlLoginEnabled, &createdAt, &updatedAt, &providerScope) == nil { + var linkedControlUsers, inheritingApplications int + _ = s.app.DB.QueryRow(r.Context(), `SELECT count(*) FROM control_user_identities WHERE auth_provider_config_id=$1`, id).Scan(&linkedControlUsers) + if inheritable && providerScope == "installation" { + _ = s.app.DB.QueryRow(r.Context(), `SELECT count(*) FROM applications a WHERE a.deleted_at IS NULL +AND NOT EXISTS(SELECT 1 FROM auth_provider_configs local WHERE local.application_id=a.id AND local.provider=$1 AND local.disabled_at IS NULL) +AND NOT EXISTS(SELECT 1 FROM auth_provider_configs organization_provider WHERE organization_provider.organization_id=a.organization_id +AND organization_provider.application_id IS NULL AND organization_provider.provider=$1 AND organization_provider.inheritable AND organization_provider.disabled_at IS NULL)`, provider).Scan(&inheritingApplications) + } else if inheritable && providerScope == "organization" { + _ = s.app.DB.QueryRow(r.Context(), `SELECT count(*) FROM applications a WHERE a.organization_id=$1 AND a.deleted_at IS NULL +AND NOT EXISTS(SELECT 1 FROM auth_provider_configs local WHERE local.application_id=a.id AND local.provider=$2 AND local.disabled_at IS NULL)`, scope.OrganizationID, provider).Scan(&inheritingApplications) + } + items = append(items, map[string]any{"id": id, "provider": provider, "client_id": clientID, "scope": providerScope, "inheritable": inheritable, + "control_login_enabled": controlLoginEnabled, "linked_control_users": linkedControlUsers, "inheriting_applications": inheritingApplications, + "inherited": providerScope != scope.name(), "configured": true, "callback_uri": s.externalAuthCallbackURI(provider), "created_at": createdAt, "updated_at": updatedAt}) } } kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) @@ -215,8 +287,30 @@ func (s *Server) disableAuthProvider(w http.ResponseWriter, r *http.Request, sco if !s.authorizeProviderScope(w, r, scope, true) { return } - result, err := s.app.DB.Exec(r.Context(), `UPDATE auth_provider_configs SET disabled_at=now(),updated_at=now() -WHERE provider=$1 AND application_id IS NOT DISTINCT FROM $2::uuid AND organization_id IS NOT DISTINCT FROM $3::uuid AND disabled_at IS NULL`, chi.URLParam(r, "provider"), scope.ApplicationID, scope.OrganizationID) + provider := chi.URLParam(r, "provider") + tx, err := s.app.DB.Begin(r.Context()) + var controlLoginEnabled bool + if err == nil { + err = tx.QueryRow(r.Context(), `SELECT control_login_enabled FROM auth_provider_configs +WHERE provider=$1 AND application_id IS NOT DISTINCT FROM $2::uuid AND organization_id IS NOT DISTINCT FROM $3::uuid AND disabled_at IS NULL FOR UPDATE`, provider, scope.ApplicationID, scope.OrganizationID).Scan(&controlLoginEnabled) + } + if err == nil && scope.name() == "installation" && controlLoginEnabled && !s.allowControlMethodRemoval(w, r, provider, r.URL.Query().Get("confirm_affected_users") == "true") { + _ = tx.Rollback(r.Context()) + return + } + var result pgconn.CommandTag + if err == nil { + result, err = tx.Exec(r.Context(), `UPDATE auth_provider_configs SET disabled_at=now(),updated_at=now() +WHERE provider=$1 AND application_id IS NOT DISTINCT FROM $2::uuid AND organization_id IS NOT DISTINCT FROM $3::uuid AND disabled_at IS NULL`, provider, scope.ApplicationID, scope.OrganizationID) + } + if err == nil && scope.name() == "installation" && controlLoginEnabled { + err = s.emitControlEvent(r.Context(), tx, r, "control_auth.provider_login_disabled", "auth_provider/"+provider, map[string]any{"provider": provider, "enabled": false}) + } + if err == nil { + err = tx.Commit(r.Context()) + } else if tx != nil { + _ = tx.Rollback(r.Context()) + } if err != nil || result.RowsAffected() != 1 { kernel.WriteProblem(w, r, http.StatusNotFound, "auth_provider_not_found", "The authentication provider was not found at this scope.") return @@ -227,14 +321,14 @@ WHERE provider=$1 AND application_id IS NOT DISTINCT FROM $2::uuid AND organizat func (s *Server) loadEffectiveAuthProvider(ctx context.Context, applicationID, provider string) (externalAuthProviderConfig, error) { var value externalAuthProviderConfig var ciphertext string - err := s.app.DB.QueryRow(ctx, `SELECT ap.id,ap.provider,ap.client_id,ap.config_ciphertext,ap.inheritable, + err := s.app.DB.QueryRow(ctx, `SELECT ap.id,ap.provider,ap.client_id,ap.config_ciphertext,ap.inheritable,ap.control_login_enabled, CASE WHEN ap.application_id IS NOT NULL THEN 'application' WHEN ap.organization_id IS NOT NULL THEN 'organization' ELSE 'installation' END FROM auth_provider_configs ap JOIN applications a ON a.id=$1 WHERE ap.provider=$2 AND ap.disabled_at IS NULL AND (ap.application_id=$1 OR (ap.application_id IS NULL AND ap.organization_id=a.organization_id AND ap.inheritable) OR (ap.application_id IS NULL AND ap.organization_id IS NULL AND ap.inheritable)) ORDER BY CASE WHEN ap.application_id IS NOT NULL THEN 0 WHEN ap.organization_id IS NOT NULL THEN 1 ELSE 2 END LIMIT 1`, applicationID, provider). - Scan(&value.ID, &value.Provider, &value.ClientID, &ciphertext, &value.Inheritable, &value.Scope) + Scan(&value.ID, &value.Provider, &value.ClientID, &ciphertext, &value.Inheritable, &value.ControlLoginEnabled, &value.Scope) if err != nil && provider == "google" { var metadata []byte err = s.app.DB.QueryRow(ctx, `SELECT id,metadata,ciphertext FROM application_secrets WHERE application_id=$1 AND kind='auth_provider' AND name='google'`, applicationID).Scan(&value.ID, &metadata, &ciphertext) @@ -264,9 +358,9 @@ ORDER BY CASE WHEN ap.application_id IS NOT NULL THEN 0 WHEN ap.organization_id func authProviderResponse(config externalAuthProviderConfig, callbackURI string) map[string]any { return map[string]any{"id": config.ID, "provider": config.Provider, "client_id": config.ClientID, "configured": true, "scope": config.Scope, - "inheritable": config.Inheritable, "inherited": config.Scope != "application", "callback_uri": callbackURI} + "inheritable": config.Inheritable, "control_login_enabled": config.ControlLoginEnabled, "inherited": config.Scope != "application", "callback_uri": callbackURI} } -func (s *Server) externalAuthCallbackURI(applicationID, provider string) string { - return s.app.PublicURL + "/v1/applications/" + applicationID + "/auth/providers/" + provider + "/callback" +func (s *Server) externalAuthCallbackURI(provider string) string { + return s.app.PublicURL + "/v1/auth/providers/" + provider + "/callback" } diff --git a/internal/httpapi/auth_provider_inheritance_test.go b/internal/httpapi/auth_provider_inheritance_test.go index b480e74..f6e9b77 100644 --- a/internal/httpapi/auth_provider_inheritance_test.go +++ b/internal/httpapi/auth_provider_inheritance_test.go @@ -31,15 +31,15 @@ func TestInstallationAuthProviderInheritanceCanBeChangedWithoutCredentials(t *te t.Fatal(err) } server := &Server{app: platform.New(db, vault, "https://platform93.test")} - operatorID, organizationID, applicationID, providerID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() + controlUserID, organizationID, applicationID, providerID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() suffix := providerID.String() if _, err = db.Exec(context.Background(), `DELETE FROM auth_provider_configs WHERE application_id IS NULL AND organization_id IS NULL AND client_id IN ('platform93-inheritance-test-client','client')`); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, operatorID, "provider-owner-"+suffix+"@example.test"); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, controlUserID, "provider-owner-"+suffix+"@example.test"); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,'owner')`, operatorID); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'owner')`, controlUserID); err != nil { t.Fatal(err) } if _, err = db.Exec(context.Background(), `INSERT INTO organizations(id,name,slug) VALUES($1,'Provider inheritance',$2)`, organizationID, "provider-inheritance-"+suffix); err != nil { @@ -60,7 +60,7 @@ func TestInstallationAuthProviderInheritanceCanBeChangedWithoutCredentials(t *te }() update := func(inheritable any) *httptest.ResponseRecorder { - request := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": inheritable}, map[string]string{"provider": "google"}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + request := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": inheritable}, map[string]string{"provider": "google"}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) response := httptest.NewRecorder() server.updateInstallationAuthProvider(response, request) return response diff --git a/internal/httpapi/authorization.go b/internal/httpapi/authorization.go index 4176c8f..572f356 100644 --- a/internal/httpapi/authorization.go +++ b/internal/httpapi/authorization.go @@ -1,14 +1,15 @@ package httpapi import ( + "fmt" "net/http" "strings" "time" "github.com/go-chi/chi/v5" "github.com/google/uuid" + platformauthz "github.com/supaapps/platform93/internal/authorization" "github.com/supaapps/platform93/internal/kernel" - "github.com/supaapps/platform93/internal/secure" ) func (s *Server) createRole(w http.ResponseWriter, r *http.Request) { @@ -21,9 +22,8 @@ func (s *Server) createRole(w http.ResponseWriter, r *http.Request) { if !kernel.DecodeJSON(w, r, &request) { return } - request.Key = strings.TrimSpace(request.Key) request.Name = strings.TrimSpace(request.Name) - if request.Key == "" || request.Name == "" || (request.Scope != "application" && request.Scope != "workspace") || len(request.Permissions) == 0 { + if request.Name == "" || (request.Scope != "application" && request.Scope != "workspace") || validateRolePermissions(request.Permissions) != nil || platformauthz.ValidateRoleKey(request.Key) != nil { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_role", "Key, name, scope, and at least one permission are required.") return } @@ -92,18 +92,10 @@ func (s *Server) updateRole(w http.ResponseWriter, r *http.Request) { } } if request.Permissions != nil { - values := uniqueStrings(*request.Permissions) - for _, permission := range values { - if strings.TrimSpace(permission) == "" || len(permission) > 160 { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_role", "Permissions must be non-empty and at most 160 characters.") - return - } - } - if len(values) == 0 || len(values) > 200 { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_role", "At least one and at most 200 permissions are required.") + if err := validateRolePermissions(*request.Permissions); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_role_permissions", "Permissions must be unique lowercase ASCII colon-delimited keys; wildcards are allowed only as the final complete segment.") return } - request.Permissions = &values } var version int64 var builtIn bool @@ -190,7 +182,11 @@ SELECT $1,$2,$3,$4,$5,$6 WHERE EXISTS(SELECT 1 FROM users WHERE id=$3 AND applic _, err = tx.Exec(r.Context(), `INSERT INTO billing_profiles(id,application_id,subject_type,subject_id) VALUES($1,$2,'workspace',$3)`, kernel.NewID(), chi.URLParam(r, "application_id"), id) } - if err != nil || tx.Commit(r.Context()) != nil { + applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "workspace.created", "workspace/"+id.String(), actor(r), map[string]any{"workspace_id": id, "owner_user_id": request.OwnerUserID, "key": request.Key, "name": request.Name, "status": "active"}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusConflict, "workspace_conflict", "A workspace with this key already exists.") return } @@ -321,240 +317,6 @@ func (s *Server) deleteRoleAssignment(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) } -func (s *Server) createWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { - var request struct { - WorkspaceID string `json:"workspace_id"` - Email string `json:"email"` - RoleKeys []string `json:"role_keys"` - ExpiresIn int64 `json:"expires_in,omitempty"` - } - if !kernel.DecodeJSON(w, r, &request) { - return - } - if request.WorkspaceID == "" { - request.WorkspaceID = chi.URLParam(r, "workspace_id") - } - normalized := kernel.NormalizeEmail(request.Email) - request.RoleKeys = uniqueStrings(request.RoleKeys) - if !strings.Contains(normalized, "@") || len(request.RoleKeys) == 0 || len(request.RoleKeys) > 20 { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_workspace_invitation", "A valid email, workspace, and at least one role key are required.") - return - } - if request.ExpiresIn == 0 { - request.ExpiresIn = int64((7 * 24 * time.Hour).Seconds()) - } - if request.ExpiresIn < 300 || request.ExpiresIn > int64((30*24*time.Hour).Seconds()) { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_invitation_expiry", "Invitation expiry must be between five minutes and thirty days.") - return - } - var validWorkspace bool - var roleCount int - applicationID := chi.URLParam(r, "application_id") - if actor(r).Type == "user" && !s.canAccessWorkspace(r, true) { - kernel.WriteProblem(w, r, http.StatusForbidden, "workspace_management_required", "Workspace management permission is required.") - return - } - err := s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM workspaces WHERE id=$1 AND application_id=$2 AND deleted_at IS NULL), -(SELECT count(*) FROM roles WHERE application_id=$2 AND scope='workspace' AND key=ANY($3))`, - request.WorkspaceID, applicationID, request.RoleKeys).Scan(&validWorkspace, &roleCount) - if err != nil || !validWorkspace || roleCount != len(request.RoleKeys) { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_workspace_roles", "The workspace and role keys must exist in this application and all roles must be workspace scoped.") - return - } - credential, err := secure.RandomToken("p93_invite_", 32) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "invitation_creation_failed", "The invitation credential could not be created.") - return - } - invitationID := kernel.NewID() - notificationID := kernel.NewID() - expiresAt := s.app.Now().Add(time.Duration(request.ExpiresIn) * time.Second) - var workspaceName string - if err = s.app.DB.QueryRow(r.Context(), `SELECT name FROM workspaces WHERE id=$1 AND application_id=$2 AND deleted_at IS NULL`, request.WorkspaceID, applicationID).Scan(&workspaceName); err != nil { - kernel.WriteProblem(w, r, http.StatusNotFound, "workspace_not_found", "The workspace was not found.") - return - } - flows, _ := s.loadApplicationFlowConfig(r.Context(), applicationID) - invitationLink := "" - if flows.InvitationRedirectURI != "" { - invitationLink = appendCredentialQuery(flows.InvitationRedirectURI, map[string]string{ - "application_id": applicationID, "invitation_id": invitationID.String(), "invitation_token": credential, "platform93_flow": "workspace_invitation", - }) - } - templateID, templateLocale, payload, renderErr := s.renderSystemNotification(r.Context(), &applicationID, workspaceInvitationTemplate, normalized, map[string]any{ - "workspace_id": request.WorkspaceID, "workspace_name": workspaceName, "role_keys": strings.Join(request.RoleKeys, ", "), - "invitation_link": invitationLink, "invitation_token": credential, "expires_at": templateTimestamp(expiresAt), - }) - if renderErr != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "invitation_template_unavailable", "The workspace invitation email template is unavailable or invalid.") - return - } - tx, err := s.app.DB.Begin(r.Context()) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The invitation could not be created.") - return - } - defer rollback(tx, r.Context()) - _, err = tx.Exec(r.Context(), `INSERT INTO workspace_invitations -(id,application_id,workspace_id,normalized_email,credential_digest,roles,expires_at) VALUES ($1,$2,$3,$4,$5,$6,$7)`, - invitationID, applicationID, request.WorkspaceID, normalized, s.app.Vault.Digest(credential), request.RoleKeys, expiresAt) - if err == nil { - var ciphertext string - ciphertext, err = s.app.Vault.Encrypt(payload, "notification:"+notificationID.String()) - if err == nil { - _, err = tx.Exec(r.Context(), `INSERT INTO notifications -(id,application_id,template_id,recipient,locale,payload_ciphertext,status) VALUES ($1,$2,$3,$4,$5,$6,'queued')`, notificationID, applicationID, templateID, normalized, templateLocale, ciphertext) - } - } - parsedApplicationID, parseErr := uuid.Parse(applicationID) - if err == nil && parseErr == nil { - _, err = s.app.Emit(r.Context(), tx, &parsedApplicationID, "workspace.invitation_created", "workspace_invitation/"+invitationID.String(), actor(r), - map[string]any{"invitation_id": invitationID, "workspace_id": request.WorkspaceID, "role_keys": request.RoleKeys}) - } - if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusConflict, "workspace_invitation_conflict", "A pending invitation already exists or could not be created.") - return - } - kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": invitationID, "workspace_id": request.WorkspaceID, "email": normalized, - "role_keys": request.RoleKeys, "expires_at": expiresAt, "invitation_token": credential}) -} - -func (s *Server) listWorkspaceInvitations(w http.ResponseWriter, r *http.Request) { - rows, err := s.app.DB.Query(r.Context(), `SELECT i.id,i.workspace_id,t.key,t.name,i.normalized_email,i.roles,i.expires_at, -i.accepted_at,i.revoked_at,i.created_at FROM workspace_invitations i JOIN workspaces t ON t.id=i.workspace_id -WHERE i.application_id=$1 ORDER BY i.created_at DESC,i.id DESC`, chi.URLParam(r, "application_id")) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Workspace invitations could not be loaded.") - return - } - defer rows.Close() - items := []map[string]any{} - for rows.Next() { - var id, workspaceID, workspaceKey, workspaceName, email string - var roles []string - var expiresAt, createdAt time.Time - var acceptedAt, revokedAt *time.Time - if rows.Scan(&id, &workspaceID, &workspaceKey, &workspaceName, &email, &roles, &expiresAt, &acceptedAt, &revokedAt, &createdAt) == nil { - items = append(items, workspaceInvitationResponse(id, workspaceID, workspaceKey, workspaceName, email, roles, expiresAt, acceptedAt, revokedAt, createdAt)) - } - } - kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) -} - -func (s *Server) revokeWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { - result, err := s.app.DB.Exec(r.Context(), `UPDATE workspace_invitations SET revoked_at=now() -WHERE id=$1 AND application_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL`, chi.URLParam(r, "invitation_id"), chi.URLParam(r, "application_id")) - if err != nil || result.RowsAffected() != 1 { - kernel.WriteProblem(w, r, http.StatusNotFound, "workspace_invitation_not_found", "The pending workspace invitation was not found.") - return - } - w.WriteHeader(http.StatusNoContent) -} - -func (s *Server) listMyWorkspaceInvitations(w http.ResponseWriter, r *http.Request) { - rows, err := s.app.DB.Query(r.Context(), `SELECT i.id,i.workspace_id,t.key,t.name,i.normalized_email,i.roles,i.expires_at, -i.accepted_at,i.revoked_at,i.created_at FROM workspace_invitations i JOIN workspaces t ON t.id=i.workspace_id JOIN users u -ON u.application_id=i.application_id AND u.normalized_email=i.normalized_email -WHERE i.application_id=$1 AND u.id=$2 AND i.accepted_at IS NULL AND i.revoked_at IS NULL AND i.expires_at>now() -ORDER BY i.created_at DESC,i.id DESC`, chi.URLParam(r, "application_id"), actor(r).ID) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Workspace invitations could not be loaded.") - return - } - defer rows.Close() - items := []map[string]any{} - for rows.Next() { - var id, workspaceID, workspaceKey, workspaceName, email string - var roles []string - var expiresAt, createdAt time.Time - var acceptedAt, revokedAt *time.Time - if rows.Scan(&id, &workspaceID, &workspaceKey, &workspaceName, &email, &roles, &expiresAt, &acceptedAt, &revokedAt, &createdAt) == nil { - items = append(items, workspaceInvitationResponse(id, workspaceID, workspaceKey, workspaceName, email, roles, expiresAt, acceptedAt, revokedAt, createdAt)) - } - } - kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) -} - -func (s *Server) acceptWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { - var request struct { - InvitationToken string `json:"invitation_token"` - } - if !kernel.DecodeJSON(w, r, &request) || request.InvitationToken == "" { - return - } - tx, err := s.app.DB.Begin(r.Context()) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The invitation could not be accepted.") - return - } - defer rollback(tx, r.Context()) - var workspaceID, invitedEmail string - var roleKeys []string - var credentialDigest []byte - err = tx.QueryRow(r.Context(), `SELECT workspace_id,normalized_email,roles,credential_digest FROM workspace_invitations -WHERE id=$1 AND application_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL AND expires_at>now() FOR UPDATE`, - chi.URLParam(r, "invitation_id"), chi.URLParam(r, "application_id")).Scan(&workspaceID, &invitedEmail, &roleKeys, &credentialDigest) - var userEmail string - if err == nil { - err = tx.QueryRow(r.Context(), `SELECT normalized_email FROM users WHERE id=$1 AND application_id=$2 AND status='active'`, - actor(r).ID, chi.URLParam(r, "application_id")).Scan(&userEmail) - } - if err != nil || userEmail != invitedEmail || !equalBytes(credentialDigest, s.app.Vault.Digest(request.InvitationToken)) { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_workspace_invitation", "The workspace invitation is invalid, expired, or belongs to another account.") - return - } - rows, err := tx.Query(r.Context(), `SELECT id FROM roles WHERE application_id=$1 AND scope='workspace' AND key=ANY($2)`, - chi.URLParam(r, "application_id"), roleKeys) - roleIDs := []string{} - if err == nil { - for rows.Next() { - var roleID string - if rows.Scan(&roleID) == nil { - roleIDs = append(roleIDs, roleID) - } - } - rows.Close() - } - if err != nil || len(roleIDs) != len(roleKeys) { - kernel.WriteProblem(w, r, http.StatusConflict, "workspace_invitation_roles_changed", "One or more invited roles are no longer available.") - return - } - _, err = tx.Exec(r.Context(), `INSERT INTO workspace_memberships(application_id,workspace_id,user_id) -VALUES($1,$2,$3) ON CONFLICT(workspace_id,user_id) DO NOTHING`, chi.URLParam(r, "application_id"), workspaceID, actor(r).ID) - for _, roleID := range roleIDs { - if err == nil { - _, err = tx.Exec(r.Context(), `INSERT INTO role_assignments(id,application_id,user_id,role_id,workspace_id) -VALUES ($1,$2,$3,$4,$5) ON CONFLICT DO NOTHING`, kernel.NewID(), chi.URLParam(r, "application_id"), actor(r).ID, roleID, workspaceID) - } - } - if err == nil { - _, err = tx.Exec(r.Context(), `UPDATE workspace_invitations SET accepted_at=now() WHERE id=$1`, chi.URLParam(r, "invitation_id")) - } - applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) - if err == nil && parseErr == nil { - _, err = s.app.Emit(r.Context(), tx, &applicationID, "workspace.invitation_accepted", "workspace_invitation/"+chi.URLParam(r, "invitation_id"), actor(r), - map[string]any{"invitation_id": chi.URLParam(r, "invitation_id"), "workspace_id": workspaceID, "user_id": actor(r).ID}) - } - if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "workspace_invitation_acceptance_failed", "The invitation acceptance could not be committed.") - return - } - kernel.WriteJSON(w, http.StatusOK, map[string]any{"workspace_id": workspaceID, "role_keys": roleKeys, "accepted": true}) -} - -func workspaceInvitationResponse(id, workspaceID, workspaceKey, workspaceName, email string, roles []string, expiresAt time.Time, acceptedAt, revokedAt *time.Time, createdAt time.Time) map[string]any { - status := "pending" - if acceptedAt != nil { - status = "accepted" - } else if revokedAt != nil { - status = "revoked" - } else if expiresAt.Before(time.Now()) { - status = "expired" - } - return map[string]any{"id": id, "workspace_id": workspaceID, "workspace_key": workspaceKey, "workspace_name": workspaceName, "email": email, - "role_keys": roles, "expires_at": expiresAt, "accepted_at": acceptedAt, "revoked_at": revokedAt, "created_at": createdAt, "status": status} -} - func uniqueStrings(values []string) []string { seen := map[string]bool{} result := make([]string, 0, len(values)) @@ -568,6 +330,23 @@ func uniqueStrings(values []string) []string { return result } +func validateRolePermissions(values []string) error { + if len(values) == 0 || len(values) > 200 { + return fmt.Errorf("permission count is invalid") + } + seen := make(map[string]struct{}, len(values)) + for _, permission := range values { + if err := platformauthz.ValidateRelativePermission(permission); err != nil { + return err + } + if _, exists := seen[permission]; exists { + return fmt.Errorf("permission is duplicated") + } + seen[permission] = struct{}{} + } + return nil +} + func (s *Server) listMyWorkspaces(w http.ResponseWriter, r *http.Request) { s.listWorkspaces(w, r) } @@ -580,41 +359,41 @@ func (s *Server) checkPermissions(w http.ResponseWriter, r *http.Request) { if !kernel.DecodeJSON(w, r, &request) || len(request.Permissions) == 0 || len(request.Permissions) > 100 { return } - rows, err := s.app.DB.Query(r.Context(), `SELECT ro.key,unnest(ro.permissions) FROM role_assignments ra -JOIN roles ro ON ro.id=ra.role_id WHERE ra.application_id=$1 AND ra.user_id=$2 -AND (ra.workspace_id IS NULL OR ra.workspace_id=$3)`, chi.URLParam(r, "application_id"), actor(r).ID, request.WorkspaceID) + applicationID, err := uuid.Parse(chi.URLParam(r, "application_id")) if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Permissions could not be evaluated.") + kernel.WriteProblem(w, r, http.StatusBadRequest, "invalid_application_id", "The application identifier is invalid.") return } - defer rows.Close() - sources := map[string][]string{} - for rows.Next() { - var role, permission string - if rows.Scan(&role, &permission) == nil { - sources[permission] = append(sources[permission], role) + access, err := s.userEffectiveAccess(r, applicationID, actor(r).ID) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "authorization_data_invalid", "Permissions could not be evaluated because the account authorization data is invalid.") + return + } + canonical := make([]string, len(request.Permissions)) + for index, permission := range request.Permissions { + if err = platformauthz.ValidateRelativePermission(permission); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission", "Permission checks require lowercase ASCII colon-delimited permission keys.") + return + } + canonical[index], err = platformauthz.CanonicalScope(applicationID.String(), request.WorkspaceID, permission) + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission", "The permission could not be evaluated in the selected workspace.") + return } } results := make([]map[string]any, 0, len(request.Permissions)) - for _, wanted := range request.Permissions { + for index, wanted := range canonical { matched := []string{} - for granted, roles := range sources { + for _, granted := range access.Scopes { if permissionMatches(granted, wanted) { - matched = append(matched, roles...) + matched = append(matched, granted) } } - results = append(results, map[string]any{"permission": wanted, "allowed": len(matched) > 0, "roles": matched}) + results = append(results, map[string]any{"permission": request.Permissions[index], "canonical_scope": wanted, "allowed": len(matched) > 0, "matched_scopes": matched}) } kernel.WriteJSON(w, http.StatusOK, map[string]any{"workspace_id": request.WorkspaceID, "results": results}) } func permissionMatches(granted, wanted string) bool { - if granted == wanted || granted == "*" { - return true - } - if !strings.HasSuffix(granted, "/*") { - return false - } - base := strings.TrimSuffix(granted, "/*") - return wanted == base || strings.HasPrefix(wanted, base+"/") + return platformauthz.Match(granted, wanted) } diff --git a/internal/httpapi/authorization_security_test.go b/internal/httpapi/authorization_security_test.go new file mode 100644 index 0000000..7107863 --- /dev/null +++ b/internal/httpapi/authorization_security_test.go @@ -0,0 +1,102 @@ +package httpapi + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/supaapps/platform93/internal/database" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/platform" + "github.com/supaapps/platform93/internal/secure" +) + +func TestRolePermissionInputRejectsScopeInjection(t *testing.T) { + server := &Server{} + for _, permission := range []string{"invoices:read billing:*", "invoices:read\tbilling:*", "members::read", "members:*:read", "members%20read", "../read", "mémbers:read"} { + request := requestWithRoute(t, http.MethodPost, "/", map[string]any{ + "key": "accountant", "name": "Accountant", "scope": "application", "permissions": []string{permission}, + }, map[string]string{"application_id": kernel.NewID().String()}, kernel.Actor{Type: "control_user"}) + response := httptest.NewRecorder() + server.createRole(response, request) + if response.Code != http.StatusUnprocessableEntity { + t.Fatalf("permission %q returned %d instead of 422", permission, response.Code) + } + } +} + +func TestPermissionGrantLifecycleAndDatabaseGuards(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, _ := secure.NewVault(make([]byte, 32)) + server := &Server{app: platform.New(db, vault, "https://platform93.test")} + organizationID, applicationID, userID := kernel.NewID(), kernel.NewID(), kernel.NewID() + suffix := applicationID.String() + for _, statement := range []struct { + query string + args []any + }{ + {`INSERT INTO organizations(id,name,slug) VALUES($1,'Authorization test',$2)`, []any{organizationID, "authorization-" + suffix}}, + {`INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'Authorization test',$3)`, []any{applicationID, organizationID, "authorization-" + suffix}}, + {`INSERT INTO users(id,application_id,email,normalized_email) VALUES($1,$2,$3,$3)`, []any{userID, applicationID, "user-" + suffix + "@example.test"}}, + } { + if _, err = db.Exec(context.Background(), statement.query, statement.args...); err != nil { + t.Fatal(err) + } + } + if _, err = db.Exec(context.Background(), `INSERT INTO roles(application_id,key,name,scope,permissions) VALUES($1,'bad','Bad','application',ARRAY['read write'])`, applicationID); err == nil { + t.Fatal("database accepted malformed role permission") + } + if _, err = db.Exec(context.Background(), `INSERT INTO personal_api_keys(application_id,user_id,token_prefix,token_digest,scopes,expires_at) VALUES($1,$2,'bad',$3,ARRAY[$4],now()+interval '1 day')`, applicationID, userID, []byte("digest"), "/applications/"+applicationID.String()+"/read write"); err == nil { + t.Fatal("database accepted malformed PAT scope") + } + if _, err = db.Exec(context.Background(), `INSERT INTO personal_api_keys(application_id,user_id,token_prefix,token_digest,scopes,expires_at) VALUES($1,$2,'root-wildcard',$3,ARRAY[$4],now()+interval '1 day')`, applicationID, userID, []byte("root-wildcard-"+suffix), "/applications/"+applicationID.String()+"/*"); err != nil { + t.Fatalf("database rejected canonical root wildcard: %v", err) + } + + create := requestWithRoute(t, http.MethodPost, "/", map[string]any{ + "subject_type": "user", "subject_id": userID, "permission": "invoices:read", "reason": "invoice review", + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "control_user", ID: kernel.NewID().String()}) + create.Header.Set("Idempotency-Key", kernel.NewID().String()) + response := httptest.NewRecorder() + server.createPermissionGrant(response, create) + if response.Code != http.StatusCreated { + t.Fatalf("grant creation returned %d: %s", response.Code, response.Body.String()) + } + var created map[string]any + if err = json.Unmarshal(response.Body.Bytes(), &created); err != nil { + t.Fatal(err) + } + wanted := "/applications/" + applicationID.String() + "/invoices/read" + access, err := server.userEffectiveAccess(create, applicationID, userID.String()) + if err != nil || !containsAllowedScope(access.Scopes, wanted) { + t.Fatalf("direct grant missing from effective access: %#v, %v", access.Scopes, err) + } + + revoke := requestWithRoute(t, http.MethodDelete, "/", nil, map[string]string{ + "application_id": applicationID.String(), "grant_id": created["id"].(string), + }, kernel.Actor{Type: "control_user", ID: kernel.NewID().String()}) + revoke.Header.Set("If-Match", `"v1"`) + response = httptest.NewRecorder() + server.revokePermissionGrant(response, revoke) + if response.Code != http.StatusNoContent { + t.Fatalf("grant revocation returned %d: %s", response.Code, response.Body.String()) + } + access, err = server.userEffectiveAccess(create, applicationID, userID.String()) + if err != nil || containsAllowedScope(access.Scopes, wanted) { + t.Fatalf("revoked direct grant remained effective: %#v, %v", access.Scopes, err) + } +} diff --git a/internal/httpapi/billing.go b/internal/httpapi/billing.go index e8c8c34..6b532c5 100644 --- a/internal/httpapi/billing.go +++ b/internal/httpapi/billing.go @@ -15,6 +15,7 @@ import ( "time" "github.com/go-chi/chi/v5" + "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/supaapps/platform93/internal/kernel" ) @@ -143,13 +144,14 @@ func (s *Server) writeBillingProviderPage(w http.ResponseWriter, r *http.Request func (s *Server) createCheckoutSession(w http.ResponseWriter, r *http.Request) { var request struct { - PriceID string `json:"price_id"` - SubjectType string `json:"subject_type"` - SubjectID string `json:"subject_id"` - ProviderID string `json:"provider_id"` - PaymentMethods []string `json:"payment_methods,omitempty"` - SuccessURI string `json:"success_uri"` - CancelURI string `json:"cancel_uri"` + PriceID string `json:"price_id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + ProviderID string `json:"provider_id"` + PaymentMethods []string `json:"payment_methods,omitempty"` + SuccessURI string `json:"success_uri"` + CancelURI string `json:"cancel_uri"` + ExternalReference *string `json:"external_reference,omitempty"` } if !kernel.DecodeJSON(w, r, &request) { return @@ -172,6 +174,10 @@ func (s *Server) createCheckoutSession(w http.ResponseWriter, r *http.Request) { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_subject", "Subject type must be user or workspace.") return } + if request.ExternalReference != nil && (len(*request.ExternalReference) > 255 || strings.TrimSpace(*request.ExternalReference) == "") { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_external_reference", "External reference must contain between 1 and 255 characters.") + return + } if !s.billingRedirectAllowed(r, request.SuccessURI) || !s.billingRedirectAllowed(r, request.CancelURI) { kernel.WriteProblem(w, r, 422, "redirect_not_allowed", "Checkout redirects must exactly match an enabled client redirect URI.") return @@ -202,7 +208,7 @@ WHERE pr.id=$1 AND pr.application_id=$3 AND pr.mode IN ('recurring','one_time') policy["payment_methods"] = request.PaymentMethods policyJSON, _ := json.Marshal(policy) sessionID := kernel.NewID() - _, err = s.app.DB.Exec(r.Context(), `INSERT INTO checkout_sessions (id,application_id,subject_type,subject_id,price_id,provider_connection_id,payment_methods,policy_snapshot,success_uri,cancel_uri) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, sessionID, chi.URLParam(r, "application_id"), request.SubjectType, request.SubjectID, request.PriceID, providerConnectionID, request.PaymentMethods, policyJSON, request.SuccessURI, request.CancelURI) + _, err = s.app.DB.Exec(r.Context(), `INSERT INTO checkout_sessions (id,application_id,subject_type,subject_id,price_id,provider_connection_id,payment_methods,policy_snapshot,success_uri,cancel_uri,external_reference) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)`, sessionID, chi.URLParam(r, "application_id"), request.SubjectType, request.SubjectID, request.PriceID, providerConnectionID, request.PaymentMethods, policyJSON, request.SuccessURI, request.CancelURI, request.ExternalReference) if err != nil { kernel.WriteProblem(w, r, 409, "checkout_creation_failed", "The checkout record could not be created.") return @@ -239,6 +245,9 @@ WHERE pr.id=$1 AND pr.application_id=$3 AND pr.mode IN ('recurring','one_time') form.Set("metadata[platform93_price_id]", request.PriceID) form.Set("metadata[platform93_subject_type]", request.SubjectType) form.Set("metadata[platform93_subject_id]", request.SubjectID) + if request.ExternalReference != nil { + form.Set("metadata[platform93_external_reference]", *request.ExternalReference) + } form.Set("customer", customerID) form.Set("line_items[0][quantity]", "1") form.Set("line_items[0][price]", providerPriceID) @@ -249,6 +258,9 @@ WHERE pr.id=$1 AND pr.application_id=$3 AND pr.mode IN ('recurring','one_time') form.Set("subscription_data[metadata][platform93_price_id]", request.PriceID) form.Set("subscription_data[metadata][platform93_subject_type]", request.SubjectType) form.Set("subscription_data[metadata][platform93_subject_id]", request.SubjectID) + if request.ExternalReference != nil { + form.Set("subscription_data[metadata][platform93_external_reference]", *request.ExternalReference) + } applyStripeTrialPolicy(form, policy) } if mode == "one_time" { @@ -258,6 +270,9 @@ WHERE pr.id=$1 AND pr.application_id=$3 AND pr.mode IN ('recurring','one_time') form.Set("payment_intent_data[metadata][platform93_price_id]", request.PriceID) form.Set("payment_intent_data[metadata][platform93_subject_type]", request.SubjectType) form.Set("payment_intent_data[metadata][platform93_subject_id]", request.SubjectID) + if request.ExternalReference != nil { + form.Set("payment_intent_data[metadata][platform93_external_reference]", *request.ExternalReference) + } } for index, method := range request.PaymentMethods { form.Set(fmt.Sprintf("payment_method_types[%d]", index), method) @@ -287,7 +302,7 @@ WHERE pr.id=$1 AND pr.application_id=$3 AND pr.mode IN ('recurring','one_time') kernel.WriteProblem(w, r, 500, "checkout_update_failed", "The provider checkout could not be saved.") return } - kernel.WriteJSON(w, 201, map[string]any{"id": sessionID, "status": "open", "checkout_uri": stripeSession.URL, "provider_session_id": stripeSession.ID}) + kernel.WriteJSON(w, 201, map[string]any{"id": sessionID, "status": "open", "checkout_uri": stripeSession.URL, "provider_session_id": stripeSession.ID, "external_reference": request.ExternalReference}) } func (s *Server) stripeWebhook(w http.ResponseWriter, r *http.Request) { @@ -538,7 +553,7 @@ func stripeRequest(ctx context.Context, method, uri, secret, version, idempotenc return body, nil } -func (s *Server) upsertProviderGrant(ctx context.Context, tx pgx.Tx, applicationID, subjectType, subjectID, productID, priceID, sourceType, sourceID string, expiresAt *time.Time, revoke bool) error { +func (s *Server) upsertProviderGrant(ctx context.Context, tx pgx.Tx, applicationID, subjectType, subjectID, productID, priceID, sourceType, sourceID string, externalReference *string, expiresAt *time.Time, revoke bool) error { var grantID string lookupErr := tx.QueryRow(ctx, `SELECT id FROM entitlement_grants WHERE application_id=$1 AND source_type=$2 AND source_id=$3 AND product_id=$4`, applicationID, sourceType, sourceID, productID).Scan(&grantID) @@ -563,14 +578,20 @@ WHERE application_id=$1 AND source_type=$2 AND source_id=$3 AND product_id=$4`, base = *expiresAt } expires := base.Add(time.Duration(graceSeconds) * time.Second) - _, err := tx.Exec(ctx, `INSERT INTO entitlement_grant_actions + result, err := tx.Exec(ctx, `INSERT INTO entitlement_grant_actions (id,grant_id,action,action_key,expires_at,reason,actor_type) VALUES($1,$2,'adjusted',$3,$4,'provider_access_ended','provider') ON CONFLICT(grant_id,action_key) DO NOTHING`, kernel.NewID(), grantID, "provider_ended_grace:"+marker, expires) + if err == nil && result.RowsAffected() == 1 { + err = s.emitProviderGrantEvents(ctx, tx, applicationID, "entitlement.adjusted", grantID, subjectType, subjectID, externalReference) + } return err } - _, err := tx.Exec(ctx, `INSERT INTO entitlement_grant_actions + result, err := tx.Exec(ctx, `INSERT INTO entitlement_grant_actions (id,grant_id,action,action_key,reason,actor_type) VALUES($1,$2,'revoked',$3,'provider_access_ended','provider') ON CONFLICT(grant_id,action_key) DO NOTHING`, kernel.NewID(), grantID, "provider_ended:"+marker) + if err == nil && result.RowsAffected() == 1 { + err = s.emitProviderGrantEvents(ctx, tx, applicationID, "entitlement.revoked", grantID, subjectType, subjectID, externalReference) + } return err } if lookupErr != nil && lookupErr != pgx.ErrNoRows { @@ -587,9 +608,12 @@ ON CONFLICT(grant_id,action_key) DO NOTHING`, kernel.NewID(), grantID, "provider if latestAction == "revoked" { action = "restored" } - _, err := tx.Exec(ctx, `INSERT INTO entitlement_grant_actions + result, err := tx.Exec(ctx, `INSERT INTO entitlement_grant_actions (id,grant_id,action,action_key,expires_at,reason,actor_type) VALUES($1,$2,$3,$4,$5,'provider_access_active','provider') ON CONFLICT(grant_id,action_key) DO NOTHING`, kernel.NewID(), grantID, action, "provider_active:"+marker, expiresAt) + if err == nil && result.RowsAffected() == 1 { + err = s.emitProviderGrantEvents(ctx, tx, applicationID, "entitlement."+action, grantID, subjectType, subjectID, externalReference) + } return err } features := map[string]any{} @@ -621,10 +645,38 @@ FROM price_features pf JOIN features f ON f.id=pf.feature_id WHERE pf.price_id=$ if err = tx.QueryRow(ctx, "SELECT entitlement_config FROM prices WHERE id=$1", priceID).Scan(&configuration); err != nil { return err } - _, err = tx.Exec(ctx, `INSERT INTO entitlement_grants -(id,application_id,subject_type,subject_id,product_id,price_id,source_type,source_id,feature_values,configuration,starts_at,expires_at) -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,now(),$11) -ON CONFLICT (application_id,source_type,source_id,product_id) WHERE source_id IS NOT NULL DO NOTHING`, kernel.NewID(), applicationID, subjectType, subjectID, productID, priceID, sourceType, sourceID, featuresJSON, configuration, expiresAt) + newGrantID := kernel.NewID() + var persistedGrantID string + var created bool + err = tx.QueryRow(ctx, `INSERT INTO entitlement_grants +(id,application_id,subject_type,subject_id,product_id,price_id,source_type,source_id,feature_values,configuration,starts_at,expires_at,external_reference) +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,now(),$11,$12) + ON CONFLICT (application_id,source_type,source_id,product_id) WHERE source_id IS NOT NULL DO UPDATE SET external_reference=COALESCE(EXCLUDED.external_reference,entitlement_grants.external_reference) +RETURNING id,(xmax=0)`, newGrantID, applicationID, subjectType, subjectID, productID, priceID, sourceType, sourceID, featuresJSON, configuration, expiresAt, externalReference).Scan(&persistedGrantID, &created) + if err == nil && created { + err = s.emitProviderGrantEvents(ctx, tx, applicationID, "entitlement.granted", persistedGrantID, subjectType, subjectID, externalReference) + } + return err +} + +func (s *Server) emitProviderGrantEvents(ctx context.Context, tx pgx.Tx, applicationID, eventType, grantID, subjectType, subjectID string, externalReference *string) error { + parsed, err := uuid.Parse(applicationID) + if err != nil { + return err + } + providerActor := map[string]any{"type": "provider"} + status := "active" + if eventType == "entitlement.revoked" { + status = "revoked" + } + data := map[string]any{"grant_id": grantID, "subject_type": subjectType, "subject_id": subjectID, "external_reference": externalReference, "status": status} + if eventType == "entitlement.granted" { + data["reason"] = "provider" + } + if _, err = s.app.Emit(ctx, tx, &parsed, eventType, "entitlement/"+grantID, providerActor, data); err != nil { + return err + } + _, err = s.app.Emit(ctx, tx, &parsed, "entitlement.effective_changed", subjectType+"/"+subjectID, providerActor, map[string]any{"grant_id": grantID, "subject_type": subjectType, "subject_id": subjectID, "external_reference": externalReference}) return err } func applyStripeCheckoutPolicy(form url.Values, policy map[string]any) { diff --git a/internal/httpapi/billing_lifecycle.go b/internal/httpapi/billing_lifecycle.go index b9fe257..e7157d2 100644 --- a/internal/httpapi/billing_lifecycle.go +++ b/internal/httpapi/billing_lifecycle.go @@ -170,17 +170,17 @@ func (s *Server) createPortalSession(w http.ResponseWriter, r *http.Request) { func (s *Server) getCheckoutSession(w http.ResponseWriter, r *http.Request) { var id, subjectType, subjectID, priceID, status, successURI, cancelURI string - var providerID, providerSessionID, checkoutURI *string + var providerID, providerSessionID, checkoutURI, externalReference *string var paymentMethods []string var policy []byte var createdAt, updatedAt time.Time err := s.app.DB.QueryRow(r.Context(), `SELECT id,subject_type,subject_id,price_id,provider_connection_id,provider_session_id, -status,payment_methods,policy_snapshot,success_uri,cancel_uri,checkout_uri,created_at,updated_at FROM checkout_sessions +status,payment_methods,policy_snapshot,success_uri,cancel_uri,checkout_uri,external_reference,created_at,updated_at FROM checkout_sessions WHERE id=$1 AND application_id=$2 AND ((subject_type='user' AND subject_id=$3) OR (subject_type='workspace' AND workspace_accessible_to_user(application_id,subject_id,$3)))`, chi.URLParam(r, "session_id"), chi.URLParam(r, "application_id"), actor(r).ID). Scan(&id, &subjectType, &subjectID, &priceID, &providerID, &providerSessionID, &status, &paymentMethods, &policy, - &successURI, &cancelURI, &checkoutURI, &createdAt, &updatedAt) + &successURI, &cancelURI, &checkoutURI, &externalReference, &createdAt, &updatedAt) if err != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "checkout_session_not_found", "The checkout session was not found.") return @@ -188,7 +188,7 @@ WHERE id=$1 AND application_id=$2 AND ((subject_type='user' AND subject_id=$3) O kernel.WriteJSON(w, http.StatusOK, map[string]any{"id": id, "subject_type": subjectType, "subject_id": subjectID, "price_id": priceID, "provider_id": providerID, "provider_session_id": providerSessionID, "status": status, "payment_methods": paymentMethods, "policy": decodeMap(policy), "success_uri": successURI, "cancel_uri": cancelURI, - "checkout_uri": checkoutURI, "created_at": createdAt, "updated_at": updatedAt}) + "checkout_uri": checkoutURI, "external_reference": externalReference, "created_at": createdAt, "updated_at": updatedAt}) } func (s *Server) listSubscriptions(w http.ResponseWriter, r *http.Request) { @@ -204,7 +204,7 @@ func (s *Server) writeSubscriptions(w http.ResponseWriter, r *http.Request, user filter = &userID } rows, err := s.app.DB.Query(r.Context(), `SELECT id,subject_type,subject_id,price_id,provider_connection_id,status, -current_period_start,current_period_end,cancel_at,canceled_at,trial_end,cancel_at_period_end,created_at,updated_at +current_period_start,current_period_end,cancel_at,canceled_at,trial_end,cancel_at_period_end,external_reference,created_at,updated_at FROM subscriptions s WHERE s.application_id=$1 AND ($2::uuid IS NULL OR s.subject_type='user' AND s.subject_id=$2::uuid OR s.subject_type='workspace' AND workspace_accessible_to_user(s.application_id,s.subject_id,$2::uuid)) @@ -219,11 +219,12 @@ ORDER BY created_at DESC,id DESC`, chi.URLParam(r, "application_id"), filter) var id, subjectType, subjectID, priceID, providerID, status string var periodStart, periodEnd, cancelAt, canceledAt, trialEnd *time.Time var cancelAtPeriodEnd bool + var externalReference *string var createdAt, updatedAt time.Time - if rows.Scan(&id, &subjectType, &subjectID, &priceID, &providerID, &status, &periodStart, &periodEnd, &cancelAt, &canceledAt, &trialEnd, &cancelAtPeriodEnd, &createdAt, &updatedAt) == nil { + if rows.Scan(&id, &subjectType, &subjectID, &priceID, &providerID, &status, &periodStart, &periodEnd, &cancelAt, &canceledAt, &trialEnd, &cancelAtPeriodEnd, &externalReference, &createdAt, &updatedAt) == nil { items = append(items, map[string]any{"id": id, "subject_type": subjectType, "subject_id": subjectID, "price_id": priceID, "provider_id": providerID, "status": status, "current_period_start": periodStart, "current_period_end": periodEnd, "cancel_at": cancelAt, "canceled_at": canceledAt, - "trial_end": trialEnd, "cancel_at_period_end": cancelAtPeriodEnd, "created_at": createdAt, "updated_at": updatedAt}) + "trial_end": trialEnd, "cancel_at_period_end": cancelAtPeriodEnd, "external_reference": externalReference, "created_at": createdAt, "updated_at": updatedAt}) } } kernel.WriteJSON(w, 200, map[string]any{"items": items, "next_cursor": nil}) @@ -233,18 +234,19 @@ func (s *Server) getSubscription(w http.ResponseWriter, r *http.Request) { var id, subjectType, subjectID, priceID, providerID, status string var periodStart, periodEnd, cancelAt, canceledAt, trialEnd *time.Time var cancelAtPeriodEnd bool + var externalReference *string var createdAt, updatedAt time.Time err := s.app.DB.QueryRow(r.Context(), `SELECT id,subject_type,subject_id,price_id,provider_connection_id,status, -current_period_start,current_period_end,cancel_at,canceled_at,trial_end,cancel_at_period_end,created_at,updated_at +current_period_start,current_period_end,cancel_at,canceled_at,trial_end,cancel_at_period_end,external_reference,created_at,updated_at FROM subscriptions WHERE id=$1 AND application_id=$2`, chi.URLParam(r, "subscription_id"), chi.URLParam(r, "application_id")). - Scan(&id, &subjectType, &subjectID, &priceID, &providerID, &status, &periodStart, &periodEnd, &cancelAt, &canceledAt, &trialEnd, &cancelAtPeriodEnd, &createdAt, &updatedAt) + Scan(&id, &subjectType, &subjectID, &priceID, &providerID, &status, &periodStart, &periodEnd, &cancelAt, &canceledAt, &trialEnd, &cancelAtPeriodEnd, &externalReference, &createdAt, &updatedAt) if err != nil { kernel.WriteProblem(w, r, 404, "subscription_not_found", "The subscription was not found.") return } kernel.WriteJSON(w, 200, map[string]any{"id": id, "subject_type": subjectType, "subject_id": subjectID, "price_id": priceID, "provider_id": providerID, "status": status, "current_period_start": periodStart, "current_period_end": periodEnd, "cancel_at": cancelAt, "canceled_at": canceledAt, - "trial_end": trialEnd, "cancel_at_period_end": cancelAtPeriodEnd, "created_at": createdAt, "updated_at": updatedAt}) + "trial_end": trialEnd, "cancel_at_period_end": cancelAtPeriodEnd, "external_reference": externalReference, "created_at": createdAt, "updated_at": updatedAt}) } func (s *Server) cancelSubscription(w http.ResponseWriter, r *http.Request) { @@ -383,7 +385,7 @@ func (s *Server) writeInvoices(w http.ResponseWriter, r *http.Request, userID st filter = &userID } rows, err := s.app.DB.Query(r.Context(), `SELECT i.id,i.provider_connection_id,i.provider_invoice_id,i.subscription_id,i.status, -i.amount_due_minor,i.amount_paid_minor,i.tax_minor,i.currency,i.due_at,i.paid_at,i.hosted_uri,i.created_at,i.updated_at +i.amount_due_minor,i.amount_paid_minor,i.tax_minor,i.currency,i.due_at,i.paid_at,i.hosted_uri,i.external_reference,i.created_at,i.updated_at FROM invoices i LEFT JOIN billing_customers bc ON bc.id=i.billing_customer_id WHERE i.application_id=$1 AND ($2::uuid IS NULL OR bc.subject_type='user' AND bc.subject_id=$2::uuid OR bc.subject_type='workspace' AND workspace_accessible_to_user(i.application_id,bc.subject_id,$2::uuid)) @@ -396,14 +398,14 @@ ORDER BY i.created_at DESC,i.id DESC`, chi.URLParam(r, "application_id"), filter items := []map[string]any{} for rows.Next() { var id, providerID, providerInvoiceID, status, currency string - var subscriptionID, hostedURI *string + var subscriptionID, hostedURI, externalReference *string var dueAt, paidAt *time.Time var due, paid, tax int64 var createdAt, updatedAt time.Time - if rows.Scan(&id, &providerID, &providerInvoiceID, &subscriptionID, &status, &due, &paid, &tax, ¤cy, &dueAt, &paidAt, &hostedURI, &createdAt, &updatedAt) == nil { + if rows.Scan(&id, &providerID, &providerInvoiceID, &subscriptionID, &status, &due, &paid, &tax, ¤cy, &dueAt, &paidAt, &hostedURI, &externalReference, &createdAt, &updatedAt) == nil { items = append(items, map[string]any{"id": id, "provider_id": providerID, "provider_invoice_id": providerInvoiceID, "subscription_id": subscriptionID, "status": status, "amount_due_minor": due, "amount_paid_minor": paid, "tax_minor": tax, "currency": currency, "due_at": dueAt, "paid_at": paidAt, - "hosted_uri": hostedURI, "created_at": createdAt, "updated_at": updatedAt}) + "hosted_uri": hostedURI, "external_reference": externalReference, "created_at": createdAt, "updated_at": updatedAt}) } } kernel.WriteJSON(w, 200, map[string]any{"items": items, "next_cursor": nil}) @@ -419,7 +421,7 @@ func (s *Server) writePayments(w http.ResponseWriter, r *http.Request, userID st filter = &userID } rows, err := s.app.DB.Query(r.Context(), `SELECT p.id,p.provider_connection_id,p.provider_payment_id,p.checkout_session_id,p.invoice_id, -p.status,p.amount_minor,p.amount_received_minor,p.currency,p.payment_method_type,p.failure_code,p.failure_message,p.created_at,p.updated_at +p.status,p.amount_minor,p.amount_received_minor,p.currency,p.payment_method_type,p.failure_code,p.failure_message,p.external_reference,p.created_at,p.updated_at FROM payments p LEFT JOIN billing_customers bc ON bc.id=p.billing_customer_id WHERE p.application_id=$1 AND ($2::uuid IS NULL OR bc.subject_type='user' AND bc.subject_id=$2::uuid OR bc.subject_type='workspace' AND workspace_accessible_to_user(p.application_id,bc.subject_id,$2::uuid)) @@ -432,13 +434,13 @@ ORDER BY p.created_at DESC,p.id DESC`, chi.URLParam(r, "application_id"), filter items := []map[string]any{} for rows.Next() { var id, providerID, providerPaymentID, status, currency string - var checkoutID, invoiceID, method, failureCode, failureMessage *string + var checkoutID, invoiceID, method, failureCode, failureMessage, externalReference *string var amount, received int64 var createdAt, updatedAt time.Time - if rows.Scan(&id, &providerID, &providerPaymentID, &checkoutID, &invoiceID, &status, &amount, &received, ¤cy, &method, &failureCode, &failureMessage, &createdAt, &updatedAt) == nil { + if rows.Scan(&id, &providerID, &providerPaymentID, &checkoutID, &invoiceID, &status, &amount, &received, ¤cy, &method, &failureCode, &failureMessage, &externalReference, &createdAt, &updatedAt) == nil { items = append(items, map[string]any{"id": id, "provider_id": providerID, "provider_payment_id": providerPaymentID, "checkout_session_id": checkoutID, "invoice_id": invoiceID, "status": status, "amount_minor": amount, "amount_received_minor": received, "currency": currency, - "payment_method_type": method, "failure_code": failureCode, "failure_message": failureMessage, "created_at": createdAt, "updated_at": updatedAt}) + "payment_method_type": method, "failure_code": failureCode, "failure_message": failureMessage, "external_reference": externalReference, "created_at": createdAt, "updated_at": updatedAt}) } } kernel.WriteJSON(w, 200, map[string]any{"items": items, "next_cursor": nil}) diff --git a/internal/httpapi/billing_profiles.go b/internal/httpapi/billing_profiles.go index db1a2ea..52ae9d0 100644 --- a/internal/httpapi/billing_profiles.go +++ b/internal/httpapi/billing_profiles.go @@ -50,8 +50,8 @@ func (s *Server) canManageWorkspaceBilling(r *http.Request) bool { } func (s *Server) canManageWorkspaceBillingFor(r *http.Request, workspaceID string) bool { - if actor(r).Type == "operator" || s.isWorkspaceOwnerOrOperator(r) { - if actor(r).Type == "operator" { + if actor(r).Type == "control_user" || s.isWorkspaceOwnerOrControlUser(r) { + if actor(r).Type == "control_user" { return true } var owner bool diff --git a/internal/httpapi/billing_stripe_events.go b/internal/httpapi/billing_stripe_events.go index 3a31604..758348a 100644 --- a/internal/httpapi/billing_stripe_events.go +++ b/internal/httpapi/billing_stripe_events.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "github.com/google/uuid" "github.com/supaapps/platform93/internal/kernel" ) @@ -28,11 +29,12 @@ func (s *Server) normalizeStripeCheckout(ctx context.Context, applicationID, con } defer tx.Rollback(ctx) var mode, subjectType, subjectID, productID, priceID string + var externalReference *string var validity *int64 err = tx.QueryRow(ctx, `UPDATE checkout_sessions c SET status=$1,provider_session_id=COALESCE(NULLIF($2,''),provider_session_id),updated_at=now() FROM prices pr WHERE c.id=$3 AND c.application_id=$4 AND pr.id=c.price_id -RETURNING pr.mode,c.subject_type,c.subject_id,pr.product_id,pr.id,pr.validity_seconds`, status, stringValue(object["id"]), checkoutID, applicationID). - Scan(&mode, &subjectType, &subjectID, &productID, &priceID, &validity) +RETURNING pr.mode,c.subject_type,c.subject_id,pr.product_id,pr.id,pr.validity_seconds,c.external_reference`, status, stringValue(object["id"]), checkoutID, applicationID). + Scan(&mode, &subjectType, &subjectID, &productID, &priceID, &validity, &externalReference) if err != nil { return fmt.Errorf("resolve checkout %s: %w", checkoutID, err) } @@ -44,7 +46,7 @@ RETURNING pr.mode,c.subject_type,c.subject_id,pr.product_id,pr.id,pr.validity_se value := s.app.Now().Add(time.Duration(*validity) * time.Second) expires = &value } - if err = s.upsertProviderGrant(ctx, tx, applicationID, subjectType, subjectID, productID, priceID, "one_time", checkoutID, expires, false); err != nil { + if err = s.upsertProviderGrant(ctx, tx, applicationID, subjectType, subjectID, productID, priceID, "one_time", checkoutID, externalReference, expires, false); err != nil { return err } } @@ -59,10 +61,11 @@ func (s *Server) normalizeStripeSubscription(ctx context.Context, applicationID, } checkoutID := metadataString(object, "platform93_checkout_id") var subjectType, subjectID, priceID string + var externalReference *string if checkoutID != "" { - _ = s.app.DB.QueryRow(ctx, `SELECT subject_type,subject_id,price_id FROM checkout_sessions + _ = s.app.DB.QueryRow(ctx, `SELECT subject_type,subject_id,price_id,external_reference FROM checkout_sessions WHERE id=$1 AND application_id=$2 AND provider_connection_id=$3`, checkoutID, applicationID, connectionID). - Scan(&subjectType, &subjectID, &priceID) + Scan(&subjectType, &subjectID, &priceID, &externalReference) } if priceID == "" { _ = s.app.DB.QueryRow(ctx, `SELECT subject_type,subject_id,price_id FROM subscriptions @@ -98,15 +101,15 @@ WHERE provider_connection_id=$1 AND provider_subscription_id=$2`, connectionID, var subscriptionID, productID string err = tx.QueryRow(ctx, `INSERT INTO subscriptions (id,application_id,subject_type,subject_id,price_id,provider_connection_id,provider_subscription_id,provider_item_id,status, -current_period_start,current_period_end,cancel_at,canceled_at,trial_end,cancel_at_period_end,metadata) -VALUES($1,$2,$3,$4,$5,$6,$7,NULLIF($8,''),$9,$10,$11,$12,$13,$14,$15,$16) +current_period_start,current_period_end,cancel_at,canceled_at,trial_end,cancel_at_period_end,metadata,external_reference) +VALUES($1,$2,$3,$4,$5,$6,$7,NULLIF($8,''),$9,$10,$11,$12,$13,$14,$15,$16,$17) ON CONFLICT(provider_connection_id,provider_subscription_id) DO UPDATE SET price_id=EXCLUDED.price_id,provider_item_id=COALESCE(EXCLUDED.provider_item_id,subscriptions.provider_item_id),status=EXCLUDED.status, current_period_start=EXCLUDED.current_period_start,current_period_end=EXCLUDED.current_period_end,cancel_at=EXCLUDED.cancel_at, canceled_at=EXCLUDED.canceled_at,trial_end=EXCLUDED.trial_end,cancel_at_period_end=EXCLUDED.cancel_at_period_end, -metadata=EXCLUDED.metadata,updated_at=now() RETURNING id`, kernel.NewID(), applicationID, subjectType, subjectID, priceID, +metadata=EXCLUDED.metadata,external_reference=COALESCE(EXCLUDED.external_reference,subscriptions.external_reference),updated_at=now() RETURNING id`, kernel.NewID(), applicationID, subjectType, subjectID, priceID, connectionID, providerSubscriptionID, providerItemID, status, periodStart, periodEnd, unixTimeValue(object["cancel_at"]), - unixTimeValue(object["canceled_at"]), unixTimeValue(object["trial_end"]), boolValue(object["cancel_at_period_end"]), metadata). + unixTimeValue(object["canceled_at"]), unixTimeValue(object["trial_end"]), boolValue(object["cancel_at_period_end"]), metadata, externalReference). Scan(&subscriptionID) if err == nil { err = tx.QueryRow(ctx, `SELECT product_id FROM prices WHERE id=$1 AND application_id=$2`, priceID, applicationID).Scan(&productID) @@ -115,11 +118,24 @@ metadata=EXCLUDED.metadata,updated_at=now() RETURNING id`, kernel.NewID(), appli return err } active := status == "active" || status == "trialing" || status == "past_due" - if err = s.upsertProviderGrant(ctx, tx, applicationID, subjectType, subjectID, productID, priceID, "subscription", subscriptionID, periodEnd, !active); err != nil { + if err = s.upsertProviderGrant(ctx, tx, applicationID, subjectType, subjectID, productID, priceID, "subscription", subscriptionID, externalReference, periodEnd, !active); err != nil { + return err + } + if _, err = tx.Exec(ctx, `UPDATE invoices SET subscription_id=$1, +external_reference=COALESCE(external_reference,$4),updated_at=now() +WHERE provider_connection_id=$2 AND provider_subscription_id=$3 +AND (subscription_id IS NULL OR external_reference IS NULL)`, subscriptionID, connectionID, providerSubscriptionID, externalReference); err != nil { return err } - if _, err = tx.Exec(ctx, `UPDATE invoices SET subscription_id=$1,updated_at=now() -WHERE provider_connection_id=$2 AND provider_subscription_id=$3 AND subscription_id IS NULL`, subscriptionID, connectionID, providerSubscriptionID); err != nil { + if _, err = tx.Exec(ctx, `UPDATE payments p SET external_reference=COALESCE(p.external_reference,i.external_reference),updated_at=now() +FROM invoices i WHERE p.invoice_id=i.id AND i.subscription_id=$1 AND p.external_reference IS NULL`, subscriptionID); err != nil { + return err + } + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if parseErr != nil { + return parseErr + } + if _, err = s.app.Emit(ctx, tx, &parsedApplicationID, "billing.subscription.updated", "subscription/"+subscriptionID, map[string]any{"type": "provider"}, map[string]any{"subscription_id": subscriptionID, "status": status, "subject_type": subjectType, "subject_id": subjectID, "external_reference": externalReference}); err != nil { return err } return tx.Commit(ctx) @@ -141,26 +157,47 @@ func (s *Server) normalizeStripeInvoice(ctx context.Context, applicationID, conn status = "draft" } providerCustomerID := stripeObjectID(object["customer"]) - _, err := s.app.DB.Exec(ctx, `INSERT INTO invoices + externalReference := metadataString(object, "platform93_external_reference") + if externalReference == "" && subscriptionID != nil { + _ = s.app.DB.QueryRow(ctx, `SELECT COALESCE(external_reference,'') FROM subscriptions WHERE id=$1`, *subscriptionID).Scan(&externalReference) + } + tx, err := s.app.DB.Begin(ctx) + if err != nil { + return err + } + defer tx.Rollback(ctx) + var invoiceID string + err = tx.QueryRow(ctx, `INSERT INTO invoices (id,application_id,provider_connection_id,provider_invoice_id,provider_customer_id,provider_subscription_id,billing_customer_id,subscription_id,status, -amount_due_minor,amount_paid_minor,tax_minor,currency,due_at,paid_at,hosted_uri) -VALUES($1,$2,$3,$4,NULLIF($5,''),NULLIF($6,''),$7,$8,$9,$10,$11,$12,upper($13),$14,$15,NULLIF($16,'')) +amount_due_minor,amount_paid_minor,tax_minor,currency,due_at,paid_at,hosted_uri,external_reference) +VALUES($1,$2,$3,$4,NULLIF($5,''),NULLIF($6,''),$7,$8,$9,$10,$11,$12,upper($13),$14,$15,NULLIF($16,''),NULLIF($17,'')) ON CONFLICT(provider_connection_id,provider_invoice_id) DO UPDATE SET provider_customer_id=COALESCE(EXCLUDED.provider_customer_id,invoices.provider_customer_id), provider_subscription_id=COALESCE(EXCLUDED.provider_subscription_id,invoices.provider_subscription_id), billing_customer_id=COALESCE(EXCLUDED.billing_customer_id,invoices.billing_customer_id), subscription_id=COALESCE(EXCLUDED.subscription_id,invoices.subscription_id),status=EXCLUDED.status, amount_due_minor=EXCLUDED.amount_due_minor,amount_paid_minor=EXCLUDED.amount_paid_minor,tax_minor=EXCLUDED.tax_minor, -currency=EXCLUDED.currency,due_at=EXCLUDED.due_at,paid_at=EXCLUDED.paid_at,hosted_uri=EXCLUDED.hosted_uri,updated_at=now()`, +currency=EXCLUDED.currency,due_at=EXCLUDED.due_at,paid_at=EXCLUDED.paid_at,hosted_uri=EXCLUDED.hosted_uri, +external_reference=COALESCE(EXCLUDED.external_reference,invoices.external_reference),updated_at=now() RETURNING id`, kernel.NewID(), applicationID, connectionID, providerInvoiceID, providerCustomerID, providerSubscriptionID, customerID, subscriptionID, status, int64Number(object["amount_due"]), int64Number(object["amount_paid"]), stripeTaxAmount(object), normalizedCurrency(object["currency"]), - unixTimeValue(object["due_date"]), unixTimeValue(nestedValue(object, "status_transitions", "paid_at")), stringValue(object["hosted_invoice_url"])) + unixTimeValue(object["due_date"]), unixTimeValue(nestedValue(object, "status_transitions", "paid_at")), stringValue(object["hosted_invoice_url"]), externalReference).Scan(&invoiceID) if err == nil { - _, err = s.app.DB.Exec(ctx, `UPDATE payments p SET invoice_id=i.id,updated_at=now() FROM invoices i + _, err = tx.Exec(ctx, `UPDATE payments p SET invoice_id=i.id,external_reference=COALESCE(p.external_reference,i.external_reference),updated_at=now() FROM invoices i WHERE i.provider_connection_id=$1 AND i.provider_invoice_id=$2 AND p.provider_connection_id=i.provider_connection_id AND p.provider_invoice_id=i.provider_invoice_id AND p.invoice_id IS NULL`, connectionID, providerInvoiceID) } - return err + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(ctx, tx, &parsedApplicationID, "billing.invoice.updated", "invoice/"+invoiceID, map[string]any{"type": "provider"}, map[string]any{"invoice_id": invoiceID, "status": status, "external_reference": nullableString(externalReference)}) + } + if err != nil { + return err + } + if parseErr != nil { + return parseErr + } + return tx.Commit(ctx) } func (s *Server) normalizeStripePayment(ctx context.Context, applicationID, connectionID string, object map[string]any) error { @@ -178,31 +215,54 @@ func (s *Server) normalizeStripePayment(ctx context.Context, applicationID, conn } failureCode := stringValue(nestedValue(object, "last_payment_error", "code")) failureMessage := stringValue(nestedValue(object, "last_payment_error", "message")) - _, err := s.app.DB.Exec(ctx, `INSERT INTO payments + externalReference := metadataString(object, "platform93_external_reference") + if externalReference == "" && checkoutID != nil { + _ = s.app.DB.QueryRow(ctx, `SELECT COALESCE(external_reference,'') FROM checkout_sessions WHERE id=$1`, *checkoutID).Scan(&externalReference) + } + if externalReference == "" && invoiceID != nil { + _ = s.app.DB.QueryRow(ctx, `SELECT COALESCE(external_reference,'') FROM invoices WHERE id=$1`, *invoiceID).Scan(&externalReference) + } + tx, err := s.app.DB.Begin(ctx) + if err != nil { + return err + } + defer tx.Rollback(ctx) + var paymentID string + err = tx.QueryRow(ctx, `INSERT INTO payments (id,application_id,provider_connection_id,provider_payment_id,provider_customer_id,provider_invoice_id,billing_customer_id,checkout_session_id,invoice_id,status, -amount_minor,amount_received_minor,currency,payment_method_type,failure_code,failure_message) -VALUES($1,$2,$3,$4,NULLIF($5,''),NULLIF($6,''),$7,$8,$9,$10,$11,$12,upper($13),NULLIF($14,''),NULLIF($15,''),NULLIF($16,'')) +amount_minor,amount_received_minor,currency,payment_method_type,failure_code,failure_message,external_reference) +VALUES($1,$2,$3,$4,NULLIF($5,''),NULLIF($6,''),$7,$8,$9,$10,$11,$12,upper($13),NULLIF($14,''),NULLIF($15,''),NULLIF($16,''),NULLIF($17,'')) ON CONFLICT(provider_connection_id,provider_payment_id) DO UPDATE SET provider_customer_id=COALESCE(EXCLUDED.provider_customer_id,payments.provider_customer_id), provider_invoice_id=COALESCE(EXCLUDED.provider_invoice_id,payments.provider_invoice_id), billing_customer_id=COALESCE(EXCLUDED.billing_customer_id,payments.billing_customer_id), checkout_session_id=COALESCE(EXCLUDED.checkout_session_id,payments.checkout_session_id),invoice_id=COALESCE(EXCLUDED.invoice_id,payments.invoice_id), -status=EXCLUDED.status,amount_minor=EXCLUDED.amount_minor,amount_received_minor=EXCLUDED.amount_received_minor, +status=EXCLUDED.status,amount_minor=EXCLUDED.amount_minor,amount_received_minor=EXCLUDED.amount_received_minor,external_reference=COALESCE(EXCLUDED.external_reference,payments.external_reference), currency=EXCLUDED.currency,payment_method_type=EXCLUDED.payment_method_type,failure_code=EXCLUDED.failure_code, -failure_message=EXCLUDED.failure_message,updated_at=now()`, kernel.NewID(), applicationID, connectionID, providerPaymentID, +failure_message=EXCLUDED.failure_message,updated_at=now() RETURNING id`, kernel.NewID(), applicationID, connectionID, providerPaymentID, providerCustomerID, providerInvoiceID, s.billingCustomerID(ctx, connectionID, providerCustomerID), checkoutID, invoiceID, stringValue(object["status"]), - int64Number(object["amount"]), int64Number(object["amount_received"]), normalizedCurrency(object["currency"]), method, failureCode, failureMessage) + int64Number(object["amount"]), int64Number(object["amount_received"]), normalizedCurrency(object["currency"]), method, failureCode, failureMessage, externalReference).Scan(&paymentID) if err == nil { - _, err = s.app.DB.Exec(ctx, `UPDATE refunds r SET payment_id=p.id,updated_at=now() FROM payments p + _, err = tx.Exec(ctx, `UPDATE refunds r SET payment_id=p.id,updated_at=now() FROM payments p WHERE p.provider_connection_id=$1 AND p.provider_payment_id=$2 AND r.provider_connection_id=p.provider_connection_id AND r.provider_payment_id=p.provider_payment_id AND r.payment_id IS NULL`, connectionID, providerPaymentID) } if err == nil { - _, err = s.app.DB.Exec(ctx, `UPDATE disputes d SET payment_id=p.id,updated_at=now() FROM payments p + _, err = tx.Exec(ctx, `UPDATE disputes d SET payment_id=p.id,updated_at=now() FROM payments p WHERE p.provider_connection_id=$1 AND p.provider_payment_id=$2 AND d.provider_connection_id=p.provider_connection_id AND d.provider_payment_id=p.provider_payment_id AND d.payment_id IS NULL`, connectionID, providerPaymentID) } - return err + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(ctx, tx, &parsedApplicationID, "billing.payment.updated", "payment/"+paymentID, map[string]any{"type": "provider"}, map[string]any{"payment_id": paymentID, "status": stringValue(object["status"]), "external_reference": nullableString(externalReference)}) + } + if err != nil { + return err + } + if parseErr != nil { + return parseErr + } + return tx.Commit(ctx) } func (s *Server) normalizeStripeRefund(ctx context.Context, applicationID, connectionID string, object map[string]any) error { @@ -212,14 +272,34 @@ func (s *Server) normalizeStripeRefund(ctx context.Context, applicationID, conne } paymentID := s.paymentID(ctx, connectionID, stripeObjectID(object["payment_intent"])) providerPaymentID := stripeObjectID(object["payment_intent"]) - _, err := s.app.DB.Exec(ctx, `INSERT INTO refunds + tx, err := s.app.DB.Begin(ctx) + if err != nil { + return err + } + defer tx.Rollback(ctx) + var refundID string + err = tx.QueryRow(ctx, `INSERT INTO refunds (id,application_id,provider_connection_id,provider_payment_id,payment_id,provider_refund_id,status,amount_minor,currency,reason) VALUES($1,$2,$3,NULLIF($4,''),$5,$6,$7,$8,upper($9),NULLIF($10,'')) ON CONFLICT(provider_connection_id,provider_refund_id) DO UPDATE SET provider_payment_id=COALESCE(EXCLUDED.provider_payment_id,refunds.provider_payment_id), payment_id=COALESCE(EXCLUDED.payment_id,refunds.payment_id),status=EXCLUDED.status,amount_minor=EXCLUDED.amount_minor, -currency=EXCLUDED.currency,reason=EXCLUDED.reason,updated_at=now()`, kernel.NewID(), applicationID, connectionID, providerPaymentID, paymentID, - providerRefundID, stringValue(object["status"]), int64Number(object["amount"]), normalizedCurrency(object["currency"]), stringValue(object["reason"])) - return err +currency=EXCLUDED.currency,reason=EXCLUDED.reason,updated_at=now() RETURNING id`, kernel.NewID(), applicationID, connectionID, providerPaymentID, paymentID, + providerRefundID, stringValue(object["status"]), int64Number(object["amount"]), normalizedCurrency(object["currency"]), stringValue(object["reason"])).Scan(&refundID) + var externalReference string + if err == nil && paymentID != nil { + _ = tx.QueryRow(ctx, `SELECT COALESCE(external_reference,'') FROM payments WHERE id=$1`, *paymentID).Scan(&externalReference) + } + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(ctx, tx, &parsedApplicationID, "billing.refund.updated", "refund/"+refundID, map[string]any{"type": "provider"}, map[string]any{"refund_id": refundID, "status": stringValue(object["status"]), "external_reference": nullableString(externalReference)}) + } + if err != nil { + return err + } + if parseErr != nil { + return parseErr + } + return tx.Commit(ctx) } func (s *Server) normalizeStripeDispute(ctx context.Context, applicationID, connectionID string, object map[string]any) error { @@ -231,15 +311,36 @@ func (s *Server) normalizeStripeDispute(ctx context.Context, applicationID, conn if providerPaymentID == "" { providerPaymentID = stripeObjectID(nestedValue(object, "charge", "payment_intent")) } - _, err := s.app.DB.Exec(ctx, `INSERT INTO disputes + paymentID := s.paymentID(ctx, connectionID, providerPaymentID) + tx, err := s.app.DB.Begin(ctx) + if err != nil { + return err + } + defer tx.Rollback(ctx) + var disputeID string + err = tx.QueryRow(ctx, `INSERT INTO disputes (id,application_id,provider_connection_id,provider_payment_id,payment_id,provider_dispute_id,status,amount_minor,currency,reason,evidence_due_at) VALUES($1,$2,$3,NULLIF($4,''),$5,$6,$7,$8,upper($9),NULLIF($10,''),$11) ON CONFLICT(provider_connection_id,provider_dispute_id) DO UPDATE SET provider_payment_id=COALESCE(EXCLUDED.provider_payment_id,disputes.provider_payment_id), payment_id=COALESCE(EXCLUDED.payment_id,disputes.payment_id),status=EXCLUDED.status,amount_minor=EXCLUDED.amount_minor, -currency=EXCLUDED.currency,reason=EXCLUDED.reason,evidence_due_at=EXCLUDED.evidence_due_at,updated_at=now()`, kernel.NewID(), applicationID, - connectionID, providerPaymentID, s.paymentID(ctx, connectionID, providerPaymentID), providerDisputeID, stringValue(object["status"]), - int64Number(object["amount"]), normalizedCurrency(object["currency"]), stringValue(object["reason"]), unixTimeValue(nestedValue(object, "evidence_details", "due_by"))) - return err +currency=EXCLUDED.currency,reason=EXCLUDED.reason,evidence_due_at=EXCLUDED.evidence_due_at,updated_at=now() RETURNING id`, kernel.NewID(), applicationID, + connectionID, providerPaymentID, paymentID, providerDisputeID, stringValue(object["status"]), + int64Number(object["amount"]), normalizedCurrency(object["currency"]), stringValue(object["reason"]), unixTimeValue(nestedValue(object, "evidence_details", "due_by"))).Scan(&disputeID) + var externalReference string + if err == nil && paymentID != nil { + _ = tx.QueryRow(ctx, `SELECT COALESCE(external_reference,'') FROM payments WHERE id=$1`, *paymentID).Scan(&externalReference) + } + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(ctx, tx, &parsedApplicationID, "billing.dispute.updated", "dispute/"+disputeID, map[string]any{"type": "provider"}, map[string]any{"dispute_id": disputeID, "status": stringValue(object["status"]), "external_reference": nullableString(externalReference)}) + } + if err != nil { + return err + } + if parseErr != nil { + return parseErr + } + return tx.Commit(ctx) } func (s *Server) billingCustomerID(ctx context.Context, connectionID, providerID string) *string { diff --git a/internal/httpapi/billing_stripe_events_test.go b/internal/httpapi/billing_stripe_events_test.go index d267b09..2991a63 100644 --- a/internal/httpapi/billing_stripe_events_test.go +++ b/internal/httpapi/billing_stripe_events_test.go @@ -37,6 +37,7 @@ func TestStripeEventsNormalizeOutOfOrder(t *testing.T) { productID, priceID, connectionID := kernel.NewID(), kernel.NewID(), kernel.NewID() customerID, checkoutID, subjectID := kernel.NewID(), kernel.NewID(), kernel.NewID() suffix := applicationID.String() + externalReference := "stripe-order-" + suffix providerCiphertext, err := vault.Encrypt([]byte("sk_test"), "billing-provider:"+connectionID.String()+":secret") if err != nil { t.Fatal(err) @@ -52,7 +53,7 @@ func TestStripeEventsNormalizeOutOfOrder(t *testing.T) { {`INSERT INTO prices(id,application_id,product_id,key,mode,amount_minor,currency,interval_unit,interval_count) VALUES($1,$2,$3,$4,'recurring',1000,'CHF','month',1)`, []any{priceID, applicationID, productID, "price-" + suffix}}, {`INSERT INTO provider_connections(id,application_id,provider,public_id,api_version,secret_ciphertext) VALUES($1,$2,'stripe',$3,$4,$5)`, []any{connectionID, applicationID, "stripe_" + suffix, stripeAPIVersion, providerCiphertext}}, {`INSERT INTO billing_customers(id,application_id,subject_type,subject_id,provider_connection_id,provider_customer_id) VALUES($1,$2,'user',$3,$4,'cus_test')`, []any{customerID, applicationID, subjectID, connectionID}}, - {`INSERT INTO checkout_sessions(id,application_id,subject_type,subject_id,price_id,provider_connection_id,status,policy_snapshot,success_uri,cancel_uri) VALUES($1,$2,'user',$3,$4,$5,'open','{}','https://app.test/success','https://app.test/cancel')`, []any{checkoutID, applicationID, subjectID, priceID, connectionID}}, + {`INSERT INTO checkout_sessions(id,application_id,subject_type,subject_id,price_id,provider_connection_id,status,policy_snapshot,success_uri,cancel_uri,external_reference) VALUES($1,$2,'user',$3,$4,$5,'open','{}','https://app.test/success','https://app.test/cancel',$6)`, []any{checkoutID, applicationID, subjectID, priceID, connectionID, externalReference}}, } for _, statement := range statements { if _, err = db.Exec(ctx, statement.query, statement.args...); err != nil { @@ -103,6 +104,17 @@ func TestStripeEventsNormalizeOutOfOrder(t *testing.T) { }); err != nil { t.Fatal(err) } + if err = server.normalizeStripeRefund(ctx, applicationID.String(), connectionID.String(), map[string]any{ + "id": "re_test", "payment_intent": "pi_test", "status": "succeeded", "amount": float64(500), "currency": "chf", + }); err != nil { + t.Fatal(err) + } + if err = server.normalizeStripeDispute(ctx, applicationID.String(), connectionID.String(), map[string]any{ + "id": "dp_test", "payment_intent": "pi_test", "status": "needs_response", "amount": float64(1000), "currency": "chf", + "evidence_details": map[string]any{"due_by": float64(1_900_000_000)}, + }); err != nil { + t.Fatal(err) + } var refundLinked, disputeLinked, paymentInvoiceLinked, invoiceSubscriptionLinked bool if err = db.QueryRow(ctx, `SELECT @@ -126,6 +138,31 @@ FROM subscriptions WHERE application_id=$1 AND provider_subscription_id='sub_tes if storedStart.Unix() != periodStart || storedEnd.Unix() != periodEnd || grants != 1 { t.Fatalf("unexpected period or grants: %s %s %d", storedStart, storedEnd, grants) } + var checkoutReference, subscriptionReference, invoiceReference, paymentReference, grantReference string + if err = db.QueryRow(ctx, `SELECT +(SELECT external_reference FROM checkout_sessions WHERE id=$1), +(SELECT external_reference FROM subscriptions WHERE application_id=$2 AND provider_subscription_id='sub_test'), +(SELECT external_reference FROM invoices WHERE application_id=$2 AND provider_invoice_id='in_test'), +(SELECT external_reference FROM payments WHERE application_id=$2 AND provider_payment_id='pi_test'), +(SELECT external_reference FROM entitlement_grants WHERE application_id=$2 AND source_type='subscription')`, checkoutID, applicationID). + Scan(&checkoutReference, &subscriptionReference, &invoiceReference, &paymentReference, &grantReference); err != nil { + t.Fatal(err) + } + if checkoutReference != externalReference || subscriptionReference != externalReference || invoiceReference != externalReference || + paymentReference != externalReference || grantReference != externalReference { + t.Fatalf("external reference propagation failed: checkout=%q subscription=%q invoice=%q payment=%q grant=%q", + checkoutReference, subscriptionReference, invoiceReference, paymentReference, grantReference) + } + var refundEventReference, disputeEventReference string + if err = db.QueryRow(ctx, `SELECT +(SELECT data->>'external_reference' FROM domain_events WHERE application_id=$1 AND event_type='billing.refund.updated' ORDER BY occurred_at DESC,id DESC LIMIT 1), +(SELECT data->>'external_reference' FROM domain_events WHERE application_id=$1 AND event_type='billing.dispute.updated' ORDER BY occurred_at DESC,id DESC LIMIT 1)`, applicationID). + Scan(&refundEventReference, &disputeEventReference); err != nil { + t.Fatal(err) + } + if refundEventReference != externalReference || disputeEventReference != externalReference { + t.Fatalf("external reference was omitted from related lifecycle events: refund=%q dispute=%q", refundEventReference, disputeEventReference) + } if err = server.normalizeStripeSubscription(ctx, applicationID.String(), connectionID.String(), map[string]any{ "id": "sub_test", "status": "active", "metadata": map[string]any{"platform93_checkout_id": checkoutID.String()}, "items": map[string]any{"data": []any{map[string]any{"id": "si_test", "current_period_start": float64(periodStart), "current_period_end": float64(periodEnd)}}}, diff --git a/internal/httpapi/catalog_entitlement_defaults_test.go b/internal/httpapi/catalog_entitlement_defaults_test.go index 40c9597..9eb8414 100644 --- a/internal/httpapi/catalog_entitlement_defaults_test.go +++ b/internal/httpapi/catalog_entitlement_defaults_test.go @@ -52,7 +52,7 @@ func TestPriceSnapshotsProductEntitlementDefaults(t *testing.T) { request := requestWithRoute(t, "POST", "/", map[string]any{ "key": "monthly-" + suffix, "mode": "recurring", "amount_minor": 1900, "currency": "EUR", - }, map[string]string{"application_id": applicationID.String(), "product_id": productID.String()}, kernel.Actor{Type: "operator", ID: kernel.NewID().String()}) + }, map[string]string{"application_id": applicationID.String(), "product_id": productID.String()}, kernel.Actor{Type: "control_user", ID: kernel.NewID().String()}) response := httptest.NewRecorder() server.createPrice(response, request) if response.Code != 201 { diff --git a/internal/httpapi/control.go b/internal/httpapi/control.go index dc090f9..e36e477 100644 --- a/internal/httpapi/control.go +++ b/internal/httpapi/control.go @@ -38,7 +38,7 @@ func (s *Server) createOrganization(w http.ResponseWriter, r *http.Request) { _, err = tx.Exec(r.Context(), "INSERT INTO organizations (id,name,slug) VALUES ($1,$2,$3)", id, request.Name, request.Slug) if err == nil { _, err = tx.Exec(r.Context(), `INSERT INTO organization_memberships -(organization_id,operator_id,role) VALUES ($1,$2,'owner')`, id, actor(r).ID) +(organization_id,control_user_id,role) VALUES ($1,$2,'owner')`, id, actor(r).ID) } if err == nil { _, err = s.app.Emit(r.Context(), tx, nil, "organization.created", "organization/"+id.String(), actor(r), request) @@ -55,8 +55,8 @@ func (s *Server) listOrganizations(w http.ResponseWriter, r *http.Request) { installationRole, installationAccess := s.installationRole(r) rows, err := s.app.DB.Query(r.Context(), `SELECT o.id,o.name,o.slug,o.version,o.created_at,o.updated_at, COALESCE(m.role,$4),o.deleted_at FROM organizations o -LEFT JOIN organization_memberships m ON m.organization_id=o.id AND m.operator_id=$1 -WHERE ($3 OR m.operator_id IS NOT NULL) AND ($2 OR o.deleted_at IS NULL) ORDER BY o.created_at,o.id`, actor(r).ID, includeRetired, installationAccess, "installation:"+installationRole) +LEFT JOIN organization_memberships m ON m.organization_id=o.id AND m.control_user_id=$1 +WHERE ($3 OR m.control_user_id IS NOT NULL) AND ($2 OR o.deleted_at IS NULL) ORDER BY o.created_at,o.id`, actor(r).ID, includeRetired, installationAccess, "installation:"+installationRole) if err != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Organizations could not be loaded.") return @@ -96,8 +96,8 @@ func (s *Server) getOrganization(w http.ResponseWriter, r *http.Request) { } installationRole, installationAccess := s.installationRole(r) err := s.app.DB.QueryRow(r.Context(), `SELECT o.name,o.slug,o.version,COALESCE(m.role,$4) FROM organizations o -LEFT JOIN organization_memberships m ON m.organization_id=o.id AND m.operator_id=$2 -WHERE o.id=$1 AND ($3 OR m.operator_id IS NOT NULL) AND o.deleted_at IS NULL`, id, actor(r).ID, installationAccess, "installation:"+installationRole).Scan(&name, &slug, &version, &role) +LEFT JOIN organization_memberships m ON m.organization_id=o.id AND m.control_user_id=$2 +WHERE o.id=$1 AND ($3 OR m.control_user_id IS NOT NULL) AND o.deleted_at IS NULL`, id, actor(r).ID, installationAccess, "installation:"+installationRole).Scan(&name, &slug, &version, &role) if err != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_not_found", "The organization was not found.") return @@ -150,7 +150,7 @@ func (s *Server) createApplication(w http.ResponseWriter, r *http.Request) { _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM organizations WHERE id=$1 AND deleted_at IS NULL)`, organizationID).Scan(&active) allowed = allowed && active if !allowed { - kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The operator cannot create applications in this organization.") + kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The Platform user cannot create applications in this organization.") return } id := kernel.NewID() @@ -174,7 +174,8 @@ VALUES ($1,$2,$3,$4)`, id, organizationID, request.Name, request.Slug) _, err = tx.Exec(r.Context(), `INSERT INTO roles (id,application_id,key,name,scope,permissions,built_in) VALUES ($1,$2,'application_admin','Application administrator','application',ARRAY[$4],true), ($3,$2,'workspace_member','Workspace member','workspace',ARRAY['read','storage:read'],true), -($5,$2,'event_publisher','Event publisher','application',ARRAY['events:publish'],true)`, kernel.NewID(), id, kernel.NewID(), "/applications/"+id.String()+"/*", kernel.NewID()) +($5,$2,'event_publisher','Event publisher','application',ARRAY['events:publish'],true), +($6,$2,'notification_sender','Notification sender','application',ARRAY['notifications:send'],true)`, kernel.NewID(), id, kernel.NewID(), "*", kernel.NewID(), kernel.NewID()) } if err == nil { _, err = s.app.Emit(r.Context(), tx, &id, "application.created", "application/"+id.String(), actor(r), request) @@ -226,7 +227,7 @@ WHERE id=$2 AND organization_id=$3 AND version=$4 AND deleted_at IS NULL`, reque func (s *Server) listApplications(w http.ResponseWriter, r *http.Request) { includeRetired := r.URL.Query().Get("include_retired") == "true" - if !s.operatorBelongsToOrganization(r, chi.URLParam(r, "organization_id")) { + if !s.controlUserBelongsToOrganization(r, chi.URLParam(r, "organization_id")) { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_not_found", "The organization was not found.") return } @@ -356,6 +357,10 @@ func (s *Server) createClient(w http.ResponseWriter, r *http.Request) { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_client_type", "Client type must be public, confidential, or machine.") return } + if err := validateClientRedirectURIs(request.ClientType, request.RedirectURIs); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_redirect_uri", err.Error()) + return + } id := kernel.NewID() var secret string var digest []byte diff --git a/internal/httpapi/control_auth_events.go b/internal/httpapi/control_auth_events.go new file mode 100644 index 0000000..5164eff --- /dev/null +++ b/internal/httpapi/control_auth_events.go @@ -0,0 +1,39 @@ +package httpapi + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/jackc/pgx/v5" + "github.com/supaapps/platform93/internal/kernel" +) + +func (s *Server) emitControlEvent(ctx context.Context, tx pgx.Tx, r *http.Request, eventType, subject string, data map[string]any) error { + current := actor(r) + actorData := map[string]any{"type": "system"} + if current.ID != "" { + actorData = map[string]any{"type": current.Type, "id": current.ID} + } + _, err := s.app.Emit(ctx, tx, nil, eventType, subject, actorData, data) + return err +} + +func insertControlAuthAudit(ctx context.Context, tx pgx.Tx, r *http.Request, actorID, action, targetType, targetID string, changes map[string]any) error { + encoded, _ := json.Marshal(changes) + _, err := tx.Exec(ctx, `INSERT INTO audit_records +(id,actor_type,actor_id,action,target_type,target_id,request_id,changes) +VALUES($1,'control_user',$2,$3,$4,$5,$6,$7)`, kernel.NewID(), actorID, action, targetType, targetID, kernel.RequestID(ctx), encoded) + return err +} + +func controlInvitationEventData(invitationID string, organizationID *string, controlUserID, role, method, status string) map[string]any { + data := map[string]any{ + "invitation_id": invitationID, "organization_id": organizationID, "role": role, + "onboarding_method": method, "status": status, + } + if controlUserID != "" { + data["control_user_id"] = controlUserID + } + return data +} diff --git a/internal/httpapi/control_auth_policy.go b/internal/httpapi/control_auth_policy.go new file mode 100644 index 0000000..fc8962d --- /dev/null +++ b/internal/httpapi/control_auth_policy.go @@ -0,0 +1,191 @@ +package httpapi + +import ( + "context" + "encoding/json" + "net/http" + + "github.com/supaapps/platform93/internal/kernel" +) + +type controlAuthPolicy struct { + EmailCodeEnabled bool `json:"email_code_enabled"` + MagicLinkEnabled bool `json:"magic_link_enabled"` + PasswordEnabled bool `json:"password_enabled"` +} + +func (s *Server) loadControlAuthPolicy(ctx context.Context) (controlAuthPolicy, error) { + var value controlAuthPolicy + err := s.app.DB.QueryRow(ctx, `SELECT control_email_code_enabled,control_magic_link_enabled,control_password_enabled +FROM installations LIMIT 1`).Scan(&value.EmailCodeEnabled, &value.MagicLinkEnabled, &value.PasswordEnabled) + return value, err +} + +func (s *Server) controlAuthMethods(w http.ResponseWriter, r *http.Request) { + policy, err := s.loadControlAuthPolicy(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusServiceUnavailable, "control_auth_unavailable", "Platform authentication configuration is unavailable.") + return + } + var smtp bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM notification_providers +WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL)`).Scan(&smtp) + providers := []string{} + rows, queryErr := s.app.DB.Query(r.Context(), `SELECT provider FROM auth_provider_configs +WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL AND control_login_enabled ORDER BY provider`) + if queryErr == nil { + defer rows.Close() + for rows.Next() { + var provider string + if rows.Scan(&provider) == nil { + providers = append(providers, provider) + } + } + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{ + "email_code": policy.EmailCodeEnabled && smtp, + "magic_link": policy.MagicLinkEnabled && smtp, + "password": policy.PasswordEnabled, + "providers": providers, + }) +} + +func (s *Server) getControlAuthPolicy(w http.ResponseWriter, r *http.Request) { + if _, allowed := s.installationRole(r); !allowed { + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_role_required", "An installation role is required.") + return + } + policy, err := s.loadControlAuthPolicy(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform authentication policy could not be loaded.") + return + } + kernel.WriteJSON(w, http.StatusOK, policy) +} + +func (s *Server) updateControlAuthPolicy(w http.ResponseWriter, r *http.Request) { + role, allowed := s.installationRole(r) + if !allowed || role != "owner" && role != "admin" { + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "An installation owner or administrator is required.") + return + } + var request struct { + EmailCodeEnabled bool `json:"email_code_enabled"` + MagicLinkEnabled bool `json:"magic_link_enabled"` + PasswordEnabled bool `json:"password_enabled"` + ConfirmAffectedUsers bool `json:"confirm_affected_users,omitempty"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + policy := controlAuthPolicy{EmailCodeEnabled: request.EmailCodeEnabled, MagicLinkEnabled: request.MagicLinkEnabled, PasswordEnabled: request.PasswordEnabled} + if !s.allowControlPolicyChange(w, r, policy, request.ConfirmAffectedUsers, "") { + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err == nil { + _, err = tx.Exec(r.Context(), `UPDATE installations SET control_email_code_enabled=$1, +control_magic_link_enabled=$2,control_password_enabled=$3,updated_at=now()`, policy.EmailCodeEnabled, policy.MagicLinkEnabled, policy.PasswordEnabled) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_auth.policy_updated", "installation/identity", map[string]any{ + "email_code_enabled": policy.EmailCodeEnabled, "magic_link_enabled": policy.MagicLinkEnabled, "password_enabled": policy.PasswordEnabled, + }) + } + if err == nil { + err = tx.Commit(r.Context()) + } else if tx != nil { + _ = tx.Rollback(r.Context()) + } + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "control_auth_policy_update_failed", "Platform authentication policy could not be updated.") + return + } + w.WriteHeader(http.StatusNoContent) +} + +func (s *Server) allowControlMethodRemoval(w http.ResponseWriter, r *http.Request, excludedProvider string, confirmed bool) bool { + policy, err := s.loadControlAuthPolicy(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform authentication safety could not be checked.") + return false + } + return s.allowControlPolicyChange(w, r, policy, confirmed, excludedProvider) +} + +func (s *Server) allowControlPolicyChange(w http.ResponseWriter, r *http.Request, policy controlAuthPolicy, confirmed bool, excludedProvider string) bool { + var smtp bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM notification_providers +WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL)`).Scan(&smtp) + return s.allowControlPolicyChangeWithSMTP(w, r, policy, confirmed, excludedProvider, smtp) +} + +func (s *Server) allowControlSMTPRemoval(w http.ResponseWriter, r *http.Request, providerID string, confirmed bool) bool { + var active, anotherActive bool + err := s.app.DB.QueryRow(r.Context(), `SELECT +EXISTS(SELECT 1 FROM notification_providers WHERE id=$1 AND application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL), +EXISTS(SELECT 1 FROM notification_providers WHERE id<>$1 AND application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL)`, providerID).Scan(&active, &anotherActive) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform authentication safety could not be checked.") + return false + } + if !active || anotherActive { + return true + } + policy, err := s.loadControlAuthPolicy(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform authentication safety could not be checked.") + return false + } + return s.allowControlPolicyChangeWithSMTP(w, r, policy, confirmed, "", false) +} + +func (s *Server) allowControlPolicyChangeWithSMTP(w http.ResponseWriter, r *http.Request, policy controlAuthPolicy, confirmed bool, excludedProvider string, smtp bool) bool { + rows, err := s.app.DB.Query(r.Context(), `SELECT u.id,u.password_hash IS NOT NULL, +EXISTS(SELECT 1 FROM installation_control_user_roles ir WHERE ir.control_user_id=u.id AND ir.role='owner'), +EXISTS(SELECT 1 FROM control_user_identities i JOIN auth_provider_configs p ON p.id=i.auth_provider_config_id +WHERE i.control_user_id=u.id AND p.disabled_at IS NULL AND p.control_login_enabled AND p.provider<>$1) +FROM control_users u WHERE u.status='active'`, excludedProvider) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform authentication safety could not be checked.") + return false + } + defer rows.Close() + affected := 0 + protected := false + currentID := actor(r).ID + for rows.Next() { + var id string + var hasPassword, owner, hasExternal bool + if rows.Scan(&id, &hasPassword, &owner, &hasExternal) != nil { + continue + } + usable := smtp && (policy.EmailCodeEnabled || policy.MagicLinkEnabled) || policy.PasswordEnabled && hasPassword || hasExternal + if usable { + continue + } + affected++ + if owner || id == currentID { + protected = true + } + } + if protected { + writeControlAuthImpact(w, r, "control_auth_owner_lockout", "The change would leave the current Platform user or an installation owner without a usable sign-in method.", affected) + return false + } + if affected > 0 && !confirmed { + writeControlAuthImpact(w, r, "control_auth_confirmation_required", "The change would remove the final usable sign-in method from active Platform users. Confirm the affected users to continue.", affected) + return false + } + return true +} + +func writeControlAuthImpact(w http.ResponseWriter, r *http.Request, code, detail string, affected int) { + w.Header().Set("Content-Type", "application/problem+json") + w.WriteHeader(http.StatusConflict) + _ = json.NewEncoder(w).Encode(map[string]any{ + "type": "https://platform93.dev/problems/" + code, "title": "Platform authentication change rejected", + "status": http.StatusConflict, "detail": detail, "code": code, "affected_users": affected, + "request_id": kernel.RequestID(r.Context()), + }) +} diff --git a/internal/httpapi/control_external_auth.go b/internal/httpapi/control_external_auth.go new file mode 100644 index 0000000..5e6407a --- /dev/null +++ b/internal/httpapi/control_external_auth.go @@ -0,0 +1,441 @@ +package httpapi + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" + + "github.com/coreos/go-oidc/v3/oidc" + "github.com/go-chi/chi/v5" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/secure" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" +) + +type controlExternalIdentity struct { + Subject string + Email string + FirstName string + LastName string +} + +func (s *Server) startControlProviderLogin(w http.ResponseWriter, r *http.Request) { + s.startControlExternalAuth(w, r, chi.URLParam(r, "provider"), "login", "", "") +} + +func (s *Server) startControlProviderLink(w http.ResponseWriter, r *http.Request) { + var recent bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT authenticated_at>now()-interval '10 minutes' FROM control_user_sessions +WHERE id=$1 AND control_user_id=$2 AND revoked_at IS NULL AND expires_at>now()`, actor(r).SessionID, actor(r).ID).Scan(&recent) + if !recent { + kernel.WriteProblem(w, r, http.StatusConflict, "recent_authentication_required", "Sign in again before linking an external identity.") + return + } + s.startControlExternalAuth(w, r, chi.URLParam(r, "provider"), "link", actor(r).ID, "") +} + +func (s *Server) startControlInvitationProvider(w http.ResponseWriter, r *http.Request) { + provider := chi.URLParam(r, "provider") + var request struct { + InvitationToken string `json:"invitation_token"` + } + if !kernel.DecodeJSON(w, r, &request) || request.InvitationToken == "" { + return + } + var invitationID string + err := s.app.DB.QueryRow(r.Context(), `SELECT id FROM control_user_invitations +WHERE credential_digest=$1 AND onboarding_method=$2 AND accepted_at IS NULL AND revoked_at IS NULL AND expires_at>now()`, + s.app.Vault.Digest(request.InvitationToken), provider).Scan(&invitationID) + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_control_user_invitation", "The Platform user invitation is invalid or expired.") + return + } + s.startControlExternalAuth(w, r, provider, "invitation", "", invitationID) +} + +func (s *Server) startControlExternalAuth(w http.ResponseWriter, r *http.Request, provider, flow, requestedBy, invitationID string) { + if provider != "google" && provider != "apple" { + kernel.WriteProblem(w, r, http.StatusNotFound, "control_auth_provider_not_found", "The Platform authentication provider is unavailable.") + return + } + if !s.allowAuthAttempt(w, r, "control_external_"+provider, requestedBy+invitationID, 12, 10*time.Minute) { + return + } + config, err := s.loadControlAuthProvider(r, provider) + if err != nil { + kernel.WriteProblem(w, r, http.StatusServiceUnavailable, "control_auth_provider_unavailable", "The Platform authentication provider is unavailable.") + return + } + state, _ := secure.RandomToken("p93_control_"+provider+"_state_", 32) + nonce, _ := secure.RandomToken("", 32) + verifier := oauth2.GenerateVerifier() + challengeID := kernel.NewID() + verifierValue := verifier + if provider == "apple" { + verifierValue = "apple" + } + ciphertext, err := s.app.Vault.Encrypt([]byte(verifierValue), "control-external-auth:"+challengeID.String()) + var requestedByValue, invitationValue any + if requestedBy != "" { + requestedByValue = requestedBy + } + if invitationID != "" { + invitationValue = invitationID + } + if err == nil { + _, err = s.app.DB.Exec(r.Context(), `INSERT INTO control_user_external_auth_challenges +(id,auth_provider_config_id,provider,flow,requested_by_control_user_id,invitation_id,state_digest,nonce_digest,verifier_ciphertext,expires_at) +VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, challengeID, config.ID, provider, flow, requestedByValue, invitationValue, + s.app.Vault.Digest(state), s.app.Vault.Digest(nonce), ciphertext, s.app.Now().Add(10*time.Minute)) + } + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "control_external_auth_start_failed", "The Platform authentication flow could not be started.") + return + } + var authorizeURL string + if provider == "google" { + oauthConfig := oauth2.Config{ClientID: config.ClientID, ClientSecret: config.Credentials["client_secret"], Endpoint: google.Endpoint, + RedirectURL: s.externalAuthCallbackURI("google"), Scopes: []string{oidc.ScopeOpenID, "email", "profile"}} + authorizeURL = oauthConfig.AuthCodeURL(state, oauth2.S256ChallengeOption(verifier), oauth2.SetAuthURLParam("nonce", nonce), oauth2.SetAuthURLParam("prompt", "select_account")) + } else { + query := url.Values{"client_id": {config.ClientID}, "redirect_uri": {s.externalAuthCallbackURI("apple")}, "response_type": {"code"}, + "response_mode": {"form_post"}, "scope": {"name email"}, "state": {state}, "nonce": {nonce}} + authorizeURL = "https://appleid.apple.com/auth/authorize?" + query.Encode() + } + kernel.WriteJSON(w, http.StatusCreated, map[string]any{"provider": provider, "authorize_url": authorizeURL, "expires_in": 600}) +} + +func (s *Server) loadControlAuthProvider(r *http.Request, provider string) (externalAuthProviderConfig, error) { + var value externalAuthProviderConfig + var ciphertext string + err := s.app.DB.QueryRow(r.Context(), `SELECT id,provider,client_id,config_ciphertext,inheritable,control_login_enabled +FROM auth_provider_configs WHERE provider=$1 AND application_id IS NULL AND organization_id IS NULL +AND disabled_at IS NULL AND control_login_enabled`, provider).Scan(&value.ID, &value.Provider, &value.ClientID, &ciphertext, &value.Inheritable, &value.ControlLoginEnabled) + if err != nil { + return value, err + } + plaintext, err := s.app.Vault.Decrypt(ciphertext, "auth-provider:"+value.ID) + if err != nil || json.Unmarshal(plaintext, &value.Credentials) != nil { + return value, fmt.Errorf("control provider unavailable") + } + value.Scope = "installation" + return value, nil +} + +func (s *Server) routeControlExternalCallback(w http.ResponseWriter, r *http.Request, provider, state string) bool { + var exists bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM control_user_external_auth_challenges +WHERE provider=$1 AND state_digest=$2 AND consumed_at IS NULL AND expires_at>now())`, provider, s.app.Vault.Digest(state)).Scan(&exists) + if !exists { + return false + } + s.controlExternalCallback(w, r, provider, state) + return true +} + +func (s *Server) controlExternalCallback(w http.ResponseWriter, r *http.Request, provider, state string) { + var challengeID, providerConfigID, flow, verifierCiphertext string + var requestedBy, invitationID *string + var nonceDigest []byte + err := s.app.DB.QueryRow(r.Context(), `UPDATE control_user_external_auth_challenges SET locked_until=now()+interval '2 minutes' +WHERE provider=$1 AND state_digest=$2 AND consumed_at IS NULL AND expires_at>now() AND (locked_until IS NULL OR locked_untilnow() FOR UPDATE`, invitationID, config.Provider). + Scan(&email, &role, &organizationID) + if err == nil && email != external.Email { + err = fmt.Errorf("invitation email mismatch") + } + displayName := strings.TrimSpace(external.FirstName + " " + external.LastName) + if displayName == "" { + displayName = strings.Split(email, "@")[0] + } + var controlUserStatus string + if err == nil { + err = tx.QueryRow(r.Context(), `INSERT INTO control_users(id,email,normalized_email,display_name) +VALUES($1,$2,$2,$3) ON CONFLICT(normalized_email) DO UPDATE SET display_name=CASE WHEN control_users.display_name='' THEN EXCLUDED.display_name ELSE control_users.display_name END +RETURNING id,status`, kernel.NewID(), email, truncate(displayName, 200)).Scan(&controlUserID, &controlUserStatus) + } + if err == nil && controlUserStatus != "active" { + err = fmt.Errorf("control user unavailable") + } + metadata, _ := json.Marshal(map[string]any{"email": external.Email, "first_name": external.FirstName, "last_name": external.LastName}) + if err == nil { + err = tx.QueryRow(r.Context(), `INSERT INTO control_user_identities +(id,control_user_id,auth_provider_config_id,provider,provider_subject,metadata,last_used_at) VALUES($1,$2,$3,$4,$5,$6,now()) +ON CONFLICT(control_user_id,auth_provider_config_id) DO UPDATE SET last_used_at=now(),metadata=EXCLUDED.metadata +RETURNING (xmax=0)`, kernel.NewID(), controlUserID, config.ID, config.Provider, external.Subject, metadata).Scan(&identityCreated) + } + if err == nil && organizationID == nil { + _, err = tx.Exec(r.Context(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,$2) +ON CONFLICT(control_user_id) DO UPDATE SET role=EXCLUDED.role,updated_at=now()`, controlUserID, role) + } else if err == nil { + _, err = tx.Exec(r.Context(), `INSERT INTO organization_memberships(organization_id,control_user_id,role) VALUES($1,$2,$3) +ON CONFLICT(organization_id,control_user_id) DO UPDATE SET role=EXCLUDED.role`, *organizationID, controlUserID, role) + } + if err == nil { + _, err = tx.Exec(r.Context(), `UPDATE control_user_invitations SET accepted_by=$1,accepted_at=now(),updated_at=now() WHERE id=$2`, controlUserID, invitationID) + } + if err == nil && identityCreated { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.identity_linked", "control_user/"+controlUserID, + map[string]any{"control_user_id": controlUserID, "provider": config.Provider}) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_accepted", "control_user_invitation/"+invitationID, + controlInvitationEventData(invitationID, organizationID, controlUserID, role, config.Provider, "accepted")) + } + if err == nil { + err = insertControlAuthAudit(r.Context(), tx, r, controlUserID, "control_user.invitation_accepted", "control_user_invitation", invitationID, + map[string]any{"provider": config.Provider, "organization_id": organizationID, "role": role}) + } + } else { + err = fmt.Errorf("invalid control external flow") + } + refresh, tokenErr := secure.RandomToken("p93_control_refresh_", 32) + sessionID := kernel.NewID() + if err == nil && tokenErr == nil { + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_sessions +(id,control_user_id,refresh_digest,kind,ip_address,user_agent,amr,expires_at) VALUES($1,$2,$3,'control',$4,$5,$6,$7)`, sessionID, controlUserID, + s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), []string{config.Provider}, s.app.Now().Add(12*time.Hour)) + } + if err == nil { + _, err = tx.Exec(r.Context(), `UPDATE control_user_external_auth_challenges SET consumed_at=now(),locked_until=NULL WHERE id=$1`, challengeID) + } + access, tokenErr := s.issueControlUserAccessWithQuerier(r.Context(), tx, controlUserID, sessionID.String(), "control") + if err != nil || tokenErr != nil { + return fmt.Errorf("control external session failed") + } + if err = tx.Commit(r.Context()); err != nil { + return err + } + s.setControlUserCookies(w, access, refresh, 12*time.Hour) + http.Redirect(w, r, strings.TrimRight(s.app.PublicURL, "/")+"/?control_provider="+url.QueryEscape(config.Provider)+"&status=success", http.StatusFound) + return nil +} + +func (s *Server) consumeControlExternalChallenge(r *http.Request, challengeID string) { + _, _ = s.app.DB.Exec(r.Context(), `UPDATE control_user_external_auth_challenges SET consumed_at=now(),locked_until=NULL WHERE id=$1`, challengeID) +} + +func (s *Server) redirectControlExternal(w http.ResponseWriter, r *http.Request, provider, failure string) { + query := url.Values{"control_provider": {provider}} + if failure == "" { + query.Set("status", "success") + } else { + query.Set("error", failure) + } + http.Redirect(w, r, strings.TrimRight(s.app.PublicURL, "/")+"/?"+query.Encode(), http.StatusFound) +} + +func (s *Server) unlinkControlUserIdentity(w http.ResponseWriter, r *http.Request) { + var recent bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT authenticated_at>now()-interval '10 minutes' FROM control_user_sessions +WHERE id=$1 AND control_user_id=$2 AND revoked_at IS NULL AND expires_at>now()`, actor(r).SessionID, actor(r).ID).Scan(&recent) + if !recent { + kernel.WriteProblem(w, r, http.StatusConflict, "recent_authentication_required", "Sign in again before unlinking an external identity.") + return + } + identityID := chi.URLParam(r, "identity_id") + var provider string + if s.app.DB.QueryRow(r.Context(), `SELECT provider FROM control_user_identities WHERE id=$1 AND control_user_id=$2`, identityID, actor(r).ID).Scan(&provider) != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "control_user_identity_not_found", "The linked identity was not found.") + return + } + policy, err := s.loadControlAuthPolicy(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform authentication safety could not be checked.") + return + } + var usable bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT +(EXISTS(SELECT 1 FROM notification_providers WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL) AND ($2 OR $3)) +OR ($4 AND u.password_hash IS NOT NULL) +OR EXISTS(SELECT 1 FROM control_user_identities i JOIN auth_provider_configs p ON p.id=i.auth_provider_config_id +WHERE i.control_user_id=u.id AND i.id<>$5 AND p.disabled_at IS NULL AND p.control_login_enabled) +FROM control_users u WHERE u.id=$1`, actor(r).ID, policy.EmailCodeEnabled, policy.MagicLinkEnabled, policy.PasswordEnabled, identityID).Scan(&usable) + if !usable { + kernel.WriteProblem(w, r, http.StatusConflict, "control_auth_owner_lockout", "Unlinking this identity would leave the Platform user without a usable sign-in method.") + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err == nil { + _, err = tx.Exec(r.Context(), `DELETE FROM control_user_identities WHERE id=$1 AND control_user_id=$2`, identityID, actor(r).ID) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.identity_unlinked", "control_user/"+actor(r).ID, + map[string]any{"control_user_id": actor(r).ID, "provider": provider}) + } + if err == nil { + err = tx.Commit(r.Context()) + } else if tx != nil { + _ = tx.Rollback(r.Context()) + } + if err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "control_user_identity_not_found", "The linked identity was not found.") + return + } + w.WriteHeader(http.StatusNoContent) +} diff --git a/internal/httpapi/control_external_auth_integration_test.go b/internal/httpapi/control_external_auth_integration_test.go new file mode 100644 index 0000000..df08af1 --- /dev/null +++ b/internal/httpapi/control_external_auth_integration_test.go @@ -0,0 +1,181 @@ +package httpapi + +import ( + "context" + "net/http" + "net/http/httptest" + "os" + "strings" + "testing" + "time" + + "github.com/supaapps/platform93/internal/database" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/platform" + "github.com/supaapps/platform93/internal/secure" +) + +func TestControlExternalInvitationAndLoginLifecycle(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, err := secure.NewVault(make([]byte, 32)) + if err != nil { + t.Fatal(err) + } + app := platform.New(db, vault, "https://platform93.test") + server := &Server{app: app} + if _, err = db.Exec(context.Background(), `INSERT INTO installations(id,setup_completed_at) +SELECT $1,now() WHERE NOT EXISTS(SELECT 1 FROM installations)`, kernel.NewID()); err != nil { + t.Fatal(err) + } + tx, err := db.Begin(context.Background()) + if err != nil { + t.Fatal(err) + } + if err = app.EnsureSigningKey(context.Background(), tx); err != nil { + t.Fatal(err) + } + if err = tx.Commit(context.Background()); err != nil { + t.Fatal(err) + } + + for _, provider := range []string{"google", "apple"} { + t.Run(provider, func(t *testing.T) { + inviterID, providerID, invitationID, challengeID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() + var acceptedControlUserID string + providerCreated := false + challengeIDs := []string{challengeID.String()} + suffix := challengeID.String() + email := provider + "-invite-" + suffix + "@example.test" + if _, insertErr := db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email,display_name) +VALUES($1,$2,$2,'External auth inviter')`, inviterID, "inviter-"+suffix+"@example.test"); insertErr != nil { + t.Fatal(insertErr) + } + var existingProviderID string + providerErr := db.QueryRow(context.Background(), `SELECT id FROM auth_provider_configs +WHERE provider=$1 AND application_id IS NULL AND organization_id IS NULL`, provider).Scan(&existingProviderID) + if providerErr == nil { + if parseErr := providerID.Scan(existingProviderID); parseErr != nil { + t.Fatal(parseErr) + } + } else { + ciphertext, encryptErr := vault.Encrypt([]byte(`{}`), "auth-provider:"+providerID.String()) + if encryptErr != nil { + t.Fatal(encryptErr) + } + if _, insertErr := db.Exec(context.Background(), `INSERT INTO auth_provider_configs +(id,provider,client_id,config_ciphertext,control_login_enabled) VALUES($1,$2,$3,$4,true)`, + providerID, provider, provider+"-client-"+suffix, ciphertext); insertErr != nil { + t.Fatal(insertErr) + } + providerCreated = true + } + t.Cleanup(func() { + _, _ = db.Exec(context.Background(), `DELETE FROM control_user_external_auth_challenges WHERE id=ANY($1::uuid[])`, challengeIDs) + if acceptedControlUserID != "" { + _, _ = db.Exec(context.Background(), `DELETE FROM control_user_sessions WHERE control_user_id=$1`, acceptedControlUserID) + _, _ = db.Exec(context.Background(), `DELETE FROM installation_control_user_roles WHERE control_user_id=$1`, acceptedControlUserID) + _, _ = db.Exec(context.Background(), `DELETE FROM control_user_identities WHERE control_user_id=$1`, acceptedControlUserID) + } + _, _ = db.Exec(context.Background(), `DELETE FROM control_user_invitations WHERE id=$1`, invitationID) + if acceptedControlUserID != "" { + _, _ = db.Exec(context.Background(), `DELETE FROM control_users WHERE id=$1`, acceptedControlUserID) + } + _, _ = db.Exec(context.Background(), `DELETE FROM control_users WHERE id=$1`, inviterID) + if providerCreated { + _, _ = db.Exec(context.Background(), `DELETE FROM auth_provider_configs WHERE id=$1`, providerID) + } + }) + if _, insertErr := db.Exec(context.Background(), `INSERT INTO control_user_invitations +(id,normalized_email,role,onboarding_method,credential_digest,invited_by,expires_at) +VALUES($1,$2,'auditor',$3,$4,$5,now()+interval '1 hour')`, invitationID, email, provider, vault.Digest("invite-"+suffix), inviterID); insertErr != nil { + t.Fatal(insertErr) + } + insertControlExternalChallenge(t, server, challengeID, providerID, provider, "invitation", invitationID.String(), "") + + request := requestWithRoute(t, http.MethodGet, "/v1/auth/providers/"+provider+"/callback", nil, nil, kernel.Actor{}) + response := httptest.NewRecorder() + config := externalAuthProviderConfig{ID: providerID.String(), Provider: provider} + external := controlExternalIdentity{Subject: "subject-" + suffix, Email: email, FirstName: "External", LastName: "User"} + if err = server.completeControlExternalSignIn(response, request, challengeID.String(), "invitation", invitationID.String(), config, external); err != nil { + t.Fatalf("%s invitation acceptance failed: %v", provider, err) + } + if response.Code != http.StatusFound || !strings.Contains(response.Header().Get("Set-Cookie"), "p93_control_access=") { + t.Fatalf("%s invitation did not establish a control session: %d %s", provider, response.Code, response.Header().Get("Set-Cookie")) + } + + var controlUserID, role, method string + var acceptedAt, consumedAt *time.Time + if err = db.QueryRow(context.Background(), `SELECT accepted_by,role,onboarding_method,accepted_at +FROM control_user_invitations WHERE id=$1`, invitationID).Scan(&controlUserID, &role, &method, &acceptedAt); err != nil { + t.Fatal(err) + } + if role != "auditor" || method != provider || acceptedAt == nil { + t.Fatalf("unexpected accepted invitation state: role=%q method=%q accepted=%v", role, method, acceptedAt) + } + acceptedControlUserID = controlUserID + if err = db.QueryRow(context.Background(), `SELECT consumed_at FROM control_user_external_auth_challenges WHERE id=$1`, challengeID).Scan(&consumedAt); err != nil || consumedAt == nil { + t.Fatalf("external challenge was not consumed: %v", err) + } + var identityCount, sessionCount int + if err = db.QueryRow(context.Background(), `SELECT count(*) FROM control_user_identities +WHERE control_user_id=$1 AND auth_provider_config_id=$2 AND provider_subject=$3`, controlUserID, providerID, external.Subject).Scan(&identityCount); err != nil || identityCount != 1 { + t.Fatalf("external identity count=%d err=%v", identityCount, err) + } + if err = db.QueryRow(context.Background(), `SELECT count(*) FROM control_user_sessions +WHERE control_user_id=$1 AND $2=ANY(amr) AND revoked_at IS NULL`, controlUserID, provider).Scan(&sessionCount); err != nil || sessionCount != 1 { + t.Fatalf("provider session count=%d err=%v", sessionCount, err) + } + + replayID := kernel.NewID() + challengeIDs = append(challengeIDs, replayID.String()) + insertControlExternalChallenge(t, server, replayID, providerID, provider, "invitation", invitationID.String(), "") + if replayErr := server.completeControlExternalSignIn(httptest.NewRecorder(), request, replayID.String(), "invitation", invitationID.String(), config, external); replayErr == nil { + t.Fatal("accepted external invitation was replayed") + } + + loginID := kernel.NewID() + challengeIDs = append(challengeIDs, loginID.String()) + insertControlExternalChallenge(t, server, loginID, providerID, provider, "login", "", "") + loginResponse := httptest.NewRecorder() + if loginErr := server.completeControlExternalSignIn(loginResponse, request, loginID.String(), "login", "", config, external); loginErr != nil { + t.Fatalf("linked %s login failed: %v", provider, loginErr) + } + if err = db.QueryRow(context.Background(), `SELECT count(*) FROM control_user_sessions +WHERE control_user_id=$1 AND $2=ANY(amr) AND revoked_at IS NULL`, controlUserID, provider).Scan(&sessionCount); err != nil || sessionCount != 2 { + t.Fatalf("linked provider login session count=%d err=%v", sessionCount, err) + } + }) + } +} + +func insertControlExternalChallenge(t *testing.T, server *Server, challengeID, providerID interface{ String() string }, provider, flow, invitationID, controlUserID string) { + t.Helper() + verifier, err := server.app.Vault.Encrypt([]byte("test-verifier"), "control-external-auth:"+challengeID.String()) + if err != nil { + t.Fatal(err) + } + var invitation, requestedBy any + if invitationID != "" { + invitation = invitationID + } + if controlUserID != "" { + requestedBy = controlUserID + } + if _, err = server.app.DB.Exec(context.Background(), `INSERT INTO control_user_external_auth_challenges +(id,auth_provider_config_id,provider,flow,requested_by_control_user_id,invitation_id,state_digest,nonce_digest,verifier_ciphertext,expires_at) +VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,now()+interval '10 minutes')`, challengeID.String(), providerID.String(), provider, flow, + requestedBy, invitation, server.app.Vault.Digest("state-"+challengeID.String()), server.app.Vault.Digest("nonce"), verifier); err != nil { + t.Fatal(err) + } +} diff --git a/internal/httpapi/control_invitation_test.go b/internal/httpapi/control_invitation_test.go index e70e8f0..5638907 100644 --- a/internal/httpapi/control_invitation_test.go +++ b/internal/httpapi/control_invitation_test.go @@ -37,7 +37,7 @@ func TestAcceptOrganizationInvitationIncludesNewMembershipInAccessToken(t *testi inviterID, organizationID, invitationID := kernel.NewID(), kernel.NewID(), kernel.NewID() suffix := invitationID.String() credential := "p93_org_invite_" + suffix - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, inviterID, "inviter-"+suffix+"@example.test"); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, inviterID, "inviter-"+suffix+"@example.test"); err != nil { t.Fatal(err) } if _, err = db.Exec(context.Background(), `INSERT INTO organizations(id,name,slug) VALUES($1,'Invitation test',$2)`, organizationID, "invitation-"+suffix); err != nil { @@ -47,8 +47,8 @@ func TestAcceptOrganizationInvitationIncludesNewMembershipInAccessToken(t *testi if err != nil { t.Fatal(err) } - queueRequest := requestWithRoute(t, http.MethodPost, "/", nil, nil, kernel.Actor{Type: "operator", ID: inviterID.String()}) - if err = server.queueOrganizationInvitation(queueRequest, notificationTx, organizationID.String(), invitationID.String(), "invitee-"+suffix+"@example.test", "admin", credential, time.Now().Add(time.Hour)); err != nil { + queueRequest := requestWithRoute(t, http.MethodPost, "/", nil, nil, kernel.Actor{Type: "control_user", ID: inviterID.String()}) + if err = server.queueOrganizationInvitation(queueRequest, notificationTx, organizationID.String(), invitationID.String(), "invitee-"+suffix+"@example.test", "admin", "email", credential, time.Now().Add(time.Hour)); err != nil { t.Fatal(err) } if err = notificationTx.Commit(context.Background()); err != nil { @@ -58,7 +58,7 @@ func TestAcceptOrganizationInvitationIncludesNewMembershipInAccessToken(t *testi if err = db.QueryRow(context.Background(), `SELECT organization_id FROM notifications WHERE payload_ciphertext IS NOT NULL AND recipient=$1 ORDER BY created_at DESC LIMIT 1`, "invitee-"+suffix+"@example.test").Scan(&queuedOrganizationID); err != nil || queuedOrganizationID != organizationID.String() { t.Fatalf("organization invitation notification lost its provider scope: organization=%q err=%v", queuedOrganizationID, err) } - if _, err = db.Exec(context.Background(), `INSERT INTO organization_invitations(id,organization_id,normalized_email,role,credential_digest,invited_by,expires_at) + if _, err = db.Exec(context.Background(), `INSERT INTO control_user_invitations(id,organization_id,normalized_email,role,credential_digest,invited_by,expires_at) VALUES($1,$2,$3,'admin',$4,$5,$6)`, invitationID, organizationID, "invitee-"+suffix+"@example.test", vault.Digest(credential), inviterID, time.Now().Add(time.Hour)); err != nil { t.Fatal(err) } @@ -75,7 +75,7 @@ VALUES($1,$2,$3,'admin',$4,$5,$6)`, invitationID, organizationID, "invitee-"+suf request := requestWithRoute(t, http.MethodPost, "/v1/control/organization-invitations/accept", map[string]any{ "invitation_token": credential, - "display_name": "Invited operator", + "display_name": "Invited control_user", }, nil, kernel.Actor{}) response := httptest.NewRecorder() server.acceptOrganizationInvitation(response, request) diff --git a/internal/httpapi/control_lifecycle_test.go b/internal/httpapi/control_lifecycle_test.go index 0260489..ea80180 100644 --- a/internal/httpapi/control_lifecycle_test.go +++ b/internal/httpapi/control_lifecycle_test.go @@ -50,14 +50,14 @@ func TestRoleWorkspaceAndWebhookLifecycle(t *testing.T) { t.Fatal(err) } - roleUpdate := requestWithRoute(t, "PATCH", "/", map[string]any{"name": "Updated", "permissions": []string{"users:read", "users:write"}}, map[string]string{"application_id": applicationID.String(), "role_id": roleID.String()}, kernel.Actor{Type: "operator"}) + roleUpdate := requestWithRoute(t, "PATCH", "/", map[string]any{"name": "Updated", "permissions": []string{"users:read", "users:write"}}, map[string]string{"application_id": applicationID.String(), "role_id": roleID.String()}, kernel.Actor{Type: "control_user"}) response := httptest.NewRecorder() server.updateRole(response, roleUpdate) if response.Code != 204 { t.Fatalf("role update failed: %d %s", response.Code, response.Body.String()) } - webhookTest := requestWithRoute(t, "POST", "/", map[string]any{}, map[string]string{"application_id": applicationID.String(), "webhook_id": webhookID.String()}, kernel.Actor{Type: "operator", ID: kernel.NewID().String()}) + webhookTest := requestWithRoute(t, "POST", "/", map[string]any{}, map[string]string{"application_id": applicationID.String(), "webhook_id": webhookID.String()}, kernel.Actor{Type: "control_user", ID: kernel.NewID().String()}) response = httptest.NewRecorder() server.testWebhook(response, webhookTest) if response.Code != 202 { @@ -74,7 +74,7 @@ func TestRoleWorkspaceAndWebhookLifecycle(t *testing.T) { t.Fatalf("targeted webhook test created events=%d deliveries=%d", eventCount, deliveryCount) } - workspaceDelete := requestWithRoute(t, "DELETE", "/", nil, map[string]string{"application_id": applicationID.String(), "workspace_id": workspaceID.String()}, kernel.Actor{Type: "operator"}) + workspaceDelete := requestWithRoute(t, "DELETE", "/", nil, map[string]string{"application_id": applicationID.String(), "workspace_id": workspaceID.String()}, kernel.Actor{Type: "control_user"}) response = httptest.NewRecorder() server.deleteWorkspace(response, workspaceDelete) if response.Code != 204 { diff --git a/internal/httpapi/control_members.go b/internal/httpapi/control_members.go index 7dbe1b8..163ad0d 100644 --- a/internal/httpapi/control_members.go +++ b/internal/httpapi/control_members.go @@ -13,12 +13,12 @@ import ( func (s *Server) listOrganizationMembers(w http.ResponseWriter, r *http.Request) { organizationID := chi.URLParam(r, "organization_id") - if !s.operatorBelongsToOrganization(r, organizationID) { + if !s.controlUserBelongsToOrganization(r, organizationID) { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_not_found", "The organization was not found.") return } rows, err := s.app.DB.Query(r.Context(), `SELECT o.id,o.email,o.display_name,o.status,m.role,m.created_at -FROM organization_memberships m JOIN operators o ON o.id=m.operator_id +FROM organization_memberships m JOIN control_users o ON o.id=m.control_user_id WHERE m.organization_id=$1 ORDER BY m.created_at,o.id`, organizationID) if err != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Organization members could not be loaded.") @@ -30,7 +30,7 @@ WHERE m.organization_id=$1 ORDER BY m.created_at,o.id`, organizationID) var id, email, displayName, status, role string var createdAt time.Time if rows.Scan(&id, &email, &displayName, &status, &role, &createdAt) == nil { - items = append(items, map[string]any{"id": id, "operator_id": id, "email": email, "display_name": displayName, "status": status, "role": role, "created_at": createdAt}) + items = append(items, map[string]any{"id": id, "control_user_id": id, "email": email, "display_name": displayName, "status": status, "role": role, "created_at": createdAt}) } } kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) @@ -46,7 +46,7 @@ func (s *Server) updateOrganizationMember(w http.ResponseWriter, r *http.Request organizationID, memberID := chi.URLParam(r, "organization_id"), chi.URLParam(r, "member_id") callerRole, allowed := s.organizationManagementRole(r, organizationID) if !allowed || callerRole != "owner" && (request.Role == "owner" || request.Role == "admin") { - kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The operator cannot assign this organization role.") + kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The Platform user cannot assign this organization role.") return } tx, err := s.app.DB.Begin(r.Context()) @@ -56,7 +56,7 @@ func (s *Server) updateOrganizationMember(w http.ResponseWriter, r *http.Request } defer rollback(tx, r.Context()) var currentRole string - err = tx.QueryRow(r.Context(), `SELECT role FROM organization_memberships WHERE organization_id=$1 AND operator_id=$2 FOR UPDATE`, organizationID, memberID).Scan(¤tRole) + err = tx.QueryRow(r.Context(), `SELECT role FROM organization_memberships WHERE organization_id=$1 AND control_user_id=$2 FOR UPDATE`, organizationID, memberID).Scan(¤tRole) if err != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_member_not_found", "The organization member was not found.") return @@ -65,7 +65,7 @@ func (s *Server) updateOrganizationMember(w http.ResponseWriter, r *http.Request kernel.WriteProblem(w, r, http.StatusConflict, "last_organization_owner", "The final organization owner cannot be demoted.") return } - _, err = tx.Exec(r.Context(), `UPDATE organization_memberships SET role=$1 WHERE organization_id=$2 AND operator_id=$3`, request.Role, organizationID, memberID) + _, err = tx.Exec(r.Context(), `UPDATE organization_memberships SET role=$1 WHERE organization_id=$2 AND control_user_id=$3`, request.Role, organizationID, memberID) if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "organization_member_update_failed", "The organization member could not be updated.") return @@ -77,7 +77,7 @@ func (s *Server) deleteOrganizationMember(w http.ResponseWriter, r *http.Request organizationID, memberID := chi.URLParam(r, "organization_id"), chi.URLParam(r, "member_id") callerRole, allowed := s.organizationManagementRole(r, organizationID) if !allowed { - kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The operator cannot remove organization members.") + kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The Platform user cannot remove organization members.") return } tx, err := s.app.DB.Begin(r.Context()) @@ -87,7 +87,7 @@ func (s *Server) deleteOrganizationMember(w http.ResponseWriter, r *http.Request } defer rollback(tx, r.Context()) var memberRole string - err = tx.QueryRow(r.Context(), `SELECT role FROM organization_memberships WHERE organization_id=$1 AND operator_id=$2 FOR UPDATE`, organizationID, memberID).Scan(&memberRole) + err = tx.QueryRow(r.Context(), `SELECT role FROM organization_memberships WHERE organization_id=$1 AND control_user_id=$2 FOR UPDATE`, organizationID, memberID).Scan(&memberRole) if err != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_member_not_found", "The organization member was not found.") return @@ -100,7 +100,7 @@ func (s *Server) deleteOrganizationMember(w http.ResponseWriter, r *http.Request kernel.WriteProblem(w, r, http.StatusConflict, "last_organization_owner", "The final organization owner cannot be removed.") return } - _, err = tx.Exec(r.Context(), `DELETE FROM organization_memberships WHERE organization_id=$1 AND operator_id=$2`, organizationID, memberID) + _, err = tx.Exec(r.Context(), `DELETE FROM organization_memberships WHERE organization_id=$1 AND control_user_id=$2`, organizationID, memberID) if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "organization_member_removal_failed", "The organization member could not be removed.") return @@ -110,9 +110,10 @@ func (s *Server) deleteOrganizationMember(w http.ResponseWriter, r *http.Request func (s *Server) createOrganizationInvitation(w http.ResponseWriter, r *http.Request) { var request struct { - Email string `json:"email"` - Role string `json:"role"` - ExpiresIn int64 `json:"expires_in,omitempty"` + Email string `json:"email"` + Role string `json:"role"` + OnboardingMethod string `json:"onboarding_method,omitempty"` + ExpiresIn int64 `json:"expires_in,omitempty"` } if !kernel.DecodeJSON(w, r, &request) { return @@ -121,16 +122,25 @@ func (s *Server) createOrganizationInvitation(w http.ResponseWriter, r *http.Req if request.ExpiresIn == 0 { request.ExpiresIn = int64((7 * 24 * time.Hour).Seconds()) } + if request.OnboardingMethod == "" { + request.OnboardingMethod = "email" + } organizationID := chi.URLParam(r, "organization_id") callerRole, allowed := s.organizationManagementRole(r, organizationID) if !allowed || callerRole != "owner" && (request.Role == "owner" || request.Role == "admin") { - kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The operator cannot invite this organization role.") + kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The Platform user cannot invite this organization role.") return } - if !strings.Contains(request.Email, "@") || !validOrganizationRole(request.Role) || request.ExpiresIn < 300 || request.ExpiresIn > int64((30*24*time.Hour).Seconds()) { + if !strings.Contains(request.Email, "@") || !validOrganizationRole(request.Role) || !validControlOnboardingMethod(request.OnboardingMethod) || request.ExpiresIn < 300 || request.ExpiresIn > int64((30*24*time.Hour).Seconds()) { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_organization_invitation", "Email, role, or expiry is invalid.") return } + if request.OnboardingMethod != "email" { + if _, err := s.loadControlAuthProvider(r, request.OnboardingMethod); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "control_auth_provider_unavailable", "The selected onboarding provider is not enabled for Platform login.") + return + } + } token, err := secure.RandomToken("p93_org_invite_", 32) if err != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "invitation_creation_failed", "The invitation credential could not be created.") @@ -140,12 +150,16 @@ func (s *Server) createOrganizationInvitation(w http.ResponseWriter, r *http.Req expiresAt := s.app.Now().Add(time.Duration(request.ExpiresIn) * time.Second) tx, err := s.app.DB.Begin(r.Context()) if err == nil { - _, err = tx.Exec(r.Context(), `INSERT INTO organization_invitations -(id,organization_id,normalized_email,role,credential_digest,invited_by,expires_at) VALUES($1,$2,$3,$4,$5,$6,$7)`, - id, organizationID, request.Email, request.Role, s.app.Vault.Digest(token), actor(r).ID, expiresAt) + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_invitations +(id,organization_id,normalized_email,role,onboarding_method,credential_digest,invited_by,expires_at) VALUES($1,$2,$3,$4,$5,$6,$7,$8)`, + id, organizationID, request.Email, request.Role, request.OnboardingMethod, s.app.Vault.Digest(token), actor(r).ID, expiresAt) + } + if err == nil { + err = s.queueOrganizationInvitation(r, tx, organizationID, id.String(), request.Email, request.Role, request.OnboardingMethod, token, expiresAt) } if err == nil { - err = s.queueOrganizationInvitation(r, tx, organizationID, id.String(), request.Email, request.Role, token, expiresAt) + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_created", "control_user_invitation/"+id.String(), + controlInvitationEventData(id.String(), &organizationID, "", request.Role, request.OnboardingMethod, "pending")) } if err == nil { err = tx.Commit(r.Context()) @@ -156,17 +170,17 @@ func (s *Server) createOrganizationInvitation(w http.ResponseWriter, r *http.Req kernel.WriteProblem(w, r, http.StatusConflict, "organization_invitation_conflict", "A pending invitation already exists or could not be created.") return } - kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": id, "email": request.Email, "role": request.Role, "expires_at": expiresAt, "invitation_token": token, "token_returned_once": true}) + kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": id, "email": request.Email, "role": request.Role, "onboarding_method": request.OnboardingMethod, "expires_at": expiresAt, "invitation_token": token, "token_returned_once": true}) } func (s *Server) listOrganizationInvitations(w http.ResponseWriter, r *http.Request) { organizationID := chi.URLParam(r, "organization_id") - if !s.operatorBelongsToOrganization(r, organizationID) { + if !s.controlUserBelongsToOrganization(r, organizationID) { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_not_found", "The organization was not found.") return } - rows, err := s.app.DB.Query(r.Context(), `SELECT id,normalized_email,role,invited_by,accepted_by,expires_at,accepted_at,revoked_at,created_at,updated_at -FROM organization_invitations WHERE organization_id=$1 ORDER BY created_at DESC,id DESC`, organizationID) + rows, err := s.app.DB.Query(r.Context(), `SELECT id,normalized_email,role,onboarding_method,invited_by,accepted_by,expires_at,accepted_at,revoked_at,created_at,updated_at +FROM control_user_invitations WHERE organization_id=$1 ORDER BY created_at DESC,id DESC`, organizationID) if err != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Organization invitations could not be loaded.") return @@ -174,11 +188,11 @@ FROM organization_invitations WHERE organization_id=$1 ORDER BY created_at DESC, defer rows.Close() items := []map[string]any{} for rows.Next() { - var id, email, role, invitedBy string + var id, email, role, onboardingMethod, invitedBy string var acceptedBy *string var expiresAt, createdAt, updatedAt time.Time var acceptedAt, revokedAt *time.Time - if rows.Scan(&id, &email, &role, &invitedBy, &acceptedBy, &expiresAt, &acceptedAt, &revokedAt, &createdAt, &updatedAt) == nil { + if rows.Scan(&id, &email, &role, &onboardingMethod, &invitedBy, &acceptedBy, &expiresAt, &acceptedAt, &revokedAt, &createdAt, &updatedAt) == nil { status := "pending" if acceptedAt != nil { status = "accepted" @@ -187,7 +201,7 @@ FROM organization_invitations WHERE organization_id=$1 ORDER BY created_at DESC, } else if expiresAt.Before(s.app.Now()) { status = "expired" } - items = append(items, map[string]any{"id": id, "email": email, "role": role, "invited_by": invitedBy, "accepted_by": acceptedBy, + items = append(items, map[string]any{"id": id, "email": email, "role": role, "onboarding_method": onboardingMethod, "invited_by": invitedBy, "accepted_by": acceptedBy, "expires_at": expiresAt, "accepted_at": acceptedAt, "revoked_at": revokedAt, "created_at": createdAt, "updated_at": updatedAt, "status": status}) } } @@ -197,7 +211,7 @@ FROM organization_invitations WHERE organization_id=$1 ORDER BY created_at DESC, func (s *Server) resendOrganizationInvitation(w http.ResponseWriter, r *http.Request) { organizationID, invitationID := chi.URLParam(r, "organization_id"), chi.URLParam(r, "invitation_id") if _, allowed := s.organizationManagementRole(r, organizationID); !allowed { - kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The operator cannot resend organization invitations.") + kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The Platform user cannot resend organization invitations.") return } token, tokenErr := secure.RandomToken("p93_org_invite_", 32) @@ -206,15 +220,40 @@ func (s *Server) resendOrganizationInvitation(w http.ResponseWriter, r *http.Req return } tx, err := s.app.DB.Begin(r.Context()) - var email, role string + var request struct { + OnboardingMethod string `json:"onboarding_method,omitempty"` + } + if r.Body != nil && r.ContentLength != 0 && !kernel.DecodeJSON(w, r, &request) { + return + } + if request.OnboardingMethod != "" && !validControlOnboardingMethod(request.OnboardingMethod) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_onboarding_method", "Onboarding method must be email, google, or apple.") + return + } + if request.OnboardingMethod != "" && request.OnboardingMethod != "email" { + if _, err := s.loadControlAuthProvider(r, request.OnboardingMethod); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "control_auth_provider_unavailable", "The selected onboarding provider is not enabled for Platform login.") + return + } + } + var email, role, onboardingMethod string var expiresAt time.Time if err == nil { - err = tx.QueryRow(r.Context(), `UPDATE organization_invitations SET credential_digest=$1,expires_at=now()+interval '7 days',updated_at=now() -WHERE id=$2 AND organization_id=$3 AND accepted_at IS NULL AND revoked_at IS NULL RETURNING normalized_email,role,expires_at`, - s.app.Vault.Digest(token), invitationID, organizationID).Scan(&email, &role, &expiresAt) + err = tx.QueryRow(r.Context(), `UPDATE control_user_invitations SET credential_digest=$1, +onboarding_method=COALESCE(NULLIF($2,''),onboarding_method),expires_at=now()+interval '7 days',updated_at=now() +WHERE id=$3 AND organization_id=$4 AND accepted_at IS NULL AND revoked_at IS NULL RETURNING normalized_email,role,onboarding_method,expires_at`, + s.app.Vault.Digest(token), request.OnboardingMethod, invitationID, organizationID).Scan(&email, &role, &onboardingMethod, &expiresAt) } if err == nil { - err = s.queueOrganizationInvitation(r, tx, organizationID, invitationID, email, role, token, expiresAt) + _, err = tx.Exec(r.Context(), `UPDATE control_user_external_auth_challenges SET consumed_at=COALESCE(consumed_at,now()),locked_until=NULL +WHERE invitation_id=$1 AND consumed_at IS NULL`, invitationID) + } + if err == nil { + err = s.queueOrganizationInvitation(r, tx, organizationID, invitationID, email, role, onboardingMethod, token, expiresAt) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_resent", "control_user_invitation/"+invitationID, + controlInvitationEventData(invitationID, &organizationID, "", role, onboardingMethod, "pending")) } if err == nil { err = tx.Commit(r.Context()) @@ -225,18 +264,38 @@ WHERE id=$2 AND organization_id=$3 AND accepted_at IS NULL AND revoked_at IS NUL kernel.WriteProblem(w, r, http.StatusNotFound, "organization_invitation_not_found", "A pending organization invitation was not found.") return } - kernel.WriteJSON(w, http.StatusOK, map[string]any{"id": invitationID, "expires_at": expiresAt, "invitation_token": token, "token_returned_once": true}) + kernel.WriteJSON(w, http.StatusOK, map[string]any{"id": invitationID, "onboarding_method": onboardingMethod, "expires_at": expiresAt, "invitation_token": token, "token_returned_once": true}) } func (s *Server) revokeOrganizationInvitation(w http.ResponseWriter, r *http.Request) { organizationID := chi.URLParam(r, "organization_id") if _, allowed := s.organizationManagementRole(r, organizationID); !allowed { - kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The operator cannot revoke organization invitations.") + kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "The Platform user cannot revoke organization invitations.") return } - result, err := s.app.DB.Exec(r.Context(), `UPDATE organization_invitations SET revoked_at=now(),updated_at=now() + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The organization invitation could not be revoked.") + return + } + defer rollback(tx, r.Context()) + var invitedRole, onboardingMethod string + if err = tx.QueryRow(r.Context(), `SELECT role,onboarding_method FROM control_user_invitations +WHERE id=$1 AND organization_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL FOR UPDATE`, chi.URLParam(r, "invitation_id"), organizationID).Scan(&invitedRole, &onboardingMethod); err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "organization_invitation_not_found", "A pending organization invitation was not found.") + return + } + result, err := tx.Exec(r.Context(), `UPDATE control_user_invitations SET revoked_at=now(),updated_at=now() WHERE id=$1 AND organization_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL`, chi.URLParam(r, "invitation_id"), organizationID) - if err != nil || result.RowsAffected() != 1 { + if err == nil && result.RowsAffected() == 1 { + _, err = tx.Exec(r.Context(), `UPDATE control_user_external_auth_challenges SET consumed_at=COALESCE(consumed_at,now()),locked_until=NULL +WHERE invitation_id=$1 AND consumed_at IS NULL`, chi.URLParam(r, "invitation_id")) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_revoked", "control_user_invitation/"+chi.URLParam(r, "invitation_id"), + controlInvitationEventData(chi.URLParam(r, "invitation_id"), &organizationID, "", invitedRole, onboardingMethod, "revoked")) + } + if err != nil || result.RowsAffected() != 1 || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_invitation_not_found", "A pending organization invitation was not found.") return } @@ -257,52 +316,66 @@ func (s *Server) acceptOrganizationInvitation(w http.ResponseWriter, r *http.Req return } defer rollback(tx, r.Context()) - var invitationID, organizationID, email, role string - err = tx.QueryRow(r.Context(), `SELECT id,organization_id,normalized_email,role FROM organization_invitations -WHERE credential_digest=$1 AND accepted_at IS NULL AND revoked_at IS NULL AND expires_at>now() FOR UPDATE`, s.app.Vault.Digest(request.InvitationToken)). + var invitationID, email, role string + var organizationID *string + err = tx.QueryRow(r.Context(), `SELECT id,organization_id,normalized_email,role FROM control_user_invitations +WHERE credential_digest=$1 AND onboarding_method='email' AND accepted_at IS NULL AND revoked_at IS NULL AND expires_at>now() FOR UPDATE`, s.app.Vault.Digest(request.InvitationToken)). Scan(&invitationID, &organizationID, &email, &role) if err != nil { kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_organization_invitation", "The organization invitation is invalid or expired.") return } - var operatorID, status string - err = tx.QueryRow(r.Context(), `INSERT INTO operators(id,email,normalized_email,display_name) -VALUES($1,$2,$2,$3) ON CONFLICT(normalized_email) DO UPDATE SET display_name=CASE WHEN EXCLUDED.display_name='' THEN operators.display_name ELSE EXCLUDED.display_name END -RETURNING id,status`, kernel.NewID(), email, truncate(request.DisplayName, 200)).Scan(&operatorID, &status) + var controlUserID, status string + err = tx.QueryRow(r.Context(), `INSERT INTO control_users(id,email,normalized_email,display_name) +VALUES($1,$2,$2,$3) ON CONFLICT(normalized_email) DO UPDATE SET display_name=CASE WHEN EXCLUDED.display_name='' THEN control_users.display_name ELSE EXCLUDED.display_name END +RETURNING id,status`, kernel.NewID(), email, truncate(request.DisplayName, 200)).Scan(&controlUserID, &status) if err != nil || status != "active" { - kernel.WriteProblem(w, r, http.StatusConflict, "operator_account_unavailable", "The invited operator account is unavailable.") + kernel.WriteProblem(w, r, http.StatusConflict, "control_user_account_unavailable", "The invited Platform user account is unavailable.") return } - _, err = tx.Exec(r.Context(), `INSERT INTO organization_memberships(organization_id,operator_id,role) VALUES($1,$2,$3) -ON CONFLICT(organization_id,operator_id) DO UPDATE SET role=EXCLUDED.role`, organizationID, operatorID, role) + if organizationID == nil { + _, err = tx.Exec(r.Context(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,$2) +ON CONFLICT(control_user_id) DO UPDATE SET role=EXCLUDED.role,updated_at=now()`, controlUserID, role) + } else { + _, err = tx.Exec(r.Context(), `INSERT INTO organization_memberships(organization_id,control_user_id,role) VALUES($1,$2,$3) +ON CONFLICT(organization_id,control_user_id) DO UPDATE SET role=EXCLUDED.role`, *organizationID, controlUserID, role) + } + if err == nil { + _, err = tx.Exec(r.Context(), `UPDATE control_user_invitations SET accepted_by=$1,accepted_at=now(),updated_at=now() WHERE id=$2`, controlUserID, invitationID) + } if err == nil { - _, err = tx.Exec(r.Context(), `UPDATE organization_invitations SET accepted_by=$1,accepted_at=now(),updated_at=now() WHERE id=$2`, operatorID, invitationID) + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_accepted", "control_user_invitation/"+invitationID, + controlInvitationEventData(invitationID, organizationID, controlUserID, role, "email", "accepted")) } - refresh, tokenErr := secure.RandomToken("p93_ops_refresh_", 32) + if err == nil { + err = insertControlAuthAudit(r.Context(), tx, r, controlUserID, "control_user.invitation_accepted", "control_user_invitation", invitationID, + map[string]any{"provider": "email", "organization_id": organizationID, "role": role}) + } + refresh, tokenErr := secure.RandomToken("p93_control_refresh_", 32) sessionID := kernel.NewID() if err == nil && tokenErr == nil { - _, err = tx.Exec(r.Context(), `INSERT INTO operator_sessions - (id,operator_id,refresh_digest,kind,ip_address,user_agent,expires_at) VALUES($1,$2,$3,'operator',$4,$5,$6)`, sessionID, operatorID, - s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), s.app.Now().Add(12*time.Hour)) + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_sessions + (id,control_user_id,refresh_digest,kind,ip_address,user_agent,amr,expires_at) VALUES($1,$2,$3,'control',$4,$5,$6,$7)`, sessionID, controlUserID, + s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), []string{"invitation"}, s.app.Now().Add(12*time.Hour)) } // The membership and session are still uncommitted, so issue against this transaction. - access, accessErr := s.issueOperatorAccessWithQuerier(r.Context(), tx, operatorID, sessionID.String(), "operator") + access, accessErr := s.issueControlUserAccessWithQuerier(r.Context(), tx, controlUserID, sessionID.String(), "control") if err != nil || tokenErr != nil || accessErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "organization_invitation_acceptance_failed", "The organization invitation could not be accepted.") return } - s.setOperatorCookies(w, access, refresh, 12*time.Hour) - kernel.WriteJSON(w, http.StatusOK, map[string]any{"organization_id": organizationID, "operator_id": operatorID, "role": role, "access_token": access, "refresh_token": refresh, "token_type": "Bearer", "expires_in": 300}) + s.setControlUserCookies(w, access, refresh, 12*time.Hour) + kernel.WriteJSON(w, http.StatusOK, map[string]any{"organization_id": organizationID, "control_user_id": controlUserID, "role": role, "access_token": access, "refresh_token": refresh, "token_type": "Bearer", "expires_in": 300}) } -func (s *Server) queueOrganizationInvitation(r *http.Request, tx pgx.Tx, organizationID, invitationID, recipient, role, token string, expiresAt time.Time) error { +func (s *Server) queueOrganizationInvitation(r *http.Request, tx pgx.Tx, organizationID, invitationID, recipient, role, onboardingMethod, token string, expiresAt time.Time) error { notificationID := kernel.NewID() var organizationName string if err := tx.QueryRow(r.Context(), `SELECT name FROM organizations WHERE id=$1 AND deleted_at IS NULL`, organizationID).Scan(&organizationName); err != nil { return err } - invitationLink := appendCredentialQuery(strings.TrimRight(s.app.PublicURL, "/")+"/?organization_invitation=true", map[string]string{ - "invitation_id": invitationID, "invitation_token": token, + invitationLink := appendCredentialQuery(strings.TrimRight(s.app.PublicURL, "/")+"/?control_invitation=true", map[string]string{ + "invitation_id": invitationID, "invitation_token": token, "onboarding_method": onboardingMethod, }) templateID, templateLocale, payload, err := s.renderSystemNotification(r.Context(), nil, organizationInviteTemplate, recipient, map[string]any{ "organization_name": organizationName, "role": role, "invitation_link": invitationLink, @@ -327,11 +400,11 @@ func (s *Server) organizationManagementRole(r *http.Request, organizationID stri return role, true } var role string - err := s.app.DB.QueryRow(r.Context(), `SELECT role FROM organization_memberships WHERE organization_id=$1 AND operator_id=$2`, organizationID, actor(r).ID).Scan(&role) + err := s.app.DB.QueryRow(r.Context(), `SELECT role FROM organization_memberships WHERE organization_id=$1 AND control_user_id=$2`, organizationID, actor(r).ID).Scan(&role) return role, err == nil && (role == "owner" || role == "admin") } -func (s *Server) operatorBelongsToOrganization(r *http.Request, organizationID string) bool { +func (s *Server) controlUserBelongsToOrganization(r *http.Request, organizationID string) bool { if actor(r).Type == "management_client" && actorHasPermission(actor(r), managementOrganizationsScope) { return true } @@ -339,16 +412,20 @@ func (s *Server) operatorBelongsToOrganization(r *http.Request, organizationID s return true } var exists bool - _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM organization_memberships WHERE organization_id=$1 AND operator_id=$2)`, organizationID, actor(r).ID).Scan(&exists) + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM organization_memberships WHERE organization_id=$1 AND control_user_id=$2)`, organizationID, actor(r).ID).Scan(&exists) return exists } func organizationHasAnotherOwner(r *http.Request, tx pgx.Tx, organizationID, memberID string) bool { var exists bool - _ = tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM organization_memberships WHERE organization_id=$1 AND operator_id<>$2 AND role='owner')`, organizationID, memberID).Scan(&exists) + _ = tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM organization_memberships WHERE organization_id=$1 AND control_user_id<>$2 AND role='owner')`, organizationID, memberID).Scan(&exists) return exists } func validOrganizationRole(value string) bool { return value == "owner" || value == "admin" || value == "member" || value == "auditor" } + +func validControlOnboardingMethod(value string) bool { + return value == "email" || value == "google" || value == "apple" +} diff --git a/internal/httpapi/control_origin_test.go b/internal/httpapi/control_origin_test.go new file mode 100644 index 0000000..2f1c3fb --- /dev/null +++ b/internal/httpapi/control_origin_test.go @@ -0,0 +1,22 @@ +package httpapi + +import "testing" + +func TestAllowedControlOrigin(t *testing.T) { + tests := []struct { + origin, publicURL string + allowed bool + }{ + {"https://platform93.example", "https://platform93.example", true}, + {"http://127.0.0.1:8093", "http://localhost:8093", true}, + {"http://[::1]:8093", "http://localhost:8093", true}, + {"http://127.0.0.1:8094", "http://localhost:8093", false}, + {"https://127.0.0.1:8093", "http://localhost:8093", false}, + {"https://other.example", "https://platform93.example", false}, + } + for _, test := range tests { + if actual := allowedControlOrigin(test.origin, test.publicURL); actual != test.allowed { + t.Errorf("allowedControlOrigin(%q, %q) = %v, want %v", test.origin, test.publicURL, actual, test.allowed) + } + } +} diff --git a/internal/httpapi/control_rename_test.go b/internal/httpapi/control_rename_test.go index 91f4102..7c1372d 100644 --- a/internal/httpapi/control_rename_test.go +++ b/internal/httpapi/control_rename_test.go @@ -28,15 +28,15 @@ func TestOrganizationAndApplicationRename(t *testing.T) { defer db.Close() vault, _ := secure.NewVault(make([]byte, 32)) server := &Server{app: platform.New(db, vault, "https://platform93.test")} - operatorID, organizationID, applicationID := kernel.NewID(), kernel.NewID(), kernel.NewID() + controlUserID, organizationID, applicationID := kernel.NewID(), kernel.NewID(), kernel.NewID() suffix := applicationID.String() statements := []struct { query string args []any }{ - {`INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, []any{operatorID, "rename-" + suffix + "@example.test"}}, + {`INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, []any{controlUserID, "rename-" + suffix + "@example.test"}}, {`INSERT INTO organizations(id,name,slug) VALUES($1,'Before organization',$2)`, []any{organizationID, "rename-" + suffix}}, - {`INSERT INTO organization_memberships(organization_id,operator_id,role) VALUES($1,$2,'admin')`, []any{organizationID, operatorID}}, + {`INSERT INTO organization_memberships(organization_id,control_user_id,role) VALUES($1,$2,'admin')`, []any{organizationID, controlUserID}}, {`INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'Before application',$3)`, []any{applicationID, organizationID, "rename-" + suffix}}, } for _, statement := range statements { @@ -45,7 +45,7 @@ func TestOrganizationAndApplicationRename(t *testing.T) { } } - organizationRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"name": "After organization"}, map[string]string{"organization_id": organizationID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + organizationRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"name": "After organization"}, map[string]string{"organization_id": organizationID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) organizationRequest.Header.Set("If-Match", kernel.ETag(1)) response := httptest.NewRecorder() server.updateOrganization(response, organizationRequest) @@ -53,7 +53,7 @@ func TestOrganizationAndApplicationRename(t *testing.T) { t.Fatalf("organization rename failed: %d %s", response.Code, response.Body.String()) } - applicationRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"name": "After application"}, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + applicationRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"name": "After application"}, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) applicationRequest.Header.Set("If-Match", kernel.ETag(1)) response = httptest.NewRecorder() server.updateApplication(response, applicationRequest) @@ -73,7 +73,7 @@ func TestOrganizationAndApplicationRename(t *testing.T) { t.Fatalf("unexpected renamed boundaries: organization=%q/v%d application=%q/v%d", organizationName, organizationVersion, applicationName, applicationVersion) } - staleRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"name": "Stale"}, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + staleRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"name": "Stale"}, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) staleRequest.Header.Set("If-Match", kernel.ETag(1)) response = httptest.NewRecorder() server.updateApplication(response, staleRequest) diff --git a/internal/httpapi/control_retirement_test.go b/internal/httpapi/control_retirement_test.go index ca40954..12a3e94 100644 --- a/internal/httpapi/control_retirement_test.go +++ b/internal/httpapi/control_retirement_test.go @@ -28,7 +28,7 @@ func TestControlPlaneRetirementRevokesCredentialsAndRestoresBoundaries(t *testin defer db.Close() vault, _ := secure.NewVault(make([]byte, 32)) server := &Server{app: platform.New(db, vault, "https://platform93.test")} - operatorID, organizationID := kernel.NewID(), kernel.NewID() + controlUserID, organizationID := kernel.NewID(), kernel.NewID() applicationID, userID, sessionID, keyID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() connectionID, publicID := kernel.NewID(), kernel.NewID().String() suffix := applicationID.String() @@ -38,9 +38,9 @@ func TestControlPlaneRetirementRevokesCredentialsAndRestoresBoundaries(t *testin query string args []any }{ - {`INSERT INTO operators(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Lifecycle owner')`, []any{operatorID, "lifecycle-" + suffix + "@platform93.test"}}, + {`INSERT INTO control_users(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Lifecycle owner')`, []any{controlUserID, "lifecycle-" + suffix + "@platform93.test"}}, {`INSERT INTO organizations(id,name,slug) VALUES($1,'Retirement test',$2)`, []any{organizationID, "retirement-" + suffix}}, - {`INSERT INTO organization_memberships(organization_id,operator_id,role) VALUES($1,$2,'admin')`, []any{organizationID, operatorID}}, + {`INSERT INTO organization_memberships(organization_id,control_user_id,role) VALUES($1,$2,'admin')`, []any{organizationID, controlUserID}}, {`INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'Retirement test',$3)`, []any{applicationID, organizationID, "retirement-" + suffix}}, {`INSERT INTO users(id,application_id,email,normalized_email) VALUES($1,$2,$3,$3)`, []any{userID, applicationID, "user-" + suffix + "@platform93.test"}}, {`INSERT INTO user_sessions(id,application_id,user_id,refresh_digest,expires_at) VALUES($1,$2,$3,$4,now()+interval '1 day')`, []any{sessionID, applicationID, userID, []byte("session-" + suffix)}}, @@ -53,17 +53,17 @@ func TestControlPlaneRetirementRevokesCredentialsAndRestoresBoundaries(t *testin } } - organizationRequest := lifecycleRequest(t, http.MethodDelete, map[string]string{"organization_id": organizationID.String()}, operatorID.String(), 1) + organizationRequest := lifecycleRequest(t, http.MethodDelete, map[string]string{"organization_id": organizationID.String()}, controlUserID.String(), 1) response := httptest.NewRecorder() server.retireOrganization(response, organizationRequest) if response.Code != http.StatusForbidden { t.Fatalf("organization retirement accepted admin: %d %s", response.Code, response.Body.String()) } - if _, err = db.Exec(context.Background(), `UPDATE organization_memberships SET role='owner' WHERE organization_id=$1 AND operator_id=$2`, organizationID, operatorID); err != nil { + if _, err = db.Exec(context.Background(), `UPDATE organization_memberships SET role='owner' WHERE organization_id=$1 AND control_user_id=$2`, organizationID, controlUserID); err != nil { t.Fatal(err) } - applicationRequest := lifecycleRequest(t, http.MethodDelete, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, operatorID.String(), 1) + applicationRequest := lifecycleRequest(t, http.MethodDelete, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, controlUserID.String(), 1) response = httptest.NewRecorder() server.retireApplication(response, applicationRequest) if response.Code != http.StatusNoContent { @@ -86,7 +86,7 @@ WHERE e.id=$1 AND s.id=$2 AND k.id=$3`, applicationID, sessionID, keyID).Scan(&a t.Fatalf("retired application accepted provider webhook: %d %s", response.Code, response.Body.String()) } - restoreApplicationRequest := lifecycleRequest(t, http.MethodPost, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, operatorID.String(), 2) + restoreApplicationRequest := lifecycleRequest(t, http.MethodPost, map[string]string{"organization_id": organizationID.String(), "application_resource_id": applicationID.String()}, controlUserID.String(), 2) response = httptest.NewRecorder() server.restoreApplication(response, restoreApplicationRequest) if response.Code != http.StatusNoContent { @@ -102,13 +102,13 @@ WHERE e.id=$1 AND s.id=$2 AND k.id=$3`, applicationID, sessionID, keyID).Scan(&a } // The application is active again before testing organization-wide retirement. - organizationRequest = lifecycleRequest(t, http.MethodDelete, map[string]string{"organization_id": organizationID.String()}, operatorID.String(), 1) + organizationRequest = lifecycleRequest(t, http.MethodDelete, map[string]string{"organization_id": organizationID.String()}, controlUserID.String(), 1) response = httptest.NewRecorder() server.retireOrganization(response, organizationRequest) if response.Code != http.StatusNoContent { t.Fatalf("organization retirement failed: %d %s", response.Code, response.Body.String()) } - organizationRestore := lifecycleRequest(t, http.MethodPost, map[string]string{"organization_id": organizationID.String()}, operatorID.String(), 2) + organizationRestore := lifecycleRequest(t, http.MethodPost, map[string]string{"organization_id": organizationID.String()}, controlUserID.String(), 2) response = httptest.NewRecorder() server.restoreOrganization(response, organizationRestore) if response.Code != http.StatusNoContent { @@ -125,9 +125,9 @@ WHERE o.id=$1 AND e.id=$2`, organizationID, applicationID).Scan(&organizationAct } } -func lifecycleRequest(t *testing.T, method string, params map[string]string, operatorID string, version int64) *http.Request { +func lifecycleRequest(t *testing.T, method string, params map[string]string, controlUserID string, version int64) *http.Request { t.Helper() - request := requestWithRoute(t, method, "/", nil, params, kernel.Actor{Type: "operator", ID: operatorID}) + request := requestWithRoute(t, method, "/", nil, params, kernel.Actor{Type: "control_user", ID: controlUserID}) request.Header.Set("If-Match", kernel.ETag(version)) return request } diff --git a/internal/httpapi/control_user_account.go b/internal/httpapi/control_user_account.go new file mode 100644 index 0000000..fe9356f --- /dev/null +++ b/internal/httpapi/control_user_account.go @@ -0,0 +1,201 @@ +package httpapi + +import ( + "net/http" + "strings" + "sync" + "time" + + "github.com/supaapps/platform93/internal/identity" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/secure" +) + +var ( + controlUserDummyPasswordOnce sync.Once + controlUserDummyPasswordHash string +) + +func (s *Server) getControlUserAccount(w http.ResponseWriter, r *http.Request) { + var id, email, displayName, status string + var passwordEnabled bool + var createdAt, updatedAt time.Time + err := s.app.DB.QueryRow(r.Context(), `SELECT id,email,display_name,status,password_hash IS NOT NULL,created_at,updated_at +FROM control_users WHERE id=$1`, actor(r).ID).Scan(&id, &email, &displayName, &status, &passwordEnabled, &createdAt, &updatedAt) + if err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "control_user_not_found", "The signed-in Platform user account was not found.") + return + } + installationRole, hasInstallationRole := s.installationRole(r) + var installationRoleValue any + if hasInstallationRole { + installationRoleValue = installationRole + } + rows, err := s.app.DB.Query(r.Context(), `SELECT o.id,o.name,m.role FROM organization_memberships m +JOIN organizations o ON o.id=m.organization_id WHERE m.control_user_id=$1 AND o.deleted_at IS NULL ORDER BY o.name,o.id`, id) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform user organization access could not be loaded.") + return + } + defer rows.Close() + organizations := []map[string]any{} + for rows.Next() { + var organizationID, name, role string + if rows.Scan(&organizationID, &name, &role) == nil { + organizations = append(organizations, map[string]any{"id": organizationID, "name": name, "role": role}) + } + } + identityRows, identityErr := s.app.DB.Query(r.Context(), `SELECT i.id,i.provider,i.metadata,i.created_at,i.last_used_at, +p.disabled_at IS NULL AND p.control_login_enabled FROM control_user_identities i +JOIN auth_provider_configs p ON p.id=i.auth_provider_config_id WHERE i.control_user_id=$1 ORDER BY i.created_at`, id) + identities := []map[string]any{} + if identityErr == nil { + defer identityRows.Close() + for identityRows.Next() { + var identityID, provider string + var metadata map[string]any + var identityCreatedAt time.Time + var lastUsedAt *time.Time + var available bool + if identityRows.Scan(&identityID, &provider, &metadata, &identityCreatedAt, &lastUsedAt, &available) == nil { + identities = append(identities, map[string]any{"id": identityID, "provider": provider, "metadata": metadata, + "available": available, "created_at": identityCreatedAt, "last_used_at": lastUsedAt}) + } + } + } + policy, _ := s.loadControlAuthPolicy(r.Context()) + var smtp bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM notification_providers WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL)`).Scan(&smtp) + kernel.WriteJSON(w, http.StatusOK, map[string]any{ + "id": id, "email": email, "display_name": displayName, "status": status, + "installation_role": installationRoleValue, "organizations": organizations, + "sign_in_methods": map[string]any{"email_code": policy.EmailCodeEnabled && smtp, "magic_link": policy.MagicLinkEnabled && smtp, + "password": policy.PasswordEnabled && passwordEnabled, "external_identities": identities}, + "created_at": createdAt, "updated_at": updatedAt, + }) +} + +func (s *Server) updateControlUserAccount(w http.ResponseWriter, r *http.Request) { + var request struct { + DisplayName string `json:"display_name"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + request.DisplayName = strings.TrimSpace(request.DisplayName) + if request.DisplayName == "" || len(request.DisplayName) > 200 { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_control_user_profile", "Display name must contain between 1 and 200 characters.") + return + } + result, err := s.app.DB.Exec(r.Context(), `UPDATE control_users SET display_name=$1,updated_at=now() WHERE id=$2 AND status='active'`, request.DisplayName, actor(r).ID) + if err != nil || result.RowsAffected() != 1 { + kernel.WriteProblem(w, r, http.StatusNotFound, "control_user_not_found", "The signed-in Platform user account was not found.") + return + } + w.WriteHeader(http.StatusNoContent) +} + +func (s *Server) changeControlUserPassword(w http.ResponseWriter, r *http.Request) { + var request struct { + CurrentPassword string `json:"current_password"` + NewPassword string `json:"new_password"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + var currentHash *string + var sessionCreatedAt time.Time + err := s.app.DB.QueryRow(r.Context(), `SELECT o.password_hash,s.created_at FROM control_users o +JOIN control_user_sessions s ON s.control_user_id=o.id WHERE o.id=$1 AND s.id=$2 AND s.revoked_at IS NULL AND s.expires_at>now()`, actor(r).ID, actor(r).SessionID). + Scan(¤tHash, &sessionCreatedAt) + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "control_user_session_required", "An active Platform user session is required.") + return + } + if currentHash != nil { + if !identity.VerifyPassword(*currentHash, request.CurrentPassword) { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_current_password", "The current password is incorrect.") + return + } + } else if sessionCreatedAt.Before(s.app.Now().Add(-10 * time.Minute)) { + kernel.WriteProblem(w, r, http.StatusConflict, "recent_authentication_required", "Sign in again with an email code or magic link before adding a password.") + return + } + newHash, err := identity.HashPassword(request.NewPassword) + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_password", err.Error()) + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The Platform user password could not be changed.") + return + } + defer rollback(tx, r.Context()) + _, err = tx.Exec(r.Context(), `UPDATE control_users SET password_hash=$1,updated_at=now() WHERE id=$2`, newHash, actor(r).ID) + if err == nil { + _, err = tx.Exec(r.Context(), `UPDATE control_user_sessions SET revoked_at=COALESCE(revoked_at,now()) +WHERE control_user_id=$1 AND id<>$2 AND revoked_at IS NULL`, actor(r).ID, actor(r).SessionID) + } + if err != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "control_user_password_change_failed", "The Platform user password could not be committed.") + return + } + w.WriteHeader(http.StatusNoContent) +} + +func (s *Server) controlUserPasswordLogin(w http.ResponseWriter, r *http.Request) { + var request struct { + Email string `json:"email"` + Password string `json:"password"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + policy, policyErr := s.loadControlAuthPolicy(r.Context()) + if policyErr != nil || !policy.PasswordEnabled { + kernel.WriteProblem(w, r, http.StatusServiceUnavailable, "control_password_login_unavailable", "Platform password sign-in is unavailable.") + return + } + normalized := kernel.NormalizeEmail(request.Email) + if !s.allowAuthAttempt(w, r, "control_user_password", normalized, 8, 10*time.Minute) { + return + } + var controlUserID, passwordHash string + err := s.app.DB.QueryRow(r.Context(), `SELECT id,password_hash FROM control_users +WHERE normalized_email=$1 AND status='active' AND password_hash IS NOT NULL`, normalized).Scan(&controlUserID, &passwordHash) + found := err == nil + if !found { + controlUserDummyPasswordOnce.Do(func() { + controlUserDummyPasswordHash, _ = identity.HashPassword("platform93 timing equalization credential") + }) + passwordHash = controlUserDummyPasswordHash + } + validPassword := identity.VerifyPassword(passwordHash, request.Password) + if !found || !validPassword { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_control_user_credentials", "The email address or password is incorrect.") + return + } + refresh, err := secure.RandomToken("p93_control_refresh_", 32) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "credential_generation_failed", "The Platform user session could not be created.") + return + } + sessionID := kernel.NewID() + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The Platform user session could not be created.") + return + } + defer rollback(tx, r.Context()) + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_sessions +(id,control_user_id,refresh_digest,kind,ip_address,user_agent,amr,expires_at) VALUES($1,$2,$3,'control',$4,$5,$6,$7)`, + sessionID, controlUserID, s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), []string{"password"}, s.app.Now().Add(12*time.Hour)) + access, tokenErr := s.issueControlUserAccessWithQuerier(r.Context(), tx, controlUserID, sessionID.String(), "control") + if err != nil || tokenErr != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "control_user_session_failed", "The Platform user session could not be committed.") + return + } + s.setControlUserCookies(w, access, refresh, 12*time.Hour) + kernel.WriteJSON(w, http.StatusOK, map[string]any{"access_token": access, "refresh_token": refresh, "token_type": "Bearer", "expires_in": 300}) +} diff --git a/internal/httpapi/control_user_account_test.go b/internal/httpapi/control_user_account_test.go new file mode 100644 index 0000000..fa68e85 --- /dev/null +++ b/internal/httpapi/control_user_account_test.go @@ -0,0 +1,224 @@ +package httpapi + +import ( + "context" + "crypto/rsa" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "strings" + "testing" + "time" + + "github.com/supaapps/platform93/internal/database" + "github.com/supaapps/platform93/internal/identity" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/platform" + "github.com/supaapps/platform93/internal/secure" +) + +func TestControlUserAccountPasswordLifecycle(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, _ := secure.NewVault(make([]byte, 32)) + app := platform.New(db, vault, "https://platform93.test") + server := &Server{app: app} + controlUserID, sessionID := kernel.NewID(), kernel.NewID() + email := "control_user-" + controlUserID.String() + "@example.test" + refresh := "p93_control_refresh_" + controlUserID.String() + if _, err = db.Exec(context.Background(), `INSERT INTO installations(id,setup_completed_at) +SELECT $1,now() WHERE NOT EXISTS(SELECT 1 FROM installations)`, kernel.NewID()); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Test ControlUser')`, controlUserID, email); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'owner')`, controlUserID); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO control_user_sessions(id,control_user_id,refresh_digest,kind,expires_at) VALUES($1,$2,$3,'control',$4)`, sessionID, controlUserID, vault.Digest(refresh), time.Now().Add(time.Hour)); err != nil { + t.Fatal(err) + } + tx, err := db.Begin(context.Background()) + if err != nil { + t.Fatal(err) + } + if err = app.EnsureSigningKey(context.Background(), tx); err != nil { + t.Fatal(err) + } + if err = tx.Commit(context.Background()); err != nil { + t.Fatal(err) + } + current := kernel.Actor{Type: "control_user", ID: controlUserID.String(), SessionID: sessionID.String()} + + accountRequest := requestWithRoute(t, http.MethodGet, "/", nil, nil, current) + accountResponse := httptest.NewRecorder() + server.getControlUserAccount(accountResponse, accountRequest) + if accountResponse.Code != http.StatusOK || !strings.Contains(accountResponse.Body.String(), `"password":false`) || !strings.Contains(accountResponse.Body.String(), email) { + t.Fatalf("unexpected control_user account response: %d %s", accountResponse.Code, accountResponse.Body.String()) + } + + addRequest := requestWithRoute(t, http.MethodPut, "/", map[string]any{"new_password": "correct horse battery staple"}, nil, current) + addResponse := httptest.NewRecorder() + server.changeControlUserPassword(addResponse, addRequest) + if addResponse.Code != http.StatusNoContent { + t.Fatalf("first control_user password was not added: %d %s", addResponse.Code, addResponse.Body.String()) + } + var passwordHash string + if err = db.QueryRow(context.Background(), `SELECT password_hash FROM control_users WHERE id=$1`, controlUserID).Scan(&passwordHash); err != nil { + t.Fatal(err) + } + if !identity.VerifyPassword(passwordHash, "correct horse battery staple") { + t.Fatal("control_user password was not stored as a valid Argon2id hash") + } + + loginRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{"email": email, "password": "correct horse battery staple"}, nil, kernel.Actor{}) + loginResponse := httptest.NewRecorder() + server.controlUserPasswordLogin(loginResponse, loginRequest) + if loginResponse.Code != http.StatusOK || !strings.Contains(loginResponse.Header().Get("Set-Cookie"), "p93_control_access=") { + t.Fatalf("control_user password login failed: %d %s", loginResponse.Code, loginResponse.Body.String()) + } + + wrongRequest := requestWithRoute(t, http.MethodPut, "/", map[string]any{"current_password": "incorrect password value", "new_password": "another correct horse battery"}, nil, current) + wrongResponse := httptest.NewRecorder() + server.changeControlUserPassword(wrongResponse, wrongRequest) + if wrongResponse.Code != http.StatusUnauthorized { + t.Fatalf("incorrect current password was accepted: %d %s", wrongResponse.Code, wrongResponse.Body.String()) + } + + changeRequest := requestWithRoute(t, http.MethodPut, "/", map[string]any{"current_password": "correct horse battery staple", "new_password": "another correct horse battery"}, nil, current) + changeResponse := httptest.NewRecorder() + server.changeControlUserPassword(changeResponse, changeRequest) + if changeResponse.Code != http.StatusNoContent { + t.Fatalf("control_user password change failed: %d %s", changeResponse.Code, changeResponse.Body.String()) + } + var activeSessions int + if err = db.QueryRow(context.Background(), `SELECT count(*) FROM control_user_sessions WHERE control_user_id=$1 AND revoked_at IS NULL`, controlUserID).Scan(&activeSessions); err != nil { + t.Fatal(err) + } + if activeSessions != 1 { + t.Fatalf("expected only the current session after password change, got %d", activeSessions) + } +} + +func TestControlUserEmailVerificationIssuesAMRFromUncommittedSession(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, _ := secure.NewVault(make([]byte, 32)) + app := platform.New(db, vault, "https://platform93.test") + server := &Server{app: app} + controlUserID, challengeID := kernel.NewID(), kernel.NewID() + email := "email-amr-" + controlUserID.String() + "@example.test" + code := "A1B2C3D4" + if _, err = db.Exec(context.Background(), `INSERT INTO installations(id,setup_completed_at) +SELECT $1,now() WHERE NOT EXISTS(SELECT 1 FROM installations)`, kernel.NewID()); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `UPDATE installations SET control_email_code_enabled=true`); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Email AMR')`, controlUserID, email); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'auditor')`, controlUserID); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO control_user_login_challenges(id,normalized_email,code_digest,expires_at) +VALUES($1,$2,$3,now()+interval '10 minutes')`, challengeID, email, vault.Digest(code)); err != nil { + t.Fatal(err) + } + tx, err := db.Begin(context.Background()) + if err != nil { + t.Fatal(err) + } + if err = app.EnsureSigningKey(context.Background(), tx); err != nil { + t.Fatal(err) + } + if err = tx.Commit(context.Background()); err != nil { + t.Fatal(err) + } + + request := requestWithRoute(t, http.MethodPost, "/v1/control/auth/email/verify", map[string]any{ + "challenge_id": challengeID.String(), "code": code, + }, nil, kernel.Actor{}) + response := httptest.NewRecorder() + server.controlUserEmailVerify(response, request) + if response.Code != http.StatusOK { + t.Fatalf("email verification failed: %d %s", response.Code, response.Body.String()) + } + var payload struct { + AccessToken string `json:"access_token"` + } + if json.Unmarshal(response.Body.Bytes(), &payload) != nil || payload.AccessToken == "" { + t.Fatal("email verification did not return an access token") + } + claims, err := identity.Verify(payload.AccessToken, func(kid string) (*rsa.PublicKey, error) { + return app.ResolvePublicKey(context.Background(), kid) + }, app.Issuer(), app.ControlAudience(), app.Now()) + if err != nil || len(claims.AMR) != 1 || claims.AMR[0] != "email_code" { + t.Fatalf("unexpected email verification claims: %#v err=%v", claims, err) + } +} + +func TestControlAuthPolicyPreventsInstallationOwnerLockout(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, _ := secure.NewVault(make([]byte, 32)) + server := &Server{app: platform.New(db, vault, "https://platform93.test")} + controlUserID := kernel.NewID() + email := "lockout-owner-" + controlUserID.String() + "@example.test" + if _, err = db.Exec(context.Background(), `INSERT INTO installations(id,setup_completed_at) +SELECT $1,now() WHERE NOT EXISTS(SELECT 1 FROM installations)`, kernel.NewID()); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, controlUserID, email); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'owner')`, controlUserID); err != nil { + t.Fatal(err) + } + defer func() { + _, _ = db.Exec(context.Background(), `DELETE FROM installation_control_user_roles WHERE control_user_id=$1`, controlUserID) + _, _ = db.Exec(context.Background(), `DELETE FROM control_users WHERE id=$1`, controlUserID) + }() + + request := requestWithRoute(t, http.MethodPatch, "/v1/control/installation/auth-policy", map[string]any{ + "email_code_enabled": false, "magic_link_enabled": false, "password_enabled": false, + }, nil, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) + response := httptest.NewRecorder() + server.updateControlAuthPolicy(response, request) + if response.Code != http.StatusConflict || !strings.Contains(response.Body.String(), "control_auth_owner_lockout") { + t.Fatalf("owner lockout was not rejected: %d %s", response.Code, response.Body.String()) + } +} diff --git a/internal/httpapi/control_user_boundary_test.go b/internal/httpapi/control_user_boundary_test.go new file mode 100644 index 0000000..08d1b5c --- /dev/null +++ b/internal/httpapi/control_user_boundary_test.go @@ -0,0 +1,165 @@ +package httpapi + +import ( + "context" + "crypto/rsa" + "net/http" + "net/http/httptest" + "os" + "testing" + "time" + + "github.com/supaapps/platform93/internal/database" + "github.com/supaapps/platform93/internal/identity" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/platform" + "github.com/supaapps/platform93/internal/secure" +) + +func TestControlUserMiddlewareEnforcesOrganizationBoundaryAndWriteRole(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, _ := secure.NewVault(make([]byte, 32)) + server := &Server{app: platform.New(db, vault, "https://platform93.test")} + controlUserID, sessionID := kernel.NewID(), kernel.NewID() + organizationID, applicationID := kernel.NewID(), kernel.NewID() + suffix := applicationID.String() + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Boundary control_user')`, controlUserID, "boundary-"+suffix+"@example.test"); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO control_user_sessions(id,control_user_id,refresh_digest,kind,expires_at) VALUES($1,$2,$3,'control',$4)`, sessionID, controlUserID, vault.Digest("refresh-"+suffix), time.Now().Add(time.Hour)); err != nil { + t.Fatal(err) + } + tx, err := db.Begin(context.Background()) + if err != nil { + t.Fatal(err) + } + if err = server.app.EnsureSigningKey(context.Background(), tx); err != nil { + t.Fatal(err) + } + if err = tx.Commit(context.Background()); err != nil { + t.Fatal(err) + } + token, err := server.issueControlUserAccess(context.Background(), controlUserID.String(), sessionID.String(), "control") + if err != nil { + t.Fatal(err) + } + claims, err := identity.Verify(token, func(kid string) (*rsa.PublicKey, error) { + return server.app.ResolvePublicKey(context.Background(), kid) + }, server.app.Issuer(), server.app.ControlAudience(), server.app.Now()) + if err != nil { + t.Fatal(err) + } + if claims.ActorType != "control_user" || claims.TokenKind != "control" || len(claims.Audience) != 1 || claims.Audience[0] != server.app.ControlAudience() { + t.Fatalf("unexpected Platform user claims: actor_type=%q token_kind=%q audience=%v", claims.ActorType, claims.TokenKind, claims.Audience) + } + if _, err = db.Exec(context.Background(), `INSERT INTO organizations(id,name,slug) VALUES($1,'Boundary org',$2)`, organizationID, "boundary-"+suffix); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'Boundary app',$3)`, applicationID, organizationID, "boundary-"+suffix); err != nil { + t.Fatal(err) + } + + applicationCalled := false + applicationHandler := server.requireUser(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + applicationCalled = true + w.WriteHeader(http.StatusNoContent) + })) + applicationRequest := requestWithRoute(t, http.MethodGet, "/v1/applications/"+suffix+"/me", nil, map[string]string{"application_id": suffix}, kernel.Actor{}) + applicationRequest.Header.Set("Authorization", "Bearer "+token) + applicationResponse := httptest.NewRecorder() + applicationHandler.ServeHTTP(applicationResponse, applicationRequest) + if applicationResponse.Code != http.StatusUnauthorized || applicationCalled { + t.Fatalf("Platform user token authenticated an application endpoint: status=%d called=%v", applicationResponse.Code, applicationCalled) + } + + kid, privateKey, err := server.app.ActiveSigningKey(context.Background()) + if err != nil { + t.Fatal(err) + } + now := server.app.Now() + applicationToken, err := identity.Sign(privateKey, kid, identity.Claims{ + Issuer: server.app.Issuer(), Subject: kernel.NewID().String(), Audience: []string{server.app.ApplicationAudience(applicationID)}, + ExpiresAt: now.Add(5 * time.Minute).Unix(), IssuedAt: now.Unix(), NotBefore: now.Add(-time.Second).Unix(), + JWTID: kernel.NewID().String(), SessionID: kernel.NewID().String(), ApplicationID: applicationID.String(), TokenKind: "access", ActorType: "user", + Roles: identity.RoleClaims{Application: []string{}, Workspaces: map[string][]string{}}, + }) + if err != nil { + t.Fatal(err) + } + controlCalled := false + controlHandler := server.requireControlUser(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + controlCalled = true + w.WriteHeader(http.StatusNoContent) + })) + controlRequest := requestWithRoute(t, http.MethodGet, "/v1/control/organizations", nil, nil, kernel.Actor{}) + controlRequest.Header.Set("Authorization", "Bearer "+applicationToken) + controlResponse := httptest.NewRecorder() + controlHandler.ServeHTTP(controlResponse, controlRequest) + if controlResponse.Code != http.StatusUnauthorized || controlCalled { + t.Fatalf("application user token authenticated a control endpoint: status=%d called=%v", controlResponse.Code, controlCalled) + } + + called := false + handler := server.requireControlUser(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + called = true + w.WriteHeader(http.StatusNoContent) + })) + request := requestWithRoute(t, "GET", "/v1/applications/"+suffix+"/users", nil, map[string]string{"application_id": suffix}, kernel.Actor{}) + request.AddCookie(&http.Cookie{Name: "p93_control_access", Value: token}) + response := httptest.NewRecorder() + handler.ServeHTTP(response, request) + if response.Code != http.StatusNotFound || called { + t.Fatalf("control_user crossed organization boundary: status=%d called=%v", response.Code, called) + } + + if _, err = db.Exec(context.Background(), `INSERT INTO organization_memberships(organization_id,control_user_id,role) VALUES($1,$2,'auditor')`, organizationID, controlUserID); err != nil { + t.Fatal(err) + } + request = requestWithRoute(t, "POST", "/v1/applications/"+suffix+"/users", map[string]any{}, map[string]string{"application_id": suffix}, kernel.Actor{}) + request.AddCookie(&http.Cookie{Name: "p93_control_access", Value: token}) + response = httptest.NewRecorder() + handler.ServeHTTP(response, request) + if response.Code != http.StatusForbidden || called { + t.Fatalf("read-only control_user gained write access: status=%d called=%v", response.Code, called) + } + + if _, err = db.Exec(context.Background(), `UPDATE organization_memberships SET role='admin' WHERE organization_id=$1 AND control_user_id=$2`, organizationID, controlUserID); err != nil { + t.Fatal(err) + } + called = false + request = requestWithRoute(t, "POST", "/v1/control/applications/"+suffix+"/users", map[string]any{}, map[string]string{"application_id": suffix}, kernel.Actor{}) + request.AddCookie(&http.Cookie{Name: "p93_control_access", Value: token}) + response = httptest.NewRecorder() + handler.ServeHTTP(response, request) + if response.Code != http.StatusForbidden || called { + t.Fatalf("cookie-authenticated write without an Origin was accepted: status=%d called=%v", response.Code, called) + } + + request = requestWithRoute(t, "POST", "/v1/control/applications/"+suffix+"/users", map[string]any{}, map[string]string{"application_id": suffix}, kernel.Actor{}) + request.Header.Set("Origin", "https://platform93.test") + request.AddCookie(&http.Cookie{Name: "p93_control_access", Value: token}) + response = httptest.NewRecorder() + handler.ServeHTTP(response, request) + if response.Code != http.StatusNoContent || !called { + t.Fatalf("authorized control_user write failed: status=%d called=%v", response.Code, called) + } + var method, path string + if err = db.QueryRow(context.Background(), `SELECT changes->>'method',changes->>'path' FROM audit_records +WHERE actor_id=$1 AND application_id=$2 AND action='http.post' ORDER BY created_at DESC LIMIT 1`, controlUserID, applicationID).Scan(&method, &path); err != nil { + t.Fatal(err) + } + if method != http.MethodPost || path != "/v1/control/applications/"+suffix+"/users" { + t.Fatalf("unexpected audit changes: method=%q path=%q", method, path) + } +} diff --git a/internal/httpapi/control_user_invitations.go b/internal/httpapi/control_user_invitations.go new file mode 100644 index 0000000..4006cee --- /dev/null +++ b/internal/httpapi/control_user_invitations.go @@ -0,0 +1,220 @@ +package httpapi + +import ( + "net/http" + "strings" + "time" + + "github.com/go-chi/chi/v5" + "github.com/jackc/pgx/v5" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/secure" +) + +func (s *Server) createInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { + role, allowed := s.installationRole(r) + if !allowed || role != "owner" && role != "admin" { + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "An installation owner or administrator is required.") + return + } + var request struct { + Email string `json:"email"` + Role string `json:"role"` + OnboardingMethod string `json:"onboarding_method,omitempty"` + ExpiresIn int64 `json:"expires_in,omitempty"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + request.Email = kernel.NormalizeEmail(request.Email) + if request.OnboardingMethod == "" { + request.OnboardingMethod = "email" + } + if request.ExpiresIn == 0 { + request.ExpiresIn = int64((7 * 24 * time.Hour).Seconds()) + } + if !strings.Contains(request.Email, "@") || !validInstallationRole(request.Role) || !validControlOnboardingMethod(request.OnboardingMethod) || + request.ExpiresIn < 300 || request.ExpiresIn > int64((30*24*time.Hour).Seconds()) || request.Role == "owner" && role != "owner" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_installation_invitation", "Email, role, onboarding method, or expiry is invalid.") + return + } + if request.OnboardingMethod != "email" { + if _, err := s.loadControlAuthProvider(r, request.OnboardingMethod); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "control_auth_provider_unavailable", "The selected onboarding provider is not enabled for Platform login.") + return + } + } + token, _ := secure.RandomToken("p93_control_invite_", 32) + id, expiresAt := kernel.NewID(), s.app.Now().Add(time.Duration(request.ExpiresIn)*time.Second) + tx, err := s.app.DB.Begin(r.Context()) + if err == nil { + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_invitations +(id,normalized_email,role,onboarding_method,credential_digest,invited_by,expires_at) VALUES($1,$2,$3,$4,$5,$6,$7)`, + id, request.Email, request.Role, request.OnboardingMethod, s.app.Vault.Digest(token), actor(r).ID, expiresAt) + } + if err == nil { + err = s.queueControlUserInvitation(r, tx, nil, request.Email, request.Role, request.OnboardingMethod, id.String(), token, expiresAt) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_created", "control_user_invitation/"+id.String(), + controlInvitationEventData(id.String(), nil, "", request.Role, request.OnboardingMethod, "pending")) + } + if err == nil { + err = tx.Commit(r.Context()) + } else if tx != nil { + _ = tx.Rollback(r.Context()) + } + if err != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "installation_invitation_conflict", "The Platform user invitation could not be created.") + return + } + kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": id, "email": request.Email, "role": request.Role, "onboarding_method": request.OnboardingMethod, + "expires_at": expiresAt, "invitation_token": token, "token_returned_once": true}) +} + +func (s *Server) listInstallationControlUserInvitations(w http.ResponseWriter, r *http.Request) { + if _, allowed := s.installationRole(r); !allowed { + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_role_required", "An installation role is required.") + return + } + rows, err := s.app.DB.Query(r.Context(), `SELECT id,normalized_email,role,onboarding_method,invited_by,accepted_by,expires_at,accepted_at,revoked_at,created_at,updated_at +FROM control_user_invitations WHERE organization_id IS NULL ORDER BY created_at DESC,id DESC`) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform user invitations could not be loaded.") + return + } + defer rows.Close() + items := []map[string]any{} + for rows.Next() { + var id, email, role, method, invitedBy string + var acceptedBy *string + var expiresAt, createdAt, updatedAt time.Time + var acceptedAt, revokedAt *time.Time + if rows.Scan(&id, &email, &role, &method, &invitedBy, &acceptedBy, &expiresAt, &acceptedAt, &revokedAt, &createdAt, &updatedAt) == nil { + status := "pending" + if acceptedAt != nil { + status = "accepted" + } else if revokedAt != nil { + status = "revoked" + } else if expiresAt.Before(s.app.Now()) { + status = "expired" + } + items = append(items, map[string]any{"id": id, "email": email, "role": role, "onboarding_method": method, "invited_by": invitedBy, + "accepted_by": acceptedBy, "expires_at": expiresAt, "accepted_at": acceptedAt, "revoked_at": revokedAt, "created_at": createdAt, "updated_at": updatedAt, "status": status}) + } + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) +} + +func (s *Server) resendInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { + role, allowed := s.installationRole(r) + if !allowed || role != "owner" && role != "admin" { + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "An installation owner or administrator is required.") + return + } + var request struct { + OnboardingMethod string `json:"onboarding_method,omitempty"` + } + if r.Body != nil && r.ContentLength != 0 && !kernel.DecodeJSON(w, r, &request) { + return + } + if request.OnboardingMethod != "" && !validControlOnboardingMethod(request.OnboardingMethod) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_onboarding_method", "Onboarding method must be email, google, or apple.") + return + } + if request.OnboardingMethod != "" && request.OnboardingMethod != "email" { + if _, err := s.loadControlAuthProvider(r, request.OnboardingMethod); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "control_auth_provider_unavailable", "The selected onboarding provider is not enabled for Platform login.") + return + } + } + token, _ := secure.RandomToken("p93_control_invite_", 32) + tx, err := s.app.DB.Begin(r.Context()) + var email, invitedRole, method string + var expiresAt time.Time + if err == nil { + err = tx.QueryRow(r.Context(), `UPDATE control_user_invitations SET credential_digest=$1,onboarding_method=COALESCE(NULLIF($2,''),onboarding_method), +expires_at=now()+interval '7 days',updated_at=now() WHERE id=$3 AND organization_id IS NULL AND accepted_at IS NULL AND revoked_at IS NULL +RETURNING normalized_email,role,onboarding_method,expires_at`, s.app.Vault.Digest(token), request.OnboardingMethod, chi.URLParam(r, "invitation_id")).Scan(&email, &invitedRole, &method, &expiresAt) + } + if err == nil { + _, err = tx.Exec(r.Context(), `UPDATE control_user_external_auth_challenges SET consumed_at=COALESCE(consumed_at,now()),locked_until=NULL +WHERE invitation_id=$1 AND consumed_at IS NULL`, chi.URLParam(r, "invitation_id")) + } + if err == nil { + err = s.queueControlUserInvitation(r, tx, nil, email, invitedRole, method, chi.URLParam(r, "invitation_id"), token, expiresAt) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_resent", "control_user_invitation/"+chi.URLParam(r, "invitation_id"), + controlInvitationEventData(chi.URLParam(r, "invitation_id"), nil, "", invitedRole, method, "pending")) + } + if err == nil { + err = tx.Commit(r.Context()) + } else if tx != nil { + _ = tx.Rollback(r.Context()) + } + if err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "installation_invitation_not_found", "A pending Platform user invitation was not found.") + return + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"id": chi.URLParam(r, "invitation_id"), "onboarding_method": method, "expires_at": expiresAt, "invitation_token": token, "token_returned_once": true}) +} + +func (s *Server) revokeInstallationControlUserInvitation(w http.ResponseWriter, r *http.Request) { + role, allowed := s.installationRole(r) + if !allowed || role != "owner" && role != "admin" { + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "An installation owner or administrator is required.") + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The Platform user invitation could not be revoked.") + return + } + defer rollback(tx, r.Context()) + var invitedRole, method string + if err = tx.QueryRow(r.Context(), `SELECT role,onboarding_method FROM control_user_invitations +WHERE id=$1 AND organization_id IS NULL AND accepted_at IS NULL AND revoked_at IS NULL FOR UPDATE`, chi.URLParam(r, "invitation_id")).Scan(&invitedRole, &method); err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "installation_invitation_not_found", "A pending Platform user invitation was not found.") + return + } + result, err := tx.Exec(r.Context(), `UPDATE control_user_invitations SET revoked_at=now(),updated_at=now() +WHERE id=$1 AND organization_id IS NULL AND accepted_at IS NULL AND revoked_at IS NULL`, chi.URLParam(r, "invitation_id")) + if err == nil && result.RowsAffected() == 1 { + _, err = tx.Exec(r.Context(), `UPDATE control_user_external_auth_challenges SET consumed_at=COALESCE(consumed_at,now()),locked_until=NULL +WHERE invitation_id=$1 AND consumed_at IS NULL`, chi.URLParam(r, "invitation_id")) + } + if err == nil { + err = s.emitControlEvent(r.Context(), tx, r, "control_user.invitation_revoked", "control_user_invitation/"+chi.URLParam(r, "invitation_id"), + controlInvitationEventData(chi.URLParam(r, "invitation_id"), nil, "", invitedRole, method, "revoked")) + } + if err != nil || result.RowsAffected() != 1 || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "installation_invitation_not_found", "A pending Platform user invitation was not found.") + return + } + w.WriteHeader(http.StatusNoContent) +} + +func (s *Server) queueControlUserInvitation(r *http.Request, tx pgx.Tx, organizationID *string, recipient, role, method, invitationID, token string, expiresAt time.Time) error { + var smtp bool + _ = tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM notification_providers WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL)`).Scan(&smtp) + if !smtp { + return nil + } + notificationID := kernel.NewID() + link := appendCredentialQuery(strings.TrimRight(s.app.PublicURL, "/")+"/?control_invitation=true", map[string]string{ + "invitation_id": invitationID, "invitation_token": token, "onboarding_method": method, + }) + templateID, locale, payload, err := s.renderSystemNotification(r.Context(), nil, controlUserInvitationTemplate, recipient, map[string]any{ + "role": role, "onboarding_method": method, "invitation_link": link, "invitation_token": token, "expires_at": templateTimestamp(expiresAt), + }) + if err != nil { + return err + } + ciphertext, err := s.app.Vault.Encrypt(payload, "notification:"+notificationID.String()) + if err == nil { + _, err = tx.Exec(r.Context(), `INSERT INTO notifications(id,organization_id,template_id,recipient,category,locale,payload_ciphertext,status) +VALUES($1,$2,$3,$4,'security',$5,$6,'queued')`, notificationID, organizationID, templateID, recipient, locale, ciphertext) + } + return err +} diff --git a/internal/httpapi/control_user_sessions.go b/internal/httpapi/control_user_sessions.go new file mode 100644 index 0000000..901b6a1 --- /dev/null +++ b/internal/httpapi/control_user_sessions.go @@ -0,0 +1,109 @@ +package httpapi + +import ( + "encoding/json" + "net" + "net/http" + "strings" + "time" + + "github.com/go-chi/chi/v5" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/secure" +) + +func (s *Server) refreshControlUserSession(w http.ResponseWriter, r *http.Request) { + var request struct { + RefreshToken string `json:"refresh_token"` + } + if cookie, cookieErr := r.Cookie("p93_control_refresh"); cookieErr == nil { + request.RefreshToken = cookie.Value + } + if r.Body != nil && r.ContentLength != 0 { + _ = json.NewDecoder(r.Body).Decode(&request) + } + if request.RefreshToken == "" { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "control_user_refresh_required", "A Platform user refresh credential is required.") + return + } + token, err := secure.RandomToken("p93_control_refresh_", 32) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "credential_generation_failed", "The Platform user session could not be rotated.") + return + } + expiresAt := s.app.Now().Add(12 * time.Hour) + var sessionID, controlUserID string + err = s.app.DB.QueryRow(r.Context(), `UPDATE control_user_sessions SET refresh_digest=$1,expires_at=$2,last_used_at=now(),ip_address=$3,user_agent=$4 +WHERE refresh_digest=$5 AND kind='control' AND revoked_at IS NULL AND expires_at>now() +RETURNING id,control_user_id`, s.app.Vault.Digest(token), expiresAt, requestIPAddress(r), truncate(r.UserAgent(), 500), s.app.Vault.Digest(request.RefreshToken)).Scan(&sessionID, &controlUserID) + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_control_user_session", "The Platform user session could not be refreshed.") + return + } + access, err := s.issueControlUserAccess(r.Context(), controlUserID, sessionID, "control") + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "control_user_token_failed", "The Platform user access token could not be issued.") + return + } + s.setControlUserCookies(w, access, token, 12*time.Hour) + kernel.WriteJSON(w, http.StatusOK, map[string]any{"access_token": access, "refresh_token": token, "token_type": "Bearer", "expires_in": 300, "refresh_expires_at": expiresAt}) +} + +func (s *Server) listControlUserSessions(w http.ResponseWriter, r *http.Request) { + rows, err := s.app.DB.Query(r.Context(), `SELECT id,ip_address::text,user_agent,authenticated_at,amr,last_used_at,expires_at,revoked_at,created_at +FROM control_user_sessions WHERE control_user_id=$1 AND kind='control' ORDER BY created_at DESC,id DESC LIMIT 101`, actor(r).ID) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform user sessions could not be loaded.") + return + } + defer rows.Close() + items := []map[string]any{} + for rows.Next() { + var id, userAgent string + var ipAddress *string + var authenticatedAt, lastUsedAt, expiresAt, createdAt time.Time + var amr []string + var revokedAt *time.Time + if rows.Scan(&id, &ipAddress, &userAgent, &authenticatedAt, &amr, &lastUsedAt, &expiresAt, &revokedAt, &createdAt) == nil { + items = append(items, map[string]any{"id": id, "ip_address": ipAddress, "user_agent": userAgent, "last_used_at": lastUsedAt, + "authenticated_at": authenticatedAt, "amr": amr, "expires_at": expiresAt, "revoked_at": revokedAt, "created_at": createdAt, "current": id == actor(r).SessionID}) + } + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) +} + +func (s *Server) revokeControlUserSession(w http.ResponseWriter, r *http.Request) { + sessionID := chi.URLParam(r, "session_id") + result, err := s.app.DB.Exec(r.Context(), `UPDATE control_user_sessions SET revoked_at=COALESCE(revoked_at,now()) +WHERE id=$1 AND control_user_id=$2 AND kind='control'`, sessionID, actor(r).ID) + if err != nil || result.RowsAffected() != 1 { + kernel.WriteProblem(w, r, http.StatusNotFound, "control_user_session_not_found", "The Platform user session was not found.") + return + } + if sessionID == actor(r).SessionID { + s.clearControlUserCookies(w) + } + w.WriteHeader(http.StatusNoContent) +} + +func (s *Server) logoutAllControlUserSessions(w http.ResponseWriter, r *http.Request) { + _, err := s.app.DB.Exec(r.Context(), `UPDATE control_user_sessions SET revoked_at=COALESCE(revoked_at,now()) +WHERE control_user_id=$1 AND kind='control'`, actor(r).ID) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "control_user_logout_failed", "Platform user sessions could not be revoked.") + return + } + s.clearControlUserCookies(w) + w.WriteHeader(http.StatusNoContent) +} + +func requestIPAddress(r *http.Request) any { + value := strings.TrimSpace(r.RemoteAddr) + if host, _, err := net.SplitHostPort(value); err == nil { + value = host + } + if net.ParseIP(value) == nil { + return nil + } + return value +} diff --git a/internal/httpapi/cors.go b/internal/httpapi/cors.go new file mode 100644 index 0000000..df3087f --- /dev/null +++ b/internal/httpapi/cors.go @@ -0,0 +1,171 @@ +package httpapi + +import ( + "context" + "net" + "net/http" + "net/url" + "strings" + + "github.com/supaapps/platform93/internal/kernel" +) + +var corsRequestHeaders = map[string]struct{}{ + "accept": {}, "authorization": {}, "content-type": {}, "idempotency-key": {}, "if-match": {}, +} + +func (s *Server) cors(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + origin := strings.TrimSpace(r.Header.Get("Origin")) + if origin == "" { + next.ServeHTTP(w, r) + return + } + if r.URL.Path == "/oidc/.well-known/openid-configuration" || r.URL.Path == "/oidc/jwks.json" { + w.Header().Set("Access-Control-Allow-Origin", "*") + if r.Method == http.MethodOptions { + w.Header().Set("Access-Control-Allow-Methods", "GET, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Accept") + w.Header().Set("Access-Control-Max-Age", "600") + w.WriteHeader(http.StatusNoContent) + return + } + next.ServeHTTP(w, r) + return + } + applicationID := applicationIDFromAPIPath(r.URL.Path) + allowed := s.platformOriginAllowed(origin) + if !allowed && applicationID != "" { + allowed = s.applicationOriginAllowed(r.Context(), applicationID, origin) + } else if !allowed && strings.HasPrefix(r.URL.Path, "/oidc/") { + allowed = s.oauthOriginAllowed(r.Context(), origin) + } else if applicationID == "" && !strings.HasPrefix(r.URL.Path, "/oidc/") { + next.ServeHTTP(w, r) + return + } + if !allowed { + writeCORSProblem(w, r) + return + } + if r.Method == http.MethodOptions && !validCORSPreflight(r) { + writeCORSProblem(w, r) + return + } + w.Header().Set("Access-Control-Allow-Origin", origin) + w.Header().Add("Vary", "Origin") + w.Header().Set("Access-Control-Expose-Headers", "ETag, Retry-After, X-Request-ID") + if r.Method == http.MethodOptions { + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Idempotency-Key, If-Match") + w.Header().Set("Access-Control-Max-Age", "600") + w.WriteHeader(http.StatusNoContent) + return + } + next.ServeHTTP(w, r) + }) +} + +func (s *Server) platformOriginAllowed(origin string) bool { + requestOrigin, requestOK := normalizedWebOrigin(origin) + publicOrigin, publicOK := normalizedWebOrigin(s.app.PublicURL) + return requestOK && publicOK && requestOrigin == origin && requestOrigin == publicOrigin +} + +func applicationIDFromAPIPath(path string) string { + const prefix = "/v1/applications/" + if !strings.HasPrefix(path, prefix) { + return "" + } + remainder := strings.TrimPrefix(path, prefix) + if index := strings.IndexByte(remainder, '/'); index >= 0 { + return remainder[:index] + } + return remainder +} + +func (s *Server) applicationOriginAllowed(ctx context.Context, applicationID, origin string) bool { + if _, ok := normalizedWebOrigin(origin); !ok { + return false + } + if s.clientRedirectOriginAllowed(ctx, applicationID, origin) { + return true + } + var verified bool + _ = s.app.DB.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM application_domains +WHERE application_id=$1 AND verified_at IS NOT NULL AND 'https://' || hostname=$2)`, applicationID, origin).Scan(&verified) + return verified +} + +func (s *Server) oauthOriginAllowed(ctx context.Context, origin string) bool { + return s.clientRedirectOriginAllowed(ctx, "", origin) +} + +func (s *Server) clientRedirectOriginAllowed(ctx context.Context, applicationID, origin string) bool { + normalized, ok := normalizedWebOrigin(origin) + if !ok || normalized != origin { + return false + } + query := `SELECT redirect_uris,post_logout_redirect_uris FROM clients +WHERE disabled_at IS NULL AND client_type='public'` + arguments := []any{} + if applicationID != "" { + query += " AND application_id=$1" + arguments = append(arguments, applicationID) + } + rows, err := s.app.DB.Query(ctx, query, arguments...) + if err != nil { + return false + } + defer rows.Close() + for rows.Next() { + var redirects, postLogoutRedirects []string + if rows.Scan(&redirects, &postLogoutRedirects) != nil { + return false + } + for _, candidate := range append(redirects, postLogoutRedirects...) { + if candidateOrigin, valid := normalizedWebOrigin(candidate); valid && candidateOrigin == normalized { + return true + } + } + } + return false +} + +func normalizedWebOrigin(value string) (string, bool) { + parsed, err := url.Parse(value) + if err != nil || parsed.User != nil || parsed.Host == "" || parsed.Scheme != "http" && parsed.Scheme != "https" { + return "", false + } + if parsed.RawQuery != "" || parsed.Fragment != "" { + return "", false + } + host := strings.ToLower(parsed.Hostname()) + port := parsed.Port() + if port != "" && !(parsed.Scheme == "http" && port == "80") && !(parsed.Scheme == "https" && port == "443") { + host = net.JoinHostPort(host, port) + } else if strings.Contains(host, ":") { + host = "[" + host + "]" + } + return parsed.Scheme + "://" + host, true +} + +func validCORSPreflight(r *http.Request) bool { + method := strings.ToUpper(strings.TrimSpace(r.Header.Get("Access-Control-Request-Method"))) + if method != http.MethodGet && method != http.MethodPost && method != http.MethodPut && method != http.MethodPatch && method != http.MethodDelete { + return false + } + for _, header := range strings.Split(r.Header.Get("Access-Control-Request-Headers"), ",") { + header = strings.ToLower(strings.TrimSpace(header)) + if header == "" { + continue + } + if _, allowed := corsRequestHeaders[header]; !allowed { + return false + } + } + return true +} + +func writeCORSProblem(w http.ResponseWriter, r *http.Request) { + kernel.WriteProblem(w, r, http.StatusForbidden, "origin_not_allowed", "The request origin is not allowed.") +} diff --git a/internal/httpapi/cors_test.go b/internal/httpapi/cors_test.go new file mode 100644 index 0000000..ebf19f0 --- /dev/null +++ b/internal/httpapi/cors_test.go @@ -0,0 +1,99 @@ +package httpapi + +import ( + "context" + "net/http" + "net/http/httptest" + "os" + "testing" + + "github.com/supaapps/platform93/internal/database" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/platform" + "github.com/supaapps/platform93/internal/secure" +) + +func TestNormalizedWebOrigin(t *testing.T) { + tests := map[string]string{ + "https://app.example/auth/callback": "https://app.example", + "https://APP.example:443/callback": "https://app.example", + "http://localhost:3000/callback": "http://localhost:3000", + } + for input, wanted := range tests { + if actual, ok := normalizedWebOrigin(input); !ok || actual != wanted { + t.Errorf("normalizedWebOrigin(%q) = %q, %v; want %q, true", input, actual, ok, wanted) + } + } + for _, input := range []string{"null", "file:///tmp/callback", "javascript:alert(1)", "https://user@app.example/callback"} { + if _, ok := normalizedWebOrigin(input); ok { + t.Errorf("normalizedWebOrigin(%q) accepted an unsafe origin", input) + } + } +} + +func TestApplicationCORSUsesRegisteredPublicClientOrigins(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, err := secure.NewVault(make([]byte, 32)) + if err != nil { + t.Fatal(err) + } + server := &Server{app: platform.New(db, vault, "https://platform93.example")} + organizationID, applicationID, clientID := kernel.NewID(), kernel.NewID(), kernel.NewID() + suffix := clientID.String() + if _, err = db.Exec(context.Background(), `INSERT INTO organizations(id,name,slug) VALUES($1,'CORS organization',$2)`, organizationID, "cors-org-"+suffix); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'CORS application',$3)`, applicationID, organizationID, "cors-app-"+suffix); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO clients +(id,application_id,client_id,name,client_type,redirect_uris,allowed_grants,allowed_scopes) +VALUES($1,$2,$3,'Browser','public',ARRAY['https://app.example/auth/callback'],ARRAY['authorization_code'],ARRAY['openid'])`, clientID, applicationID, "cors-client-"+suffix); err != nil { + t.Fatal(err) + } + defer func() { + _, _ = db.Exec(context.Background(), `DELETE FROM clients WHERE id=$1`, clientID) + _, _ = db.Exec(context.Background(), `DELETE FROM applications WHERE id=$1`, applicationID) + _, _ = db.Exec(context.Background(), `DELETE FROM organizations WHERE id=$1`, organizationID) + }() + + handler := server.cors(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) + request := httptest.NewRequest(http.MethodOptions, "/v1/applications/"+applicationID.String()+"/public-config", nil) + request.Header.Set("Origin", "https://app.example") + request.Header.Set("Access-Control-Request-Method", "GET") + request.Header.Set("Access-Control-Request-Headers", "Authorization, Content-Type") + response := httptest.NewRecorder() + handler.ServeHTTP(response, request) + if response.Code != http.StatusNoContent || response.Header().Get("Access-Control-Allow-Origin") != "https://app.example" { + t.Fatalf("registered origin preflight failed: status=%d headers=%v body=%s", response.Code, response.Header(), response.Body.String()) + } + + request = httptest.NewRequest(http.MethodPost, "/v1/applications/"+applicationID.String()+"/auth/email/start", nil) + request.Header.Set("Origin", "https://evil.example") + response = httptest.NewRecorder() + handler.ServeHTTP(response, request) + if response.Code != http.StatusForbidden || response.Header().Get("Access-Control-Allow-Origin") != "" { + t.Fatalf("unregistered origin was not rejected: status=%d headers=%v", response.Code, response.Header()) + } + + request = httptest.NewRequest(http.MethodOptions, "/oidc/token", nil) + request.Header.Set("Origin", "https://app.example") + request.Header.Set("Access-Control-Request-Method", "POST") + request.Header.Set("Access-Control-Request-Headers", "Content-Type") + response = httptest.NewRecorder() + handler.ServeHTTP(response, request) + if response.Code != http.StatusNoContent || response.Header().Get("Access-Control-Allow-Origin") != "https://app.example" { + t.Fatalf("OIDC preflight failed: status=%d headers=%v body=%s", response.Code, response.Header(), response.Body.String()) + } +} diff --git a/internal/httpapi/delegations.go b/internal/httpapi/delegations.go index 1842cb9..23cbacb 100644 --- a/internal/httpapi/delegations.go +++ b/internal/httpapi/delegations.go @@ -8,6 +8,7 @@ import ( "github.com/go-chi/chi/v5" "github.com/google/uuid" + platformauthz "github.com/supaapps/platform93/internal/authorization" "github.com/supaapps/platform93/internal/identity" "github.com/supaapps/platform93/internal/kernel" "github.com/supaapps/platform93/internal/secure" @@ -15,7 +16,7 @@ import ( func (s *Server) createDelegation(w http.ResponseWriter, r *http.Request) { if !s.delegationEnabled(r) { - kernel.WriteProblem(w, r, http.StatusForbidden, "delegation_disabled", "Operator delegation is disabled for this application.") + kernel.WriteProblem(w, r, http.StatusForbidden, "delegation_disabled", "Platform user delegation is disabled for this application.") return } var request struct { @@ -57,8 +58,21 @@ EXISTS(SELECT 1 FROM users WHERE id=$3 AND application_id=$1 AND status='active' kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_delegation_workspace", "The target user is not a member of the selected workspace.") return } + var workspaceID *string + if request.WorkspaceID != "" { + workspaceID = &request.WorkspaceID + } + canonicalPermissions := make([]string, 0, len(request.Permissions)) + for _, permission := range request.Permissions { + canonical, canonicalErr := platformauthz.CanonicalScope(applicationID.String(), workspaceID, permission) + if canonicalErr != nil || strings.Split(permission, ":")[0] == "roles" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_delegation_permissions", "Delegated permissions must be unique lowercase ASCII colon-delimited keys; a wildcard is allowed only as the final complete segment.") + return + } + canonicalPermissions = append(canonicalPermissions, canonical) + } userPermissions := s.permissionsForWorkspace(r, applicationID, request.UserID, request.WorkspaceID) - for _, requested := range request.Permissions { + for _, requested := range canonicalPermissions { allowed := false for _, granted := range userPermissions { if permissionMatches(granted, requested) { @@ -78,10 +92,6 @@ EXISTS(SELECT 1 FROM users WHERE id=$3 AND application_id=$1 AND status='active' } id := kernel.NewID() expiresAt := s.app.Now().Add(time.Duration(request.ExpiresIn) * time.Second) - var workspaceID *string - if request.WorkspaceID != "" { - workspaceID = &request.WorkspaceID - } tx, err := s.app.DB.Begin(r.Context()) if err != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The delegation could not be created.") @@ -89,12 +99,12 @@ EXISTS(SELECT 1 FROM users WHERE id=$3 AND application_id=$1 AND status='active' } defer rollback(tx, r.Context()) _, err = tx.Exec(r.Context(), `INSERT INTO delegations -(id,application_id,operator_id,user_id,workspace_id,reason,redirect_uri,permissions,exchange_digest,expires_at) +(id,application_id,control_user_id,user_id,workspace_id,reason,redirect_uri,permissions,exchange_digest,expires_at) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, id, applicationID, actor(r).ID, request.UserID, workspaceID, - request.Reason, request.RedirectURI, request.Permissions, s.app.Vault.Digest(exchangeCode), expiresAt) + request.Reason, request.RedirectURI, canonicalPermissions, s.app.Vault.Digest(exchangeCode), expiresAt) if err == nil { _, err = s.app.Emit(r.Context(), tx, &applicationID, "delegation.created", "delegation/"+id.String(), actor(r), - map[string]any{"delegation_id": id, "user_id": request.UserID, "workspace_id": workspaceID, "permissions": request.Permissions, + map[string]any{"delegation_id": id, "user_id": request.UserID, "workspace_id": workspaceID, "permissions": canonicalPermissions, "reason": request.Reason, "expires_at": expiresAt}) } if err != nil || tx.Commit(r.Context()) != nil { @@ -107,12 +117,12 @@ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, id, applicationID, actor(r).ID, reques query.Set("exchange_code", exchangeCode) redirect.RawQuery = query.Encode() kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": id, "user_id": request.UserID, "workspace_id": workspaceID, - "permissions": request.Permissions, "reason": request.Reason, "expires_at": expiresAt, "exchange_code": exchangeCode, + "permissions": canonicalPermissions, "reason": request.Reason, "expires_at": expiresAt, "exchange_code": exchangeCode, "redirect_to": redirect.String()}) } func (s *Server) listDelegations(w http.ResponseWriter, r *http.Request) { - rows, err := s.app.DB.Query(r.Context(), `SELECT d.id,d.operator_id,d.user_id,u.email,d.workspace_id,d.reason,d.redirect_uri,d.permissions, + rows, err := s.app.DB.Query(r.Context(), `SELECT d.id,d.control_user_id,d.user_id,u.email,d.workspace_id,d.reason,d.redirect_uri,d.permissions, d.expires_at,d.exchanged_at,d.revoked_at,d.created_at FROM delegations d JOIN users u ON u.id=d.user_id WHERE d.application_id=$1 ORDER BY d.created_at DESC,d.id DESC`, chi.URLParam(r, "application_id")) if err != nil { @@ -131,7 +141,7 @@ WHERE d.application_id=$1 ORDER BY d.created_at DESC,d.id DESC`, chi.URLParam(r, } func (s *Server) getDelegation(w http.ResponseWriter, r *http.Request) { - row := s.app.DB.QueryRow(r.Context(), `SELECT d.id,d.operator_id,d.user_id,u.email,d.workspace_id,d.reason,d.redirect_uri,d.permissions, + row := s.app.DB.QueryRow(r.Context(), `SELECT d.id,d.control_user_id,d.user_id,u.email,d.workspace_id,d.reason,d.redirect_uri,d.permissions, d.expires_at,d.exchanged_at,d.revoked_at,d.created_at FROM delegations d JOIN users u ON u.id=d.user_id WHERE d.id=$1 AND d.application_id=$2`, chi.URLParam(r, "delegation_id"), chi.URLParam(r, "application_id")) item, ok := scanDelegation(row) @@ -176,7 +186,7 @@ WHERE id=$1 AND application_id=$2`, chi.URLParam(r, "delegation_id"), applicatio func (s *Server) exchangeDelegation(w http.ResponseWriter, r *http.Request) { if !s.delegationEnabled(r) { - kernel.WriteProblem(w, r, http.StatusForbidden, "delegation_disabled", "Operator delegation is disabled for this application.") + kernel.WriteProblem(w, r, http.StatusForbidden, "delegation_disabled", "Platform user delegation is disabled for this application.") return } var request struct { @@ -196,18 +206,18 @@ func (s *Server) exchangeDelegation(w http.ResponseWriter, r *http.Request) { return } defer rollback(tx, r.Context()) - var userID, operatorID string + var userID, controlUserID string var workspaceID *string var permissions []string var expiresAt time.Time var email, locale string var emailVerified, orgVerified bool - err = tx.QueryRow(r.Context(), `SELECT d.user_id,d.operator_id,d.workspace_id,d.permissions,d.expires_at,u.email,u.locale, + err = tx.QueryRow(r.Context(), `SELECT d.user_id,d.control_user_id,d.workspace_id,d.permissions,d.expires_at,u.email,u.locale, u.email_verified_at IS NOT NULL,u.is_org_verified FROM delegations d JOIN users u ON u.id=d.user_id WHERE d.id=$1 AND d.application_id=$2 AND d.exchange_digest=$3 AND d.exchanged_at IS NULL AND d.revoked_at IS NULL AND d.expires_at>now() AND u.status='active' FOR UPDATE OF d`, chi.URLParam(r, "delegation_id"), applicationID, s.app.Vault.Digest(request.ExchangeCode)). - Scan(&userID, &operatorID, &workspaceID, &permissions, &expiresAt, &email, &locale, &emailVerified, &orgVerified) + Scan(&userID, &controlUserID, &workspaceID, &permissions, &expiresAt, &email, &locale, &emailVerified, &orgVerified) if err != nil { kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_delegation_exchange", "The delegation exchange code is invalid, expired, or already used.") return @@ -251,17 +261,22 @@ AND d.exchanged_at IS NULL AND d.revoked_at IS NULL AND d.expires_at>now() AND u } var access string if err == nil && keyErr == nil { - access, err = identity.Sign(privateKey, kid, identity.Claims{Issuer: s.app.Issuer(), Subject: userID, Audience: []string{s.app.ApplicationAudience(applicationID)}, - ExpiresAt: accessExpires.Unix(), IssuedAt: now.Unix(), NotBefore: now.Add(-5 * time.Second).Unix(), JWTID: kernel.NewID().String(), - SessionID: sessionID.String(), ApplicationID: applicationID.String(), TokenKind: "access", ActorType: "user", Scope: strings.Join(permissions, " "), Email: email, Locale: locale, EmailVerified: emailVerified, - IsOrgVerified: orgVerified, AMR: []string{"delegation"}, - Actor: &identity.Actor{Subject: operatorID, Type: "operator"}}) + customClaims, claimsErr := s.customClaimsForUser(r.Context(), applicationID.String(), userID) + if claimsErr != nil { + err = claimsErr + } else { + access, err = identity.Sign(privateKey, kid, identity.Claims{Issuer: s.app.Issuer(), Subject: userID, Audience: []string{s.app.ApplicationAudience(applicationID)}, + ExpiresAt: accessExpires.Unix(), IssuedAt: now.Unix(), NotBefore: now.Add(-5 * time.Second).Unix(), JWTID: kernel.NewID().String(), + SessionID: sessionID.String(), ApplicationID: applicationID.String(), TokenKind: "access", ActorType: "user", Scope: strings.Join(permissions, " "), Email: email, Locale: locale, EmailVerified: emailVerified, + Roles: emptyRoleClaims(), IsOrgVerified: orgVerified, CustomClaims: customClaims, AMR: []string{"delegation"}, + Actor: &identity.Actor{Subject: controlUserID, Type: "control_user"}}) + } } else if keyErr != nil { err = keyErr } if err == nil { _, err = s.app.Emit(r.Context(), tx, &applicationID, "delegation.exchanged", "delegation/"+chi.URLParam(r, "delegation_id"), - map[string]any{"type": "operator", "id": operatorID}, map[string]any{"delegation_id": chi.URLParam(r, "delegation_id"), "user_id": userID}) + map[string]any{"type": "control_user", "id": controlUserID}, map[string]any{"delegation_id": chi.URLParam(r, "delegation_id"), "user_id": userID}) } if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "delegation_exchange_failed", "The delegated session could not be created.") @@ -272,12 +287,12 @@ AND d.exchanged_at IS NULL AND d.revoked_at IS NULL AND d.expires_at>now() AND u } func scanDelegation(row scanner) (map[string]any, bool) { - var id, operatorID, userID, email, reason, redirectURI string + var id, controlUserID, userID, email, reason, redirectURI string var workspaceID *string var permissions []string var expiresAt, createdAt time.Time var exchangedAt, revokedAt *time.Time - if row.Scan(&id, &operatorID, &userID, &email, &workspaceID, &reason, &redirectURI, &permissions, + if row.Scan(&id, &controlUserID, &userID, &email, &workspaceID, &reason, &redirectURI, &permissions, &expiresAt, &exchangedAt, &revokedAt, &createdAt) != nil { return nil, false } @@ -289,7 +304,7 @@ func scanDelegation(row scanner) (map[string]any, bool) { } else if exchangedAt != nil { status = "active" } - return map[string]any{"id": id, "operator_id": operatorID, "user_id": userID, "user_email": email, "workspace_id": workspaceID, + return map[string]any{"id": id, "control_user_id": controlUserID, "user_id": userID, "user_email": email, "workspace_id": workspaceID, "reason": reason, "redirect_uri": redirectURI, "permissions": permissions, "expires_at": expiresAt, "exchanged_at": exchangedAt, "revoked_at": revokedAt, "created_at": createdAt, "status": status}, true } diff --git a/internal/httpapi/entitlements.go b/internal/httpapi/entitlements.go index 6039955..8d97dac 100644 --- a/internal/httpapi/entitlements.go +++ b/internal/httpapi/entitlements.go @@ -13,15 +13,16 @@ import ( ) type grantRequest struct { - SubjectType string `json:"subject_type"` - SubjectID string `json:"subject_id"` - ProductID *string `json:"product_id"` - PriceID *string `json:"price_id"` - FeatureValues map[string]any `json:"feature_values"` - Configuration map[string]any `json:"configuration"` - StartsAt *time.Time `json:"starts_at"` - ExpiresAt *time.Time `json:"expires_at"` - Reason string `json:"reason"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + ProductID *string `json:"product_id"` + PriceID *string `json:"price_id"` + FeatureValues map[string]any `json:"feature_values"` + Configuration map[string]any `json:"configuration"` + StartsAt *time.Time `json:"starts_at"` + ExpiresAt *time.Time `json:"expires_at"` + Reason string `json:"reason"` + ExternalReference *string `json:"external_reference"` } func (s *Server) createEntitlement(w http.ResponseWriter, r *http.Request) { @@ -76,17 +77,24 @@ WHERE p.id=$1 AND p.application_id=$2 AND ($3::uuid IS NULL OR EXISTS(SELECT 1 F kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_catalog_reference", "A price cannot be selected without its product.") return } + if request.ExternalReference != nil && (strings.TrimSpace(*request.ExternalReference) == "" || len(*request.ExternalReference) > 255) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_external_reference", "External reference must contain between 1 and 255 characters.") + return + } _, err = tx.Exec(r.Context(), `INSERT INTO entitlement_grants -(id,application_id,subject_type,subject_id,product_id,price_id,source_type,feature_values,configuration,starts_at,expires_at,created_by) -VALUES ($1,$2,$3,$4,$5,$6,'manual',$7,$8,$9,$10,$11)`, id, applicationID, request.SubjectType, request.SubjectID, request.ProductID, request.PriceID, features, configuration, starts, request.ExpiresAt, actor(r).ID) +(id,application_id,subject_type,subject_id,product_id,price_id,source_type,feature_values,configuration,starts_at,expires_at,created_by,external_reference) +VALUES ($1,$2,$3,$4,$5,$6,'manual',$7,$8,$9,$10,$11,$12)`, id, applicationID, request.SubjectType, request.SubjectID, request.ProductID, request.PriceID, features, configuration, starts, request.ExpiresAt, actor(r).ID, request.ExternalReference) + if err == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.granted", "entitlement/"+id.String(), actor(r), map[string]any{"grant_id": id, "subject_type": request.SubjectType, "subject_id": request.SubjectID, "reason": request.Reason, "external_reference": request.ExternalReference, "status": "active"}) + } if err == nil { - _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.granted", "entitlement/"+id.String(), actor(r), map[string]any{"grant_id": id, "subject_type": request.SubjectType, "subject_id": request.SubjectID, "reason": request.Reason}) + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.effective_changed", request.SubjectType+"/"+request.SubjectID, actor(r), map[string]any{"subject_type": request.SubjectType, "subject_id": request.SubjectID, "grant_id": id, "external_reference": request.ExternalReference}) } if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, 409, "entitlement_creation_failed", "The entitlement could not be granted.") return } - kernel.WriteJSON(w, 201, map[string]any{"id": id, "subject_type": request.SubjectType, "subject_id": request.SubjectID, "source_type": "manual", "feature_values": request.FeatureValues, "configuration": request.Configuration, "starts_at": starts, "expires_at": request.ExpiresAt}) + kernel.WriteJSON(w, 201, map[string]any{"id": id, "subject_type": request.SubjectType, "subject_id": request.SubjectID, "source_type": "manual", "feature_values": request.FeatureValues, "configuration": request.Configuration, "starts_at": starts, "expires_at": request.ExpiresAt, "external_reference": request.ExternalReference}) } func (s *Server) listEntitlements(w http.ResponseWriter, r *http.Request) { @@ -94,7 +102,7 @@ func (s *Server) listEntitlements(w http.ResponseWriter, r *http.Request) { subjectID := r.URL.Query().Get("subject_id") rows, err := s.app.DB.Query(r.Context(), `SELECT g.id,g.subject_type,g.subject_id,g.product_id,g.price_id,g.source_type,g.source_id,g.feature_values,g.configuration,g.starts_at, COALESCE(a.expires_at,g.expires_at),CASE WHEN a.id IS NULL THEN g.revoked_at WHEN a.action='revoked' THEN a.created_at ELSE NULL END, -CASE WHEN a.id IS NULL THEN g.revocation_reason ELSE a.reason END,g.created_at +CASE WHEN a.id IS NULL THEN g.revocation_reason ELSE a.reason END,g.external_reference,g.created_at FROM entitlement_grants g LEFT JOIN LATERAL (SELECT id,action,expires_at,reason,created_at FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1) a ON true WHERE g.application_id=$1 AND ($2='' OR g.subject_type=$2) AND ($3='' OR g.subject_id=$3::uuid) @@ -110,7 +118,7 @@ ORDER BY g.created_at DESC,g.id LIMIT 101`, chi.URLParam(r, "application_id"), s func (s *Server) getEntitlement(w http.ResponseWriter, r *http.Request) { rows, err := s.app.DB.Query(r.Context(), `SELECT g.id,g.subject_type,g.subject_id,g.product_id,g.price_id,g.source_type,g.source_id,g.feature_values,g.configuration,g.starts_at, COALESCE(a.expires_at,g.expires_at),CASE WHEN a.id IS NULL THEN g.revoked_at WHEN a.action='revoked' THEN a.created_at ELSE NULL END, -CASE WHEN a.id IS NULL THEN g.revocation_reason ELSE a.reason END,g.created_at +CASE WHEN a.id IS NULL THEN g.revocation_reason ELSE a.reason END,g.external_reference,g.created_at FROM entitlement_grants g LEFT JOIN LATERAL (SELECT id,action,expires_at,reason,created_at FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1) a ON true WHERE g.id=$1 AND g.application_id=$2`, chi.URLParam(r, "entitlement_id"), chi.URLParam(r, "application_id")) @@ -163,8 +171,10 @@ func (s *Server) revokeEntitlement(w http.ResponseWriter, r *http.Request) { defer rollback(tx, r.Context()) var legacyRevoked *time.Time var latestAction *string - err = tx.QueryRow(r.Context(), `SELECT g.revoked_at,(SELECT action FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1) -FROM entitlement_grants g WHERE g.id=$1 AND g.application_id=$2 FOR UPDATE`, chi.URLParam(r, "entitlement_id"), chi.URLParam(r, "application_id")).Scan(&legacyRevoked, &latestAction) + var subjectType, subjectID string + var externalReference *string + err = tx.QueryRow(r.Context(), `SELECT g.revoked_at,(SELECT action FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1),g.subject_type,g.subject_id,g.external_reference +FROM entitlement_grants g WHERE g.id=$1 AND g.application_id=$2 FOR UPDATE`, chi.URLParam(r, "entitlement_id"), chi.URLParam(r, "application_id")).Scan(&legacyRevoked, &latestAction, &subjectType, &subjectID, &externalReference) if err != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "entitlement_not_found", "The entitlement was not found.") return @@ -174,8 +184,15 @@ FROM entitlement_grants g WHERE g.id=$1 AND g.application_id=$2 FOR UPDATE`, chi return } _, err = tx.Exec(r.Context(), `INSERT INTO entitlement_grant_actions(id,grant_id,action,reason,actor_type,actor_id) -VALUES($1,$2,'revoked',$3,'operator',$4)`, kernel.NewID(), chi.URLParam(r, "entitlement_id"), request.Reason, actor(r).ID) - if err != nil || tx.Commit(r.Context()) != nil { +VALUES($1,$2,'revoked',$3,'control_user',$4)`, kernel.NewID(), chi.URLParam(r, "entitlement_id"), request.Reason, actor(r).ID) + applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.revoked", "entitlement/"+chi.URLParam(r, "entitlement_id"), actor(r), map[string]any{"grant_id": chi.URLParam(r, "entitlement_id"), "reason": request.Reason, "external_reference": externalReference, "status": "revoked"}) + } + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.effective_changed", subjectType+"/"+subjectID, actor(r), map[string]any{"subject_type": subjectType, "subject_id": subjectID, "grant_id": chi.URLParam(r, "entitlement_id"), "external_reference": externalReference}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "entitlement_revocation_failed", "The entitlement revocation could not be committed.") return } @@ -197,8 +214,10 @@ func (s *Server) restoreEntitlement(w http.ResponseWriter, r *http.Request) { defer rollback(tx, r.Context()) var grantExpiry, legacyRevoked *time.Time var latestAction *string - err = tx.QueryRow(r.Context(), `SELECT g.expires_at,g.revoked_at,(SELECT action FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1) -FROM entitlement_grants g WHERE g.id=$1 AND g.application_id=$2 FOR UPDATE`, chi.URLParam(r, "entitlement_id"), chi.URLParam(r, "application_id")).Scan(&grantExpiry, &legacyRevoked, &latestAction) + var subjectType, subjectID string + var externalReference *string + err = tx.QueryRow(r.Context(), `SELECT g.expires_at,g.revoked_at,(SELECT action FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1),g.subject_type,g.subject_id,g.external_reference +FROM entitlement_grants g WHERE g.id=$1 AND g.application_id=$2 FOR UPDATE`, chi.URLParam(r, "entitlement_id"), chi.URLParam(r, "application_id")).Scan(&grantExpiry, &legacyRevoked, &latestAction, &subjectType, &subjectID, &externalReference) if err != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "entitlement_not_found", "The entitlement was not found.") return @@ -210,13 +229,66 @@ FROM entitlement_grants g WHERE g.id=$1 AND g.application_id=$2 FOR UPDATE`, chi _ = tx.QueryRow(r.Context(), `SELECT expires_at FROM entitlement_grant_actions WHERE grant_id=$1 AND action IN ('adjusted','restored') AND expires_at IS NOT NULL ORDER BY created_at DESC,id DESC LIMIT 1`, chi.URLParam(r, "entitlement_id")).Scan(&grantExpiry) _, err = tx.Exec(r.Context(), `INSERT INTO entitlement_grant_actions(id,grant_id,action,expires_at,reason,actor_type,actor_id) -VALUES($1,$2,'restored',$3,NULLIF($4,''),'operator',$5)`, kernel.NewID(), chi.URLParam(r, "entitlement_id"), grantExpiry, strings.TrimSpace(request.Reason), actor(r).ID) - if err != nil || tx.Commit(r.Context()) != nil { +VALUES($1,$2,'restored',$3,NULLIF($4,''),'control_user',$5)`, kernel.NewID(), chi.URLParam(r, "entitlement_id"), grantExpiry, strings.TrimSpace(request.Reason), actor(r).ID) + if err == nil { + _, err = tx.Exec(r.Context(), `UPDATE entitlement_grants SET expiration_recorded_at=NULL WHERE id=$1`, chi.URLParam(r, "entitlement_id")) + } + applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.restored", "entitlement/"+chi.URLParam(r, "entitlement_id"), actor(r), map[string]any{"grant_id": chi.URLParam(r, "entitlement_id"), "reason": strings.TrimSpace(request.Reason), "expires_at": grantExpiry, "external_reference": externalReference, "status": "active"}) + } + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.effective_changed", subjectType+"/"+subjectID, actor(r), map[string]any{"subject_type": subjectType, "subject_id": subjectID, "grant_id": chi.URLParam(r, "entitlement_id"), "external_reference": externalReference}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "entitlement_restoration_failed", "The entitlement restoration could not be committed.") return } w.WriteHeader(http.StatusNoContent) } + +func (s *Server) adjustEntitlement(w http.ResponseWriter, r *http.Request) { + var request struct { + ExpiresAt *time.Time `json:"expires_at"` + Reason string `json:"reason"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + request.Reason = strings.TrimSpace(request.Reason) + if request.Reason == "" || len(request.Reason) > 500 { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "adjustment_reason_required", "An adjustment reason of at most 500 characters is required.") + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The entitlement could not be adjusted.") + return + } + defer rollback(tx, r.Context()) + var subjectType, subjectID string + var externalReference *string + err = tx.QueryRow(r.Context(), `INSERT INTO entitlement_grant_actions(id,grant_id,action,expires_at,reason,actor_type,actor_id) +SELECT $1,id,'adjusted',$2,$3,'control_user',$4 FROM entitlement_grants WHERE id=$5 AND application_id=$6 +RETURNING (SELECT subject_type FROM entitlement_grants WHERE id=$5),(SELECT subject_id FROM entitlement_grants WHERE id=$5),(SELECT external_reference FROM entitlement_grants WHERE id=$5)`, kernel.NewID(), request.ExpiresAt, request.Reason, actor(r).ID, chi.URLParam(r, "entitlement_id"), chi.URLParam(r, "application_id")).Scan(&subjectType, &subjectID, &externalReference) + if err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "entitlement_not_found", "The entitlement was not found.") + return + } + _, err = tx.Exec(r.Context(), `UPDATE entitlement_grants SET expiration_recorded_at=NULL WHERE id=$1`, chi.URLParam(r, "entitlement_id")) + applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) + if parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.adjusted", "entitlement/"+chi.URLParam(r, "entitlement_id"), actor(r), map[string]any{"grant_id": chi.URLParam(r, "entitlement_id"), "reason": request.Reason, "expires_at": request.ExpiresAt, "external_reference": externalReference, "status": "active"}) + } + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.effective_changed", subjectType+"/"+subjectID, actor(r), map[string]any{"subject_type": subjectType, "subject_id": subjectID, "grant_id": chi.URLParam(r, "entitlement_id"), "external_reference": externalReference}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "entitlement_adjustment_failed", "The entitlement adjustment could not be committed.") + return + } + w.WriteHeader(http.StatusNoContent) +} func (s *Server) listMyEntitlements(w http.ResponseWriter, r *http.Request) { workspaceID := strings.TrimSpace(r.URL.Query().Get("workspace_id")) if workspaceID != "" && !s.userBelongsToWorkspace(r.Context(), chi.URLParam(r, "application_id"), actor(r).ID, workspaceID) { @@ -224,7 +296,7 @@ func (s *Server) listMyEntitlements(w http.ResponseWriter, r *http.Request) { return } rows, err := s.app.DB.Query(r.Context(), `SELECT g.id,g.subject_type,g.subject_id,g.product_id,g.price_id,g.source_type,g.source_id,g.feature_values,g.configuration,g.starts_at, -COALESCE(a.expires_at,g.expires_at),NULL::timestamptz,NULL::text,g.created_at +COALESCE(a.expires_at,g.expires_at),NULL::timestamptz,NULL::text,g.external_reference,g.created_at FROM entitlement_grants g LEFT JOIN LATERAL (SELECT id,action,expires_at FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1) a ON true WHERE g.application_id=$1 AND ((g.subject_type='user' AND g.subject_id=$2) OR @@ -259,11 +331,11 @@ func scanGrants(rows grantRows) []map[string]any { for rows.Next() { var id, subjectType, subjectID, sourceType string var starts, created time.Time - var productID, priceID, sourceID, reason *string + var productID, priceID, sourceID, reason, externalReference *string var expires, revoked *time.Time var features, configuration []byte - if rows.Scan(&id, &subjectType, &subjectID, &productID, &priceID, &sourceType, &sourceID, &features, &configuration, &starts, &expires, &revoked, &reason, &created) == nil { - items = append(items, map[string]any{"id": id, "subject_type": subjectType, "subject_id": subjectID, "product_id": productID, "price_id": priceID, "source_type": sourceType, "source_id": sourceID, "feature_values": decodeMap(features), "configuration": decodeMap(configuration), "starts_at": starts, "expires_at": expires, "revoked_at": revoked, "revocation_reason": reason, "created_at": created}) + if rows.Scan(&id, &subjectType, &subjectID, &productID, &priceID, &sourceType, &sourceID, &features, &configuration, &starts, &expires, &revoked, &reason, &externalReference, &created) == nil { + items = append(items, map[string]any{"id": id, "subject_type": subjectType, "subject_id": subjectID, "product_id": productID, "price_id": priceID, "source_type": sourceType, "source_id": sourceID, "feature_values": decodeMap(features), "configuration": decodeMap(configuration), "starts_at": starts, "expires_at": expires, "revoked_at": revoked, "revocation_reason": reason, "external_reference": externalReference, "created_at": created}) } } return items @@ -323,11 +395,11 @@ func entitlementProvenance(grants []map[string]any, effective map[string]any) ma func (s *Server) createLocalCheckout(w http.ResponseWriter, r *http.Request) { var request struct { - PriceID string `json:"price_id"` - SubjectType string `json:"subject_type"` - SubjectID string `json:"subject_id"` - AddressID *string `json:"address_id"` - LocalReference *string `json:"local_reference"` + PriceID string `json:"price_id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + AddressID *string `json:"address_id"` + ExternalReference *string `json:"external_reference"` } if !kernel.DecodeJSON(w, r, &request) { return @@ -348,6 +420,10 @@ func (s *Server) createLocalCheckout(w http.ResponseWriter, r *http.Request) { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_subject", "Subject type must be user or workspace.") return } + if request.ExternalReference != nil && (strings.TrimSpace(*request.ExternalReference) == "" || len(*request.ExternalReference) > 255) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_external_reference", "External reference must contain between 1 and 255 characters.") + return + } applicationID, _ := applicationID(r) tx, err := s.app.DB.Begin(r.Context()) if err != nil { @@ -387,20 +463,20 @@ FROM price_features pf JOIN features f ON f.id=pf.feature_id WHERE pf.price_id=$ } id := kernel.NewID() _, err = tx.Exec(r.Context(), `INSERT INTO local_entitlement_requests -(id,application_id,requester_user_id,subject_type,subject_id,product_id,price_id,product_snapshot,price_snapshot,feature_snapshot,address_snapshot,local_reference) -VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)`, id, applicationID, actor(r).ID, request.SubjectType, request.SubjectID, productID, request.PriceID, productSnapshot, priceSnapshot, featureSnapshot, nullableBytes(addressSnapshot), request.LocalReference) +(id,application_id,requester_user_id,subject_type,subject_id,product_id,price_id,product_snapshot,price_snapshot,feature_snapshot,address_snapshot,external_reference) +VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)`, id, applicationID, actor(r).ID, request.SubjectType, request.SubjectID, productID, request.PriceID, productSnapshot, priceSnapshot, featureSnapshot, nullableBytes(addressSnapshot), request.ExternalReference) if err == nil { _, err = tx.Exec(r.Context(), `INSERT INTO local_entitlement_request_actions(id,request_id,action,actor_type,actor_id) VALUES($1,$2,'created','user',$3)`, kernel.NewID(), id, actor(r).ID) } if err == nil { - _, err = s.app.Emit(r.Context(), tx, &applicationID, "local_entitlement_request.created", "local_entitlement_request/"+id.String(), actor(r), map[string]any{"request_id": id, "subject_type": request.SubjectType, "subject_id": request.SubjectID, "price_id": request.PriceID}) + _, err = s.app.Emit(r.Context(), tx, &applicationID, "local_entitlement_request.created", "local_entitlement_request/"+id.String(), actor(r), map[string]any{"request_id": id, "subject_type": request.SubjectType, "subject_id": request.SubjectID, "price_id": request.PriceID, "external_reference": request.ExternalReference}) } if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, 409, "local_request_creation_failed", "The local entitlement request could not be created.") return } - kernel.WriteJSON(w, 201, map[string]any{"id": id, "status": "pending", "subject_type": request.SubjectType, "subject_id": request.SubjectID, "product_snapshot": decodeMap(productSnapshot), "price_snapshot": decodeMap(priceSnapshot), "feature_snapshot": decodeMap(featureSnapshot), "address_snapshot": nullableDecoded(addressSnapshot), "local_reference": request.LocalReference}) + kernel.WriteJSON(w, 201, map[string]any{"id": id, "status": "pending", "subject_type": request.SubjectType, "subject_id": request.SubjectID, "product_snapshot": decodeMap(productSnapshot), "price_snapshot": decodeMap(priceSnapshot), "feature_snapshot": decodeMap(featureSnapshot), "address_snapshot": nullableDecoded(addressSnapshot), "external_reference": request.ExternalReference}) } func (s *Server) listMyLocalRequests(w http.ResponseWriter, r *http.Request) { @@ -420,7 +496,7 @@ func (s *Server) adminGetLocalRequest(w http.ResponseWriter, r *http.Request) { func (s *Server) getLocalRequest(w http.ResponseWriter, r *http.Request, own bool) { query := `SELECT id,requester_user_id,subject_type,subject_id,product_id,price_id,product_snapshot,price_snapshot,feature_snapshot,address_snapshot, -local_reference,status,decision_reason,reviewed_by,reviewed_at,entitlement_grant_id,created_at,updated_at +external_reference,status,decision_reason,reviewed_by,reviewed_at,entitlement_grant_id,created_at,updated_at FROM local_entitlement_requests WHERE id=$1 AND application_id=$2` args := []any{chi.URLParam(r, "request_id"), chi.URLParam(r, "application_id")} if own { @@ -456,7 +532,7 @@ FROM local_entitlement_request_actions WHERE request_id=$1 ORDER BY created_at,i kernel.WriteJSON(w, http.StatusOK, items[0]) } func (s *Server) listLocalRequests(w http.ResponseWriter, r *http.Request, own bool) { - query := `SELECT id,requester_user_id,subject_type,subject_id,product_id,price_id,product_snapshot,price_snapshot,feature_snapshot,address_snapshot,local_reference,status,decision_reason,reviewed_by,reviewed_at,entitlement_grant_id,created_at,updated_at FROM local_entitlement_requests WHERE application_id=$1` + query := `SELECT id,requester_user_id,subject_type,subject_id,product_id,price_id,product_snapshot,price_snapshot,feature_snapshot,address_snapshot,external_reference,status,decision_reason,reviewed_by,reviewed_at,entitlement_grant_id,created_at,updated_at FROM local_entitlement_requests WHERE application_id=$1` args := []any{chi.URLParam(r, "application_id")} if own { query += ` AND requester_user_id=$2` @@ -487,10 +563,10 @@ func scanLocalRequests(rows localRows) []map[string]any { var id, requester, subjectType, subjectID, productID, priceID, status string var created, updated time.Time var product, price, features, address []byte - var localRef, reason, reviewer, grant *string + var externalRef, reason, reviewer, grant *string var reviewed *time.Time - if rows.Scan(&id, &requester, &subjectType, &subjectID, &productID, &priceID, &product, &price, &features, &address, &localRef, &status, &reason, &reviewer, &reviewed, &grant, &created, &updated) == nil { - items = append(items, map[string]any{"id": id, "requester_user_id": requester, "subject_type": subjectType, "subject_id": subjectID, "product_id": productID, "price_id": priceID, "product_snapshot": decodeMap(product), "price_snapshot": decodeMap(price), "feature_snapshot": decodeMap(features), "address_snapshot": nullableDecoded(address), "local_reference": localRef, "status": status, "decision_reason": reason, "reviewed_by": reviewer, "reviewed_at": reviewed, "entitlement_grant_id": grant, "created_at": created, "updated_at": updated}) + if rows.Scan(&id, &requester, &subjectType, &subjectID, &productID, &priceID, &product, &price, &features, &address, &externalRef, &status, &reason, &reviewer, &reviewed, &grant, &created, &updated) == nil { + items = append(items, map[string]any{"id": id, "requester_user_id": requester, "subject_type": subjectType, "subject_id": subjectID, "product_id": productID, "price_id": priceID, "product_snapshot": decodeMap(product), "price_snapshot": decodeMap(price), "feature_snapshot": decodeMap(features), "address_snapshot": nullableDecoded(address), "external_reference": externalRef, "status": status, "decision_reason": reason, "reviewed_by": reviewer, "reviewed_at": reviewed, "entitlement_grant_id": grant, "created_at": created, "updated_at": updated}) } } return items @@ -510,8 +586,9 @@ func (s *Server) approveLocalRequest(w http.ResponseWriter, r *http.Request) { } defer rollback(tx, r.Context()) var subjectType, subjectID, productID, priceID, status string + var externalReference *string var priceSnapshot, featureSnapshot []byte - err = tx.QueryRow(r.Context(), `SELECT subject_type,subject_id,product_id,price_id,status,price_snapshot,feature_snapshot FROM local_entitlement_requests WHERE id=$1 AND application_id=$2 FOR UPDATE`, chi.URLParam(r, "request_id"), applicationID).Scan(&subjectType, &subjectID, &productID, &priceID, &status, &priceSnapshot, &featureSnapshot) + err = tx.QueryRow(r.Context(), `SELECT subject_type,subject_id,product_id,price_id,status,price_snapshot,feature_snapshot,external_reference FROM local_entitlement_requests WHERE id=$1 AND application_id=$2 FOR UPDATE`, chi.URLParam(r, "request_id"), applicationID).Scan(&subjectType, &subjectID, &productID, &priceID, &status, &priceSnapshot, &featureSnapshot, &externalReference) if err != nil || status != "pending" { kernel.WriteProblem(w, r, 409, "local_request_not_pending", "The local request is not pending.") return @@ -529,16 +606,22 @@ func (s *Server) approveLocalRequest(w http.ResponseWriter, r *http.Request) { expires = s.app.Now().Add(time.Duration(*snapshot.ValiditySeconds) * time.Second) } _, err = tx.Exec(r.Context(), `INSERT INTO entitlement_grants -(id,application_id,subject_type,subject_id,product_id,price_id,source_type,source_id,feature_values,configuration,starts_at,expires_at,created_by) VALUES ($1,$2,$3,$4,$5,$6,'local_request',$7,$8,$9,now(),$10,$11)`, grantID, applicationID, subjectType, subjectID, productID, priceID, chi.URLParam(r, "request_id"), features, configuration, expires, actor(r).ID) +(id,application_id,subject_type,subject_id,product_id,price_id,source_type,source_id,feature_values,configuration,starts_at,expires_at,created_by,external_reference) VALUES ($1,$2,$3,$4,$5,$6,'local_request',$7,$8,$9,now(),$10,$11,$12)`, grantID, applicationID, subjectType, subjectID, productID, priceID, chi.URLParam(r, "request_id"), features, configuration, expires, actor(r).ID, externalReference) if err == nil { _, err = tx.Exec(r.Context(), `UPDATE local_entitlement_requests SET status='approved',decision_reason=$1,reviewed_by=$2,reviewed_at=now(),entitlement_grant_id=$3,updated_at=now() WHERE id=$4`, request.Reason, actor(r).ID, grantID, chi.URLParam(r, "request_id")) } if err == nil { _, err = tx.Exec(r.Context(), `INSERT INTO local_entitlement_request_actions(id,request_id,action,actor_type,actor_id,reason) -VALUES($1,$2,'approved','operator',$3,NULLIF($4,''))`, kernel.NewID(), chi.URLParam(r, "request_id"), actor(r).ID, request.Reason) +VALUES($1,$2,'approved','control_user',$3,NULLIF($4,''))`, kernel.NewID(), chi.URLParam(r, "request_id"), actor(r).ID, request.Reason) + } + if err == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "local_entitlement_request.approved", "local_entitlement_request/"+chi.URLParam(r, "request_id"), actor(r), map[string]any{"request_id": chi.URLParam(r, "request_id"), "grant_id": grantID, "external_reference": externalReference}) + } + if err == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.granted", "entitlement/"+grantID.String(), actor(r), map[string]any{"grant_id": grantID, "subject_type": subjectType, "subject_id": subjectID, "reason": "local_request_approved", "external_reference": externalReference, "status": "active"}) } if err == nil { - _, err = s.app.Emit(r.Context(), tx, &applicationID, "local_entitlement_request.approved", "local_entitlement_request/"+chi.URLParam(r, "request_id"), actor(r), map[string]any{"request_id": chi.URLParam(r, "request_id"), "grant_id": grantID}) + _, err = s.app.Emit(r.Context(), tx, &applicationID, "entitlement.effective_changed", subjectType+"/"+subjectID, actor(r), map[string]any{"subject_type": subjectType, "subject_id": subjectID, "grant_id": grantID, "external_reference": externalReference}) } if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, 500, "local_request_approval_failed", "The local request could not be approved.") @@ -566,7 +649,7 @@ func (s *Server) rejectLocalRequest(w http.ResponseWriter, r *http.Request) { return } _, err = tx.Exec(r.Context(), `INSERT INTO local_entitlement_request_actions(id,request_id,action,actor_type,actor_id,reason) -VALUES($1,$2,'rejected','operator',$3,NULLIF($4,''))`, kernel.NewID(), chi.URLParam(r, "request_id"), actor(r).ID, request.Reason) +VALUES($1,$2,'rejected','control_user',$3,NULLIF($4,''))`, kernel.NewID(), chi.URLParam(r, "request_id"), actor(r).ID, request.Reason) if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "local_request_rejection_failed", "The local request rejection could not be committed.") return @@ -618,7 +701,7 @@ WHERE id=$1 AND application_id=$2 AND status IN ('rejected','canceled')`, chi.UR return } _, err = tx.Exec(r.Context(), `INSERT INTO local_entitlement_request_actions(id,request_id,action,actor_type,actor_id,reason) -VALUES($1,$2,'reopened','operator',$3,$4)`, kernel.NewID(), chi.URLParam(r, "request_id"), actor(r).ID, request.Reason) +VALUES($1,$2,'reopened','control_user',$3,$4)`, kernel.NewID(), chi.URLParam(r, "request_id"), actor(r).ID, request.Reason) if err != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "local_request_reopen_failed", "The local request could not be reopened.") return diff --git a/internal/httpapi/event_types.go b/internal/httpapi/event_types.go index 4c3bd9f..dd27873 100644 --- a/internal/httpapi/event_types.go +++ b/internal/httpapi/event_types.go @@ -336,7 +336,7 @@ func eventTypeDefinitionResponse(id, applicationID, name, description, schemaVer "specversion": "1.0", "id": "01900000-0000-7000-8000-000000000099", "source": "platform93://applications/" + applicationID, "type": name, "contract_source": source, "time": "2026-01-01T00:00:00Z", "application_id": applicationID, "schema_version": schemaVersion, - "subject": exampleSubject, "actor": map[string]any{"type": "operator", "id": "01900000-0000-7000-8000-000000000098"}, + "subject": exampleSubject, "actor": map[string]any{"type": "control_user", "id": "01900000-0000-7000-8000-000000000098"}, "correlation_id": nil, "causation_id": nil, "data": exampleData, } return map[string]any{"id": id, "name": name, "description": description, "schema_version": schemaVersion, diff --git a/internal/httpapi/event_types_test.go b/internal/httpapi/event_types_test.go index 85dc41f..24a4bde 100644 --- a/internal/httpapi/event_types_test.go +++ b/internal/httpapi/event_types_test.go @@ -89,8 +89,8 @@ FROM event_type_definitions WHERE application_id IS NULL AND source='platform93' if err = rows.Err(); err != nil { t.Fatal(err) } - if count != 34 { - t.Fatalf("expected 34 built-in event contracts, got %d", count) + if count != 67 { + t.Fatalf("expected 67 built-in event contracts, got %d", count) } } @@ -154,6 +154,7 @@ func TestRegisteredCustomEventCreatesTransactionalOutboxRecord(t *testing.T) { ExpiresAt: now.Add(5 * time.Minute).Unix(), IssuedAt: now.Unix(), NotBefore: now.Add(-time.Second).Unix(), JWTID: kernel.NewID().String(), ApplicationID: applicationID.String(), ClientID: clientID, TokenKind: "machine", ActorType: "client", Scope: "/applications/" + applicationID.String() + "/events/publish", + Roles: identity.RoleClaims{Application: []string{}, Workspaces: map[string][]string{}}, }) if err != nil { t.Fatal(err) diff --git a/internal/httpapi/external_auth_callback_test.go b/internal/httpapi/external_auth_callback_test.go new file mode 100644 index 0000000..de30b2c --- /dev/null +++ b/internal/httpapi/external_auth_callback_test.go @@ -0,0 +1,80 @@ +package httpapi + +import ( + "context" + "net/http" + "net/http/httptest" + "os" + "testing" + "time" + + "github.com/go-chi/chi/v5" + "github.com/supaapps/platform93/internal/database" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/platform" + "github.com/supaapps/platform93/internal/secure" +) + +func TestExternalAuthCallbackURIIsInstallationWide(t *testing.T) { + server := &Server{app: &platform.App{PublicURL: "https://platform93.example"}} + if got, want := server.externalAuthCallbackURI("google"), "https://platform93.example/v1/auth/providers/google/callback"; got != want { + t.Fatalf("callback URI = %q, want %q", got, want) + } +} + +func TestExternalAuthCallbackResolvesApplicationFromState(t *testing.T) { + databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") + if databaseURL == "" { + t.Skip("PLATFORM93_DATABASE_URL is not configured") + } + if err := database.Migrate(databaseURL); err != nil { + t.Fatal(err) + } + db, err := database.Open(context.Background(), databaseURL) + if err != nil { + t.Fatal(err) + } + defer db.Close() + vault, err := secure.NewVault(make([]byte, 32)) + if err != nil { + t.Fatal(err) + } + server := &Server{app: platform.New(db, vault, "https://platform93.example")} + organizationID, applicationID, challengeID := kernel.NewID(), kernel.NewID(), kernel.NewID() + suffix := challengeID.String() + if _, err = db.Exec(context.Background(), `INSERT INTO organizations(id,name,slug) VALUES($1,'Callback organization',$2)`, organizationID, "callback-org-"+suffix); err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'Callback application',$3)`, applicationID, organizationID, "callback-app-"+suffix); err != nil { + t.Fatal(err) + } + state := "p93_callback_state_" + suffix + ciphertext, err := vault.Encrypt([]byte("verifier"), "external-auth:"+challengeID.String()) + if err != nil { + t.Fatal(err) + } + if _, err = db.Exec(context.Background(), `INSERT INTO external_auth_challenges +(id,application_id,provider,flow,app_redirect_uri,state_digest,nonce_digest,verifier_ciphertext,expires_at) +VALUES($1,$2,'google','automatic','https://app.example/callback',$3,$4,$5,$6)`, challengeID, applicationID, vault.Digest(state), vault.Digest("nonce"), ciphertext, time.Now().Add(time.Minute)); err != nil { + t.Fatal(err) + } + defer func() { + _, _ = db.Exec(context.Background(), `DELETE FROM external_auth_challenges WHERE id=$1`, challengeID) + _, _ = db.Exec(context.Background(), `DELETE FROM applications WHERE id=$1`, applicationID) + _, _ = db.Exec(context.Background(), `DELETE FROM organizations WHERE id=$1`, organizationID) + }() + + request := httptest.NewRequest(http.MethodGet, "/v1/auth/providers/google/callback?state="+state, nil) + request = request.WithContext(context.WithValue(request.Context(), chi.RouteCtxKey, chi.NewRouteContext())) + response := httptest.NewRecorder() + resolvedApplicationID := "" + server.routeExternalAuthCallback(response, request, "google", func(_ http.ResponseWriter, callbackRequest *http.Request) { + resolvedApplicationID = chi.URLParam(callbackRequest, "application_id") + }) + if response.Code != http.StatusOK { + t.Fatalf("callback router returned %d: %s", response.Code, response.Body.String()) + } + if resolvedApplicationID != applicationID.String() { + t.Fatalf("resolved application = %q, want %q", resolvedApplicationID, applicationID) + } +} diff --git a/internal/httpapi/google_auth.go b/internal/httpapi/google_auth.go index 493583d..b032948 100644 --- a/internal/httpapi/google_auth.go +++ b/internal/httpapi/google_auth.go @@ -47,7 +47,7 @@ SET ciphertext=EXCLUDED.ciphertext,metadata=EXCLUDED.metadata,updated_at=now()`, return } kernel.WriteJSON(w, http.StatusOK, map[string]any{"provider": "google", "client_id": request.ClientID, - "callback_uri": s.googleCallbackURI(applicationID), "configured": true}) + "callback_uri": s.googleCallbackURI(), "configured": true}) } func (s *Server) listAuthProvidersLegacy(w http.ResponseWriter, r *http.Request) { @@ -65,6 +65,38 @@ func (s *Server) startGoogleAuth(w http.ResponseWriter, r *http.Request) { s.startGoogleAuthFlow(w, r, "", "") } +func (s *Server) routeGoogleCallback(w http.ResponseWriter, r *http.Request) { + s.routeExternalAuthCallback(w, r, "google", s.googleCallback) +} + +func (s *Server) routeAppleCallback(w http.ResponseWriter, r *http.Request) { + s.routeExternalAuthCallback(w, r, "apple", s.appleCallback) +} + +func (s *Server) routeExternalAuthCallback(w http.ResponseWriter, r *http.Request, provider string, callback http.HandlerFunc) { + if err := r.ParseForm(); err != nil { + kernel.WriteProblem(w, r, http.StatusBadRequest, "invalid_external_auth_response", "The external authentication callback is invalid.") + return + } + state := r.Form.Get("state") + if state == "" { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_external_auth_state", "The external authentication state is invalid or expired.") + return + } + if s.routeControlExternalCallback(w, r, provider, state) { + return + } + var applicationID string + err := s.app.DB.QueryRow(r.Context(), `SELECT application_id FROM external_auth_challenges +WHERE provider=$1 AND state_digest=$2 AND consumed_at IS NULL AND expires_at>now()`, provider, s.app.Vault.Digest(state)).Scan(&applicationID) + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_external_auth_state", "The external authentication state is invalid or expired.") + return + } + chi.RouteContext(r.Context()).URLParams.Add("application_id", applicationID) + callback(w, r) +} + func (s *Server) startGoogleLink(w http.ResponseWriter, r *http.Request) { s.startGoogleAuthFlow(w, r, "link", actor(r).ID) } @@ -92,9 +124,14 @@ func (s *Server) startGoogleAuthFlow(w http.ResponseWriter, r *http.Request, for kernel.WriteProblem(w, r, http.StatusUnauthorized, "authenticated_link_required", "Linking Google requires a directly authenticated user session.") return } + if err := validateRedirectURI(request.RedirectURI, true); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "redirect_uri_not_allowed", "The redirect URI is invalid or unsafe.") + return + } var redirectAllowed bool _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM clients -WHERE application_id=$1 AND disabled_at IS NULL AND $2=ANY(redirect_uris))`, chi.URLParam(r, "application_id"), request.RedirectURI).Scan(&redirectAllowed) +WHERE application_id=$1 AND disabled_at IS NULL AND $2=ANY(redirect_uris) +AND (NOT $3 OR client_type='public'))`, chi.URLParam(r, "application_id"), request.RedirectURI, isNativeRedirectURI(request.RedirectURI)).Scan(&redirectAllowed) if !redirectAllowed { kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "redirect_uri_not_allowed", "The redirect URI must exactly match an enabled client redirect URI.") return @@ -123,7 +160,7 @@ VALUES ($1,$2,'google',$3,$4,$5,$6,$7,$8,$9)`, challengeID, chi.URLParam(r, "app kernel.WriteProblem(w, r, http.StatusInternalServerError, "google_auth_start_failed", "The Google authentication flow could not be started.") return } - config := s.googleOAuthConfig(chi.URLParam(r, "application_id"), provider) + config := s.googleOAuthConfig(provider) options := []oauth2.AuthCodeOption{oauth2.S256ChallengeOption(verifier), oauth2.SetAuthURLParam("nonce", nonce), oauth2.SetAuthURLParam("prompt", "select_account")} if request.LoginHint != "" { options = append(options, oauth2.SetAuthURLParam("login_hint", request.LoginHint)) @@ -160,7 +197,7 @@ AND (locked_until IS NULL OR locked_until 200 || platformauthz.ValidateScopeValues(request.Scopes, applicationID.String()) != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_api_key_scopes", "API key scopes must be unique canonical permissions from this application and cannot contain whitespace or malformed paths.") + return + } + liveScopes := s.permissions(r, applicationID, actor(r).ID) + for _, requested := range request.Scopes { + if !containsAllowedScope(liveScopes, requested) { + kernel.WriteProblem(w, r, http.StatusForbidden, "api_key_scope_escalation", "API key scopes must reduce the user's current effective access.") + return + } + } token, _ := secure.RandomToken("p93_pat_", 32) id := kernel.NewID() prefix := truncate(token, 16) expires := s.app.Now().Add(time.Duration(request.ExpiresInDays) * 24 * time.Hour) - _, err := s.app.DB.Exec(r.Context(), `INSERT INTO personal_api_keys + _, err = s.app.DB.Exec(r.Context(), `INSERT INTO personal_api_keys (id,application_id,user_id,label,token_prefix,token_digest,scopes,expires_at) VALUES ($1,$2,$3,$4,$5,$6,$7,$8)`, id, chi.URLParam(r, "application_id"), actor(r).ID, request.Label, prefix, s.app.Vault.Digest(token), request.Scopes, expires) if err != nil { kernel.WriteProblem(w, r, 500, "api_key_creation_failed", "The API key could not be created.") @@ -792,7 +891,7 @@ func (s *Server) discovery(w http.ResponseWriter, r *http.Request) { "code_challenge_methods_supported": []string{"S256"}, "id_token_signing_alg_values_supported": []string{"RS256"}, "token_endpoint_auth_methods_supported": []string{"none", "client_secret_basic", "client_secret_post"}, "scopes_supported": []string{"openid", "profile", "email", "offline_access"}, "subject_types_supported": []string{"public"}, - "claims_supported": []string{"sub", "iss", "aud", "exp", "iat", "auth_time", "nonce", "actor_type", "application_id", "scope", "email", "email_verified", "given_name", "family_name", "locale", "is_org_verified"}, + "claims_supported": []string{"sub", "iss", "aud", "exp", "iat", "auth_time", "nonce", "actor_type", "application_id", "scope", "roles", "email", "email_verified", "given_name", "family_name", "locale", "is_org_verified", "custom_claims"}, }) } @@ -842,12 +941,39 @@ func scanUser(row scanner) (userResponse, bool) { return u, true } +type effectiveAccess struct { + Scopes []string + Roles identity.RoleClaims + Provenance []scopeProvenance +} + +type scopeProvenance struct { + Scope string `json:"scope"` + Source string `json:"source"` + RoleKey string `json:"role_key,omitempty"` + GrantID string `json:"grant_id,omitempty"` + WorkspaceID *string `json:"workspace_id,omitempty"` + Permission string `json:"permission,omitempty"` +} + +func emptyRoleClaims() identity.RoleClaims { + return identity.RoleClaims{Application: []string{}, Workspaces: map[string][]string{}} +} + func (s *Server) permissions(r *http.Request, applicationID uuid.UUID, userID string) []string { - return s.scopes(r, applicationID, userID) + access, err := s.userEffectiveAccess(r, applicationID, userID) + if err != nil { + return []string{} + } + return access.Scopes } func (s *Server) permissionsForWorkspace(r *http.Request, applicationID uuid.UUID, userID, workspaceID string) []string { - values := s.scopes(r, applicationID, userID) + access, err := s.userEffectiveAccess(r, applicationID, userID) + if err != nil { + return []string{} + } + values := access.Scopes if workspaceID == "" { return values } @@ -863,46 +989,82 @@ func (s *Server) permissionsForWorkspace(r *http.Request, applicationID uuid.UUI } func (s *Server) scopes(r *http.Request, applicationID uuid.UUID, userID string) []string { + access, err := s.userEffectiveAccess(r, applicationID, userID) + if err != nil { + return []string{} + } + return access.Scopes +} + +func (s *Server) userEffectiveAccess(r *http.Request, applicationID uuid.UUID, userID string) (effectiveAccess, error) { rows, err := s.app.DB.Query(r.Context(), `SELECT ro.key,ro.scope,ro.permissions,ra.workspace_id::text FROM role_assignments ra JOIN roles ro ON ro.id=ra.role_id WHERE ra.application_id=$1 AND ra.user_id=$2 ORDER BY ra.created_at,ra.id`, applicationID, userID) if err != nil { - return []string{} + return effectiveAccess{}, err } defer rows.Close() - applicationPrefix := "/applications/" + applicationID.String() set := map[string]struct{}{} + provenance := []scopeProvenance{} + roles := emptyRoleClaims() for rows.Next() { var roleKey, roleScope string var permissions []string var workspaceID *string - if rows.Scan(&roleKey, &roleScope, &permissions, &workspaceID) != nil { - continue + if scanErr := rows.Scan(&roleKey, &roleScope, &permissions, &workspaceID); scanErr != nil { + return effectiveAccess{}, scanErr } - prefix := applicationPrefix - marker := prefix + "/roles/" + roleKey + var roleWorkspaceID *string if roleScope == "workspace" { if workspaceID == nil { - continue + return effectiveAccess{}, fmt.Errorf("workspace role %q has no workspace", roleKey) } - prefix += "/workspaces/" + *workspaceID - marker = prefix + "/roles/" + roleKey + roleWorkspaceID = workspaceID + roles.Workspaces[*workspaceID] = append(roles.Workspaces[*workspaceID], roleKey) + } else { + roles.Application = append(roles.Application, roleKey) + } + marker, markerErr := platformauthz.RoleMarker(applicationID.String(), roleWorkspaceID, roleKey) + if markerErr != nil { + return effectiveAccess{}, markerErr } set[marker] = struct{}{} + provenance = append(provenance, scopeProvenance{Scope: marker, Source: "role_marker", RoleKey: roleKey, WorkspaceID: roleWorkspaceID}) for _, permission := range permissions { - set[expandScope(prefix, permission)] = struct{}{} + expanded, expandErr := platformauthz.CanonicalScope(applicationID.String(), roleWorkspaceID, permission) + if expandErr != nil { + return effectiveAccess{}, expandErr + } + set[expanded] = struct{}{} + provenance = append(provenance, scopeProvenance{Scope: expanded, Source: "role", RoleKey: roleKey, WorkspaceID: roleWorkspaceID, Permission: permission}) } } + if err = rows.Err(); err != nil { + return effectiveAccess{}, err + } + if err = s.addDirectGrantScopes(r, applicationID, userID, "", set, &provenance); err != nil { + return effectiveAccess{}, err + } owned, err := s.app.DB.Query(r.Context(), `SELECT id::text FROM workspaces WHERE application_id=$1 AND owner_user_id=$2 AND deleted_at IS NULL ORDER BY id`, applicationID, userID) if err == nil { defer owned.Close() for owned.Next() { var workspaceID string - if owned.Scan(&workspaceID) == nil { - set[applicationPrefix+"/workspaces/"+workspaceID+"/*"] = struct{}{} + if scanErr := owned.Scan(&workspaceID); scanErr != nil { + return effectiveAccess{}, scanErr + } + permission := "*" + setScope, scopeErr := platformauthz.CanonicalScope(applicationID.String(), &workspaceID, permission) + if scopeErr != nil { + return effectiveAccess{}, scopeErr } + set[setScope] = struct{}{} + workspaceCopy := workspaceID + provenance = append(provenance, scopeProvenance{Scope: setScope, Source: "workspace_owner", WorkspaceID: &workspaceCopy, Permission: "*"}) } + } else { + return effectiveAccess{}, err } values := make([]string, 0, len(set)) for value := range set { @@ -911,60 +1073,121 @@ WHERE application_id=$1 AND owner_user_id=$2 AND deleted_at IS NULL ORDER BY id` } } sort.Strings(values) - return values + sort.Strings(roles.Application) + for workspaceID := range roles.Workspaces { + sort.Strings(roles.Workspaces[workspaceID]) + } + sort.Slice(provenance, func(i, j int) bool { + if provenance[i].Scope == provenance[j].Scope { + return provenance[i].Source < provenance[j].Source + } + return provenance[i].Scope < provenance[j].Scope + }) + return effectiveAccess{Scopes: values, Roles: roles, Provenance: provenance}, nil } func (s *Server) clientScopes(r *http.Request, applicationID uuid.UUID, clientID string) []string { + access, err := s.clientEffectiveAccess(r, applicationID, clientID) + if err != nil { + return []string{} + } + return access.Scopes +} + +func (s *Server) clientEffectiveAccess(r *http.Request, applicationID uuid.UUID, clientID string) (effectiveAccess, error) { rows, err := s.app.DB.Query(r.Context(), `SELECT ro.key,ro.scope,ro.permissions,ra.workspace_id::text FROM clients c JOIN role_assignments ra ON ra.client_id=c.id AND ra.application_id=c.application_id JOIN roles ro ON ro.id=ra.role_id AND ro.application_id=ra.application_id WHERE c.application_id=$1 AND c.client_id=$2 AND c.disabled_at IS NULL ORDER BY ra.created_at,ra.id`, applicationID, clientID) if err != nil { - return []string{} + return effectiveAccess{}, err } defer rows.Close() - applicationPrefix := "/applications/" + applicationID.String() set := map[string]struct{}{} + provenance := []scopeProvenance{} + roles := emptyRoleClaims() + var clientDatabaseID string + if err = s.app.DB.QueryRow(r.Context(), `SELECT id FROM clients WHERE application_id=$1 AND client_id=$2 AND disabled_at IS NULL`, applicationID, clientID).Scan(&clientDatabaseID); err != nil { + return effectiveAccess{}, err + } for rows.Next() { var roleKey, roleScope string var permissions []string var workspaceID *string - if rows.Scan(&roleKey, &roleScope, &permissions, &workspaceID) != nil { - continue + if scanErr := rows.Scan(&roleKey, &roleScope, &permissions, &workspaceID); scanErr != nil { + return effectiveAccess{}, scanErr } - prefix := applicationPrefix + var roleWorkspaceID *string if roleScope == "workspace" { if workspaceID == nil { - continue + return effectiveAccess{}, fmt.Errorf("workspace role %q has no workspace", roleKey) } - prefix += "/workspaces/" + *workspaceID + roleWorkspaceID = workspaceID + roles.Workspaces[*workspaceID] = append(roles.Workspaces[*workspaceID], roleKey) + } else { + roles.Application = append(roles.Application, roleKey) + } + marker, markerErr := platformauthz.RoleMarker(applicationID.String(), roleWorkspaceID, roleKey) + if markerErr != nil { + return effectiveAccess{}, markerErr } - set[prefix+"/roles/"+roleKey] = struct{}{} + set[marker] = struct{}{} + provenance = append(provenance, scopeProvenance{Scope: marker, Source: "role_marker", RoleKey: roleKey, WorkspaceID: roleWorkspaceID}) for _, permission := range permissions { - if expanded := expandScope(prefix, permission); expanded != "" { - set[expanded] = struct{}{} + expanded, expandErr := platformauthz.CanonicalScope(applicationID.String(), roleWorkspaceID, permission) + if expandErr != nil { + return effectiveAccess{}, expandErr } + set[expanded] = struct{}{} + provenance = append(provenance, scopeProvenance{Scope: expanded, Source: "role", RoleKey: roleKey, WorkspaceID: roleWorkspaceID, Permission: permission}) } } + if err = rows.Err(); err != nil { + return effectiveAccess{}, err + } + if err = s.addDirectGrantScopes(r, applicationID, "", clientDatabaseID, set, &provenance); err != nil { + return effectiveAccess{}, err + } values := make([]string, 0, len(set)) for value := range set { values = append(values, value) } sort.Strings(values) - return values + sort.Strings(roles.Application) + for workspaceID := range roles.Workspaces { + sort.Strings(roles.Workspaces[workspaceID]) + } + sort.Slice(provenance, func(i, j int) bool { + if provenance[i].Scope == provenance[j].Scope { + return provenance[i].Source < provenance[j].Source + } + return provenance[i].Scope < provenance[j].Scope + }) + return effectiveAccess{Scopes: values, Roles: roles, Provenance: provenance}, nil } -func expandScope(prefix, permission string) string { - permission = strings.TrimSpace(permission) - if strings.HasPrefix(permission, "/applications/") { - return permission +func (s *Server) addDirectGrantScopes(r *http.Request, applicationID uuid.UUID, userID, clientID string, set map[string]struct{}, provenance *[]scopeProvenance) error { + rows, err := s.app.DB.Query(r.Context(), `SELECT id::text,permission,canonical_scope,workspace_id::text FROM permission_grants +WHERE application_id=$1 AND user_id IS NOT DISTINCT FROM NULLIF($2,'')::uuid +AND client_id IS NOT DISTINCT FROM NULLIF($3,'')::uuid AND revoked_at IS NULL ORDER BY created_at,id`, applicationID, userID, clientID) + if err != nil { + return err } - permission = strings.Trim(permission, "/") - permission = strings.ReplaceAll(permission, ":", "/") - if permission == "" { - return "" + defer rows.Close() + for rows.Next() { + var grantID, permission, canonical string + var workspaceID *string + if err = rows.Scan(&grantID, &permission, &canonical, &workspaceID); err != nil { + return err + } + expected, canonicalErr := platformauthz.CanonicalScope(applicationID.String(), workspaceID, permission) + if canonicalErr != nil || expected != canonical { + return fmt.Errorf("permission grant contains invalid canonical data") + } + set[canonical] = struct{}{} + *provenance = append(*provenance, scopeProvenance{Scope: canonical, Source: "direct", GrantID: grantID, WorkspaceID: workspaceID, Permission: permission}) } - return prefix + "/" + permission + return rows.Err() } func (s *Server) authFlag(r *http.Request, key string) bool { diff --git a/internal/httpapi/installation_operators.go b/internal/httpapi/installation_control_users.go similarity index 56% rename from internal/httpapi/installation_operators.go rename to internal/httpapi/installation_control_users.go index 043d3f7..7233e6e 100644 --- a/internal/httpapi/installation_operators.go +++ b/internal/httpapi/installation_control_users.go @@ -11,15 +11,15 @@ import ( "github.com/supaapps/platform93/internal/kernel" ) -func (s *Server) listInstallationOperators(w http.ResponseWriter, r *http.Request) { +func (s *Server) listInstallationControlUsers(w http.ResponseWriter, r *http.Request) { if _, ok := s.installationRole(r); !ok { kernel.WriteProblem(w, r, http.StatusForbidden, "installation_role_required", "An installation role is required.") return } rows, err := s.app.DB.Query(r.Context(), `SELECT o.id,o.email,o.display_name,o.status,ir.role,ir.created_at,ir.updated_at -FROM installation_operator_roles ir JOIN operators o ON o.id=ir.operator_id ORDER BY ir.created_at,o.id`) +FROM installation_control_user_roles ir JOIN control_users o ON o.id=ir.control_user_id ORDER BY ir.created_at,o.id`) if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Installation operators could not be loaded.") + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Platform users could not be loaded.") return } defer rows.Close() @@ -34,7 +34,7 @@ FROM installation_operator_roles ir JOIN operators o ON o.id=ir.operator_id ORDE kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) } -func (s *Server) createInstallationOperator(w http.ResponseWriter, r *http.Request) { +func (s *Server) createInstallationControlUser(w http.ResponseWriter, r *http.Request) { var request struct { Email string `json:"email"` DisplayName string `json:"display_name"` @@ -45,37 +45,37 @@ func (s *Server) createInstallationOperator(w http.ResponseWriter, r *http.Reque } callerRole, allowed := s.installationRole(r) if !allowed || callerRole != "owner" && callerRole != "admin" || request.Role == "owner" && callerRole != "owner" { - kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "The operator cannot assign this installation role.") + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "The Platform user cannot assign this installation role.") return } request.Email = kernel.NormalizeEmail(request.Email) if !strings.Contains(request.Email, "@") || !validInstallationRole(request.Role) { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_installation_operator", "Email and installation role must be valid.") + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_installation_control_user", "Email and installation role must be valid.") return } tx, err := s.app.DB.Begin(r.Context()) if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The installation operator could not be created.") + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The Platform user could not be created.") return } defer rollback(tx, r.Context()) - var operatorID string - err = tx.QueryRow(r.Context(), `INSERT INTO operators(id,email,normalized_email,display_name) + var controlUserID string + err = tx.QueryRow(r.Context(), `INSERT INTO control_users(id,email,normalized_email,display_name) VALUES($1,$2,$2,$3) ON CONFLICT(normalized_email) DO UPDATE SET -display_name=CASE WHEN EXCLUDED.display_name='' THEN operators.display_name ELSE EXCLUDED.display_name END -RETURNING id`, kernel.NewID(), request.Email, truncate(request.DisplayName, 200)).Scan(&operatorID) +display_name=CASE WHEN EXCLUDED.display_name='' THEN control_users.display_name ELSE EXCLUDED.display_name END +RETURNING id`, kernel.NewID(), request.Email, truncate(request.DisplayName, 200)).Scan(&controlUserID) if err == nil { - _, err = tx.Exec(r.Context(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,$2) -ON CONFLICT(operator_id) DO UPDATE SET role=EXCLUDED.role,updated_at=now()`, operatorID, request.Role) + _, err = tx.Exec(r.Context(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,$2) +ON CONFLICT(control_user_id) DO UPDATE SET role=EXCLUDED.role,updated_at=now()`, controlUserID, request.Role) } if err != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusConflict, "installation_operator_conflict", "The installation operator could not be created.") + kernel.WriteProblem(w, r, http.StatusConflict, "installation_control_user_conflict", "The Platform user could not be created.") return } - kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": operatorID, "email": request.Email, "display_name": request.DisplayName, "role": request.Role}) + kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": controlUserID, "email": request.Email, "display_name": request.DisplayName, "role": request.Role}) } -func (s *Server) updateInstallationOperator(w http.ResponseWriter, r *http.Request) { +func (s *Server) updateInstallationControlUser(w http.ResponseWriter, r *http.Request) { var request struct { Role string `json:"role"` } @@ -84,65 +84,65 @@ func (s *Server) updateInstallationOperator(w http.ResponseWriter, r *http.Reque } callerRole, allowed := s.installationRole(r) if !allowed || callerRole != "owner" && callerRole != "admin" || request.Role == "owner" && callerRole != "owner" { - kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "The operator cannot assign this installation role.") + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "The Platform user cannot assign this installation role.") return } - operatorID := chi.URLParam(r, "operator_id") + controlUserID := chi.URLParam(r, "control_user_id") tx, err := s.app.DB.Begin(r.Context()) if err != nil { return } defer rollback(tx, r.Context()) var currentRole string - err = tx.QueryRow(r.Context(), `SELECT role FROM installation_operator_roles WHERE operator_id=$1 FOR UPDATE`, operatorID).Scan(¤tRole) + err = tx.QueryRow(r.Context(), `SELECT role FROM installation_control_user_roles WHERE control_user_id=$1 FOR UPDATE`, controlUserID).Scan(¤tRole) if err != nil { - kernel.WriteProblem(w, r, http.StatusNotFound, "installation_operator_not_found", "The installation operator was not found.") + kernel.WriteProblem(w, r, http.StatusNotFound, "installation_control_user_not_found", "The Platform user was not found.") return } - if currentRole == "owner" && request.Role != "owner" && !installationHasAnotherActiveOwner(r, tx, operatorID) { + if currentRole == "owner" && request.Role != "owner" && !installationHasAnotherActiveOwner(r, tx, controlUserID) { kernel.WriteProblem(w, r, http.StatusConflict, "last_installation_owner", "The final active installation owner cannot be demoted.") return } - _, err = tx.Exec(r.Context(), `UPDATE installation_operator_roles SET role=$1,updated_at=now() WHERE operator_id=$2`, request.Role, operatorID) + _, err = tx.Exec(r.Context(), `UPDATE installation_control_user_roles SET role=$1,updated_at=now() WHERE control_user_id=$2`, request.Role, controlUserID) if err != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "installation_operator_update_failed", "The installation operator could not be updated.") + kernel.WriteProblem(w, r, http.StatusInternalServerError, "installation_control_user_update_failed", "The Platform user could not be updated.") return } w.WriteHeader(http.StatusNoContent) } -func (s *Server) deleteInstallationOperator(w http.ResponseWriter, r *http.Request) { +func (s *Server) deleteInstallationControlUser(w http.ResponseWriter, r *http.Request) { callerRole, allowed := s.installationRole(r) if !allowed || callerRole != "owner" && callerRole != "admin" { - kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "The operator cannot remove installation roles.") + kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "The Platform user cannot remove installation roles.") return } - operatorID := chi.URLParam(r, "operator_id") + controlUserID := chi.URLParam(r, "control_user_id") tx, err := s.app.DB.Begin(r.Context()) if err != nil { return } defer rollback(tx, r.Context()) var currentRole string - err = tx.QueryRow(r.Context(), `SELECT role FROM installation_operator_roles WHERE operator_id=$1 FOR UPDATE`, operatorID).Scan(¤tRole) + err = tx.QueryRow(r.Context(), `SELECT role FROM installation_control_user_roles WHERE control_user_id=$1 FOR UPDATE`, controlUserID).Scan(¤tRole) if err != nil { - kernel.WriteProblem(w, r, http.StatusNotFound, "installation_operator_not_found", "The installation operator was not found.") + kernel.WriteProblem(w, r, http.StatusNotFound, "installation_control_user_not_found", "The Platform user was not found.") return } if currentRole == "owner" && callerRole != "owner" { kernel.WriteProblem(w, r, http.StatusForbidden, "installation_permission_required", "Only an installation owner can remove another owner.") return } - if currentRole == "owner" && !installationHasAnotherActiveOwner(r, tx, operatorID) { + if currentRole == "owner" && !installationHasAnotherActiveOwner(r, tx, controlUserID) { kernel.WriteProblem(w, r, http.StatusConflict, "last_installation_owner", "The final active installation owner cannot be removed.") return } - _, err = tx.Exec(r.Context(), `DELETE FROM installation_operator_roles WHERE operator_id=$1`, operatorID) + _, err = tx.Exec(r.Context(), `DELETE FROM installation_control_user_roles WHERE control_user_id=$1`, controlUserID) if err == nil { - _, err = tx.Exec(r.Context(), `UPDATE operator_sessions SET revoked_at=COALESCE(revoked_at,now()) WHERE operator_id=$1`, operatorID) + _, err = tx.Exec(r.Context(), `UPDATE control_user_sessions SET revoked_at=COALESCE(revoked_at,now()) WHERE control_user_id=$1`, controlUserID) } if err != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "installation_operator_removal_failed", "The installation role could not be removed.") + kernel.WriteProblem(w, r, http.StatusInternalServerError, "installation_control_user_removal_failed", "The installation role could not be removed.") return } w.WriteHeader(http.StatusNoContent) @@ -150,17 +150,17 @@ func (s *Server) deleteInstallationOperator(w http.ResponseWriter, r *http.Reque func (s *Server) installationRole(r *http.Request) (string, bool) { var role string - err := s.app.DB.QueryRow(r.Context(), `SELECT ir.role FROM installation_operator_roles ir -JOIN operators o ON o.id=ir.operator_id WHERE ir.operator_id=$1 AND o.status='active'`, actor(r).ID).Scan(&role) + err := s.app.DB.QueryRow(r.Context(), `SELECT ir.role FROM installation_control_user_roles ir +JOIN control_users o ON o.id=ir.control_user_id WHERE ir.control_user_id=$1 AND o.status='active'`, actor(r).ID).Scan(&role) return role, err == nil } func installationHasAnotherActiveOwner(r *http.Request, tx interface { QueryRow(context.Context, string, ...any) pgx.Row -}, operatorID string) bool { +}, controlUserID string) bool { var exists bool - _ = tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM installation_operator_roles ir -JOIN operators o ON o.id=ir.operator_id WHERE ir.role='owner' AND ir.operator_id<>$1 AND o.status='active')`, operatorID).Scan(&exists) + _ = tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM installation_control_user_roles ir +JOIN control_users o ON o.id=ir.control_user_id WHERE ir.role='owner' AND ir.control_user_id<>$1 AND o.status='active')`, controlUserID).Scan(&exists) return exists } diff --git a/internal/httpapi/invitations.go b/internal/httpapi/invitations.go new file mode 100644 index 0000000..39667d5 --- /dev/null +++ b/internal/httpapi/invitations.go @@ -0,0 +1,706 @@ +package httpapi + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "errors" + "net/http" + "regexp" + "strconv" + "strings" + "time" + + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + "github.com/jackc/pgx/v5" + "github.com/supaapps/platform93/internal/kernel" + "github.com/supaapps/platform93/internal/secure" +) + +const applicationInvitationTemplate = "platform93.application_invitation" + +var invitationPKCEChallengePattern = regexp.MustCompile(`^[A-Za-z0-9_-]{43}$`) +var invitationPKCEVerifierPattern = regexp.MustCompile(`^[A-Za-z0-9._~-]{43,128}$`) +var invitationCodePattern = regexp.MustCompile(`^[ABCDEFGHJKLMNPQRSTUVWXYZ23456789]{8}$`) +var errInvalidInvitationRedirect = errors.New("invitation redirect is not configured") + +type invitationRequest struct { + Email string `json:"email"` + WorkspaceID string `json:"workspace_id,omitempty"` + ApplicationRoleKeys []string `json:"application_role_keys,omitempty"` + WorkspaceRoleKeys []string `json:"workspace_role_keys,omitempty"` + RoleKeys []string `json:"role_keys,omitempty"` + ExpiresIn int64 `json:"expires_in,omitempty"` +} + +func (s *Server) createControlInvitation(w http.ResponseWriter, r *http.Request) { + s.createInvitation(w, r, true) +} + +func (s *Server) createApplicationInvitation(w http.ResponseWriter, r *http.Request) { + if actor(r).Type != "client" || !actorHasPermission(actor(r), applicationPermission(r, "invitations/manage")) { + kernel.WriteProblem(w, r, http.StatusForbidden, "invitation_management_required", "A machine client with invitation management permission is required.") + return + } + s.createInvitation(w, r, true) +} + +func (s *Server) createWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { + s.createInvitation(w, r, false) +} + +func (s *Server) createInvitation(w http.ResponseWriter, r *http.Request, applicationManaged bool) { + var request invitationRequest + if !kernel.DecodeJSON(w, r, &request) { + return + } + applicationID := chi.URLParam(r, "application_id") + if request.WorkspaceID == "" { + request.WorkspaceID = chi.URLParam(r, "workspace_id") + } + if len(request.WorkspaceRoleKeys) == 0 { + request.WorkspaceRoleKeys = request.RoleKeys + } + request.ApplicationRoleKeys = uniqueStrings(request.ApplicationRoleKeys) + request.WorkspaceRoleKeys = uniqueStrings(request.WorkspaceRoleKeys) + normalized := kernel.NormalizeEmail(request.Email) + if !strings.Contains(normalized, "@") || len(request.ApplicationRoleKeys)+len(request.WorkspaceRoleKeys) > 20 { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_invitation", "A valid email and at most twenty role keys are required.") + return + } + if request.ExpiresIn == 0 { + request.ExpiresIn = int64((7 * 24 * time.Hour).Seconds()) + } + if request.ExpiresIn < 300 || request.ExpiresIn > int64((30*24*time.Hour).Seconds()) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_invitation_expiry", "Invitation expiry must be between five minutes and thirty days.") + return + } + current := actor(r) + if !s.allowAuthAttempt(w, r, "invitation_create", normalized+"|"+request.WorkspaceID+"|"+current.Type+":"+current.ID, 10, time.Minute) { + return + } + if current.Type == "user" { + config, err := s.internalApplicationConfig(r) + if err != nil || !config.UserInvitationsEnabled { + kernel.WriteProblem(w, r, http.StatusForbidden, "user_invitations_disabled", "Application users are not allowed to invite users.") + return + } + canManageWorkspaceInvitations := s.canAccessWorkspace(r, true) || s.canAccessWorkspace(r, false) && actorHasPermission(current, workspacePermission(r, "invitations/manage")) + if applicationManaged || request.WorkspaceID == "" || len(request.ApplicationRoleKeys) > 0 || !canManageWorkspaceInvitations { + kernel.WriteProblem(w, r, http.StatusForbidden, "workspace_invitation_required", "This user may only invite users into an authorized workspace.") + return + } + } + if current.Type == "client" && !applicationManaged && !actorHasPermission(current, workspacePermission(r, "invitations/manage")) { + kernel.WriteProblem(w, r, http.StatusForbidden, "invitation_management_required", "Workspace invitation management permission is required.") + return + } + if request.WorkspaceID == "" && len(request.WorkspaceRoleKeys) > 0 { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "workspace_required", "Workspace roles require a workspace.") + return + } + if !s.validInvitationRoles(r.Context(), applicationID, request.WorkspaceID, request.ApplicationRoleKeys, request.WorkspaceRoleKeys) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_invitation_roles", "One or more invitation roles are invalid for this application or workspace.") + return + } + code := randomCode(8) + link, err := secure.RandomToken("p93_invite_", 32) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "invitation_creation_failed", "Invitation credentials could not be created.") + return + } + id, notificationID := kernel.NewID(), kernel.NewID() + expiresAt := s.app.Now().Add(time.Duration(request.ExpiresIn) * time.Second) + linkURI, templateKey, workspaceName, presentationErr := s.invitationPresentation(r.Context(), applicationID, id.String(), link, request.WorkspaceID) + if presentationErr != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invitation_redirect_unconfigured", "Configure the application's invitation redirect before creating invitations.") + return + } + roleKeys := append(append([]string{}, request.ApplicationRoleKeys...), request.WorkspaceRoleKeys...) + variables := map[string]any{"invitation_code": code, "invitation_link": linkURI, "role_keys": strings.Join(roleKeys, ", "), "expires_at": templateTimestamp(expiresAt), "inviter_name": s.inviterDisplayName(r.Context(), applicationID, current)} + if request.WorkspaceID != "" { + variables["workspace_id"], variables["workspace_name"] = request.WorkspaceID, workspaceName + } + templateID, locale, payload, renderErr := s.renderSystemNotification(r.Context(), &applicationID, templateKey, normalized, variables) + if renderErr != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "invitation_template_unavailable", "The invitation email template is unavailable or invalid.") + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The invitation could not be created.") + return + } + defer rollback(tx, r.Context()) + var workspace any + if request.WorkspaceID != "" { + workspace = request.WorkspaceID + } + _, err = tx.Exec(r.Context(), `INSERT INTO application_invitations +(id,application_id,workspace_id,normalized_email,link_credential_digest,code_credential_digest,application_roles,workspace_roles,expires_at,inviter_type,inviter_id,last_sent_at,resend_available_at) +VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,now(),now()+interval '60 seconds')`, id, applicationID, workspace, normalized, + s.app.Vault.Digest(link), s.app.Vault.Digest(code), request.ApplicationRoleKeys, request.WorkspaceRoleKeys, expiresAt, current.Type, nullableActorID(current.ID)) + if err == nil { + ciphertext, encryptErr := s.app.Vault.Encrypt(payload, "notification:"+notificationID.String()) + if encryptErr != nil { + err = encryptErr + } else { + _, err = tx.Exec(r.Context(), `INSERT INTO notifications(id,application_id,template_id,recipient,locale,payload_ciphertext,status) +VALUES($1,$2,$3,$4,$5,$6,'queued')`, notificationID, applicationID, templateID, normalized, locale, ciphertext) + } + } + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &parsedApplicationID, "application_invitation.created", "application_invitation/"+id.String(), current, + map[string]any{"invitation_id": id, "workspace_id": workspace, "application_role_keys": request.ApplicationRoleKeys, "workspace_role_keys": request.WorkspaceRoleKeys, "status": "pending"}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "invitation_conflict", "A pending invitation already exists or could not be created.") + return + } + kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": id, "email": normalized, "workspace_id": workspace, "application_role_keys": request.ApplicationRoleKeys, + "workspace_role_keys": request.WorkspaceRoleKeys, "expires_at": expiresAt, "last_sent_at": s.app.Now(), "resend_available_at": s.app.Now().Add(time.Minute)}) +} + +func nullableActorID(value string) any { + if _, err := uuid.Parse(value); err == nil { + return value + } + return nil +} + +func (s *Server) inviterDisplayName(ctx context.Context, applicationID string, current kernel.Actor) string { + var name string + switch current.Type { + case "control_user": + _ = s.app.DB.QueryRow(ctx, `SELECT COALESCE(NULLIF(display_name,''),email) FROM control_users WHERE id=$1`, current.ID).Scan(&name) + case "client": + _ = s.app.DB.QueryRow(ctx, `SELECT name FROM clients WHERE id=$1 AND application_id=$2`, current.ID, applicationID).Scan(&name) + case "user": + _ = s.app.DB.QueryRow(ctx, `SELECT COALESCE(NULLIF(trim(first_name||' '||last_name),''),email) FROM users WHERE id=$1 AND application_id=$2`, current.ID, applicationID).Scan(&name) + } + return stringWithFallback(name, current.ID) +} + +func applicationPermission(r *http.Request, suffix string) string { + return "/applications/" + chi.URLParam(r, "application_id") + "/" + strings.Trim(suffix, "/") +} + +func workspacePermission(r *http.Request, suffix string) string { + return applicationPermission(r, "workspaces/"+chi.URLParam(r, "workspace_id")+"/"+strings.Trim(suffix, "/")) +} + +func (s *Server) validInvitationRoles(ctx context.Context, applicationID, workspaceID string, applicationRoles, workspaceRoles []string) bool { + var applicationCount, workspaceCount int + if s.app.DB.QueryRow(ctx, `SELECT +(SELECT count(*) FROM roles WHERE application_id=$1 AND scope='application' AND key=ANY($2)), +(SELECT count(*) FROM roles WHERE application_id=$1 AND scope='workspace' AND key=ANY($3))`, applicationID, applicationRoles, workspaceRoles).Scan(&applicationCount, &workspaceCount) != nil { + return false + } + if applicationCount != len(applicationRoles) || workspaceCount != len(workspaceRoles) { + return false + } + if workspaceID != "" { + var exists bool + _ = s.app.DB.QueryRow(ctx, `SELECT EXISTS(SELECT 1 FROM workspaces WHERE id=$1 AND application_id=$2 AND deleted_at IS NULL)`, workspaceID, applicationID).Scan(&exists) + return exists + } + return true +} + +func (s *Server) invitationPresentation(ctx context.Context, applicationID, invitationID, linkToken, workspaceID string) (string, string, string, error) { + flows, err := s.loadApplicationFlowConfig(ctx, applicationID) + if err != nil || flows.InvitationRedirectURI == "" { + return "", "", "", errInvalidInvitationRedirect + } + link := appendCredentialQuery(flows.InvitationRedirectURI, map[string]string{"application_id": applicationID, "invitation_id": invitationID, + "link_token": linkToken, "platform93_flow": "invitation"}) + if workspaceID == "" { + return link, applicationInvitationTemplate, "", nil + } + var name string + if err := s.app.DB.QueryRow(ctx, `SELECT name FROM workspaces WHERE id=$1 AND application_id=$2`, workspaceID, applicationID).Scan(&name); err != nil { + return "", "", "", err + } + return link, workspaceInvitationTemplate, name, nil +} + +func (s *Server) listInvitations(w http.ResponseWriter, r *http.Request) { + applicationID, workspaceID := chi.URLParam(r, "application_id"), chi.URLParam(r, "workspace_id") + if !s.canManageInvitations(w, r, workspaceID) { + return + } + query := `SELECT id,workspace_id,normalized_email,application_roles,workspace_roles,expires_at,accepted_at,revoked_at,last_sent_at,resend_available_at,created_at +FROM application_invitations WHERE application_id=$1` + args := []any{applicationID} + if workspaceID != "" { + query += ` AND workspace_id=$2` + args = append(args, workspaceID) + } + query += ` ORDER BY created_at DESC,id DESC LIMIT 101` + rows, err := s.app.DB.Query(r.Context(), query, args...) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Invitations could not be loaded.") + return + } + defer rows.Close() + items := []map[string]any{} + for rows.Next() { + var id, email string + var workspace *string + var appRoles, workspaceRoles []string + var expires, sent, resend, created time.Time + var accepted, revoked *time.Time + if rows.Scan(&id, &workspace, &email, &appRoles, &workspaceRoles, &expires, &accepted, &revoked, &sent, &resend, &created) == nil { + status := "pending" + if accepted != nil { + status = "accepted" + } else if revoked != nil { + status = "revoked" + } else if expires.Before(s.app.Now()) { + status = "expired" + } + items = append(items, map[string]any{"id": id, "workspace_id": workspace, "email": email, "application_role_keys": appRoles, + "workspace_role_keys": workspaceRoles, "status": status, "expires_at": expires, "accepted_at": accepted, "revoked_at": revoked, + "last_sent_at": sent, "resend_available_at": resend, "created_at": created}) + } + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) +} + +func (s *Server) getInvitation(w http.ResponseWriter, r *http.Request) { + applicationID, invitationID := chi.URLParam(r, "application_id"), chi.URLParam(r, "invitation_id") + var workspaceID *string + var email string + var applicationRoles, workspaceRoles []string + var expiresAt, lastSentAt, resendAvailableAt, createdAt, updatedAt time.Time + var acceptedAt, revokedAt, expirationRecordedAt *time.Time + err := s.app.DB.QueryRow(r.Context(), `SELECT workspace_id,normalized_email,application_roles,workspace_roles,expires_at,accepted_at,revoked_at, +last_sent_at,resend_available_at,expiration_recorded_at,created_at,updated_at FROM application_invitations WHERE id=$1 AND application_id=$2`, invitationID, applicationID). + Scan(&workspaceID, &email, &applicationRoles, &workspaceRoles, &expiresAt, &acceptedAt, &revokedAt, &lastSentAt, &resendAvailableAt, &expirationRecordedAt, &createdAt, &updatedAt) + if err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "invitation_not_found", "The invitation was not found.") + return + } + resolvedWorkspaceID := "" + if workspaceID != nil { + resolvedWorkspaceID = *workspaceID + } + if !s.canManageInvitations(w, r, resolvedWorkspaceID) { + return + } + status := "pending" + if acceptedAt != nil { + status = "accepted" + } else if revokedAt != nil { + status = "revoked" + } else if expirationRecordedAt != nil || expiresAt.Before(s.app.Now()) { + status = "expired" + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"id": invitationID, "workspace_id": workspaceID, "email": email, + "application_role_keys": applicationRoles, "workspace_role_keys": workspaceRoles, "status": status, "expires_at": expiresAt, + "accepted_at": acceptedAt, "revoked_at": revokedAt, "last_sent_at": lastSentAt, "resend_available_at": resendAvailableAt, + "created_at": createdAt, "updated_at": updatedAt}) +} + +func (s *Server) resendInvitation(w http.ResponseWriter, r *http.Request) { + current := actor(r) + applicationID, invitationID := chi.URLParam(r, "application_id"), chi.URLParam(r, "invitation_id") + var workspaceID *string + var email string + var appRoles, workspaceRoles []string + var resendAvailable time.Time + err := s.app.DB.QueryRow(r.Context(), `SELECT workspace_id,normalized_email,application_roles,workspace_roles,resend_available_at +FROM application_invitations WHERE id=$1 AND application_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL AND expires_at>now()`, invitationID, applicationID). + Scan(&workspaceID, &email, &appRoles, &workspaceRoles, &resendAvailable) + if err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "invitation_not_found", "A pending invitation was not found.") + return + } + resolvedWorkspaceID := "" + if workspaceID != nil { + resolvedWorkspaceID = *workspaceID + } + if !s.canManageInvitations(w, r, resolvedWorkspaceID) { + return + } + if resendAvailable.After(s.app.Now()) { + retry := int(time.Until(resendAvailable).Seconds()) + 1 + w.Header().Set("Retry-After", fmtInt(retry)) + kernel.WriteProblem(w, r, http.StatusTooManyRequests, "invitation_resend_cooldown", "The invitation can be resent after the cooldown.") + return + } + code, link := randomCode(8), "" + link, _ = secure.RandomToken("p93_invite_", 32) + workspace := "" + if workspaceID != nil { + workspace = *workspaceID + } + linkURI, templateKey, workspaceName, presentationErr := s.invitationPresentation(r.Context(), applicationID, invitationID, link, workspace) + if presentationErr != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invitation_redirect_unconfigured", "Configure the application's invitation redirect before resending invitations.") + return + } + roles := append(append([]string{}, appRoles...), workspaceRoles...) + expires := s.app.Now().Add(7 * 24 * time.Hour) + variables := map[string]any{"invitation_code": code, "invitation_link": linkURI, "role_keys": strings.Join(roles, ", "), "expires_at": templateTimestamp(expires), "inviter_name": s.inviterDisplayName(r.Context(), applicationID, current)} + if workspace != "" { + variables["workspace_id"], variables["workspace_name"] = workspace, workspaceName + } + templateID, locale, payload, renderErr := s.renderSystemNotification(r.Context(), &applicationID, templateKey, email, variables) + if renderErr != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "invitation_template_unavailable", "The invitation email template is unavailable.") + return + } + notificationID := kernel.NewID() + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, 500, "database_error", "The invitation could not be resent.") + return + } + defer rollback(tx, r.Context()) + result, err := tx.Exec(r.Context(), `UPDATE application_invitations SET link_credential_digest=$1,code_credential_digest=$2,expires_at=$3, +last_sent_at=now(),resend_available_at=now()+interval '60 seconds',updated_at=now() WHERE id=$4 AND application_id=$5 AND resend_available_at<=now() +AND accepted_at IS NULL AND revoked_at IS NULL`, s.app.Vault.Digest(link), s.app.Vault.Digest(code), expires, invitationID, applicationID) + if err == nil && result.RowsAffected() != 1 { + err = pgx.ErrNoRows + } + if err == nil { + ciphertext, encryptErr := s.app.Vault.Encrypt(payload, "notification:"+notificationID.String()) + if encryptErr != nil { + err = encryptErr + } else { + _, err = tx.Exec(r.Context(), `INSERT INTO notifications(id,application_id,template_id,recipient,locale,payload_ciphertext,status) VALUES($1,$2,$3,$4,$5,$6,'queued')`, notificationID, applicationID, templateID, email, locale, ciphertext) + } + } + parsed, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &parsed, "application_invitation.resent", "application_invitation/"+invitationID, current, map[string]any{"invitation_id": invitationID, "status": "pending", "expires_at": expires}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "invitation_resend_conflict", "The invitation changed or is still in its cooldown.") + return + } + kernel.WriteJSON(w, http.StatusAccepted, map[string]any{"id": invitationID, "last_sent_at": s.app.Now(), "resend_available_at": s.app.Now().Add(time.Minute), "expires_at": expires}) +} + +func fmtInt(value int) string { return strconv.Itoa(value) } + +func (s *Server) listMyInvitations(w http.ResponseWriter, r *http.Request) { + rows, err := s.app.DB.Query(r.Context(), `SELECT i.id,i.workspace_id,i.normalized_email,i.application_roles,i.workspace_roles,i.expires_at,i.last_sent_at,i.created_at +FROM application_invitations i JOIN users u ON u.application_id=i.application_id AND u.normalized_email=i.normalized_email +WHERE i.application_id=$1 AND u.id=$2 AND i.accepted_at IS NULL AND i.revoked_at IS NULL AND i.expires_at>now() ORDER BY i.created_at DESC`, + chi.URLParam(r, "application_id"), actor(r).ID) + if err != nil { + kernel.WriteProblem(w, r, 500, "database_error", "Invitations could not be loaded.") + return + } + defer rows.Close() + items := []map[string]any{} + for rows.Next() { + var id, email string + var workspace *string + var appRoles, workspaceRoles []string + var expires, sent, created time.Time + if rows.Scan(&id, &workspace, &email, &appRoles, &workspaceRoles, &expires, &sent, &created) == nil { + items = append(items, map[string]any{"id": id, "workspace_id": workspace, "email": email, "application_role_keys": appRoles, "workspace_role_keys": workspaceRoles, "status": "pending", "expires_at": expires, "last_sent_at": sent, "created_at": created}) + } + } + kernel.WriteJSON(w, 200, map[string]any{"items": items, "next_cursor": nil}) +} + +func (s *Server) revokeWorkspaceInvitation(w http.ResponseWriter, r *http.Request) { + s.revokeInvitation(w, r) +} + +func (s *Server) revokeInvitation(w http.ResponseWriter, r *http.Request) { + applicationID, invitationID := chi.URLParam(r, "application_id"), chi.URLParam(r, "invitation_id") + var workspaceID *string + if err := s.app.DB.QueryRow(r.Context(), `SELECT workspace_id FROM application_invitations +WHERE id=$1 AND application_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL`, invitationID, applicationID).Scan(&workspaceID); err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "invitation_not_found", "A pending invitation was not found.") + return + } + resolvedWorkspaceID := "" + if workspaceID != nil { + resolvedWorkspaceID = *workspaceID + } + if !s.canManageInvitations(w, r, resolvedWorkspaceID) { + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The invitation could not be revoked.") + return + } + defer rollback(tx, r.Context()) + result, err := tx.Exec(r.Context(), `UPDATE application_invitations SET revoked_at=now(),updated_at=now() +WHERE id=$1 AND application_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL`, invitationID, applicationID) + if err != nil || result.RowsAffected() != 1 { + kernel.WriteProblem(w, r, http.StatusNotFound, "invitation_not_found", "A pending invitation was not found.") + return + } + parsed, parseErr := uuid.Parse(applicationID) + if parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &parsed, "application_invitation.revoked", "application_invitation/"+invitationID, actor(r), map[string]any{"invitation_id": invitationID, "workspace_id": workspaceID, "status": "revoked"}) + } + if parseErr != nil || err != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "invitation_revoke_failed", "The invitation could not be revoked.") + return + } + w.WriteHeader(http.StatusNoContent) +} + +func (s *Server) canManageInvitations(w http.ResponseWriter, r *http.Request, workspaceID string) bool { + current := actor(r) + switch current.Type { + case "control_user": + return true + case "client": + if actorHasPermission(current, applicationPermission(r, "invitations/manage")) || + workspaceID != "" && actorHasPermission(current, applicationPermission(r, "workspaces/"+workspaceID+"/invitations/manage")) { + return true + } + case "user": + config, err := s.internalApplicationConfig(r) + if err == nil && config.UserInvitationsEnabled && workspaceID != "" { + request := r.Clone(r.Context()) + routeContext := chi.NewRouteContext() + if existing := chi.RouteContext(r.Context()); existing != nil { + *routeContext = *existing + } + routeContext.URLParams.Add("workspace_id", workspaceID) + request = request.WithContext(context.WithValue(request.Context(), chi.RouteCtxKey, routeContext)) + if s.canAccessWorkspace(request, true) || s.canAccessWorkspace(request, false) && actorHasPermission(current, applicationPermission(r, "workspaces/"+workspaceID+"/invitations/manage")) { + return true + } + } + } + kernel.WriteProblem(w, r, http.StatusForbidden, "invitation_management_required", "Invitation management permission is required.") + return false +} + +func (s *Server) exchangeInvitation(w http.ResponseWriter, r *http.Request) { + var request struct { + InvitationID string `json:"invitation_id,omitempty"` + Email string `json:"email,omitempty"` + Code string `json:"code,omitempty"` + LinkToken string `json:"link_token,omitempty"` + CodeChallenge string `json:"code_challenge"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + if !invitationPKCEChallengePattern.MatchString(request.CodeChallenge) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "pkce_required", "A valid S256 PKCE code challenge is required.") + return + } + applicationID := chi.URLParam(r, "application_id") + request.Email = kernel.NormalizeEmail(request.Email) + codePath := request.Email != "" && request.Code != "" && request.InvitationID == "" && request.LinkToken == "" + linkPath := request.InvitationID != "" && request.LinkToken != "" && request.Email == "" && request.Code == "" + request.Code = strings.ToUpper(strings.TrimSpace(request.Code)) + if !codePath && !linkPath || codePath && !invitationCodePattern.MatchString(request.Code) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_invitation_credential", "Provide either email with code or invitation ID with link token.") + return + } + rateLimitSubject := request.InvitationID + if rateLimitSubject == "" { + rateLimitSubject = request.Email + } + if rateLimitSubject == "" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invitation_identifier_required", "An invitation ID or recipient email is required.") + return + } + if !s.allowAuthAttempt(w, r, "invitation_exchange", applicationID+":"+rateLimitSubject, 10, 15*time.Minute) { + return + } + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The invitation could not be accepted.") + return + } + defer rollback(tx, r.Context()) + var invitationID, email string + var workspaceID *string + var appRoles, workspaceRoles []string + var codeDigest, linkDigest []byte + query := `SELECT id,workspace_id,normalized_email,application_roles,workspace_roles,code_credential_digest,link_credential_digest +FROM application_invitations WHERE application_id=$1 AND accepted_at IS NULL AND revoked_at IS NULL AND expires_at>now()` + args := []any{applicationID} + if request.InvitationID != "" { + query += ` AND id=$2` + args = append(args, request.InvitationID) + } else { + query += ` AND normalized_email=$2 AND code_credential_digest=$3` + args = append(args, request.Email, s.app.Vault.Digest(strings.ToUpper(request.Code))) + } + query += ` FOR UPDATE` + err = tx.QueryRow(r.Context(), query, args...).Scan(&invitationID, &workspaceID, &email, &appRoles, &workspaceRoles, &codeDigest, &linkDigest) + valid := err == nil && ((request.Code != "" && request.Email == email && equalBytes(codeDigest, s.app.Vault.Digest(strings.ToUpper(request.Code)))) || + (request.LinkToken != "" && equalBytes(linkDigest, s.app.Vault.Digest(request.LinkToken)))) + if !valid { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_invitation", "The invitation is invalid, expired, or already used.") + return + } + var userID, status string + err = tx.QueryRow(r.Context(), `SELECT id,status FROM users WHERE application_id=$1 AND normalized_email=$2 FOR UPDATE`, applicationID, email).Scan(&userID, &status) + if err == pgx.ErrNoRows { + if limitErr := enforceUserLimit(r.Context(), tx, applicationID); limitErr != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "invited_user_creation_failed", "The invited account could not be created.") + return + } + userID, status = kernel.NewID().String(), "active" + _, err = tx.Exec(r.Context(), `INSERT INTO users(id,application_id,email,normalized_email,email_verified_at) +VALUES($1,$2,$3,$3,now())`, userID, applicationID, email) + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &parsedApplicationID, "user.created", "user/"+userID, map[string]any{"type": "invitation"}, map[string]any{"user_id": userID, "email_verified": true, "is_org_verified": false}) + } + } else if err == nil && status == "active" { + _, err = tx.Exec(r.Context(), `UPDATE users SET email_verified_at=COALESCE(email_verified_at,now()),updated_at=now() WHERE id=$1 AND application_id=$2`, userID, applicationID) + } + if err != nil || status != "active" { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invited_account_unavailable", "The invited account is unavailable.") + return + } + roleWorkspaceID := workspaceID + if workspaceID != nil { + var owner bool + _ = tx.QueryRow(r.Context(), `SELECT owner_user_id=$3 FROM workspaces WHERE id=$1 AND application_id=$2`, *workspaceID, applicationID, userID).Scan(&owner) + if !owner { + _, err = tx.Exec(r.Context(), `INSERT INTO workspace_memberships(application_id,workspace_id,user_id) VALUES($1,$2,$3) ON CONFLICT DO NOTHING`, applicationID, *workspaceID, userID) + } else { + roleWorkspaceID = nil + } + } + if err == nil { + err = assignInvitationRoles(r.Context(), tx, applicationID, userID, roleWorkspaceID, appRoles, workspaceRoles) + } + if err == nil { + result, updateErr := tx.Exec(r.Context(), `UPDATE application_invitations SET accepted_at=now(),updated_at=now() WHERE id=$1 AND accepted_at IS NULL AND revoked_at IS NULL`, invitationID) + err = updateErr + if err == nil && result.RowsAffected() != 1 { + err = pgx.ErrNoRows + } + } + authorizationCode, codeErr := secure.RandomToken("p93_invitation_code_", 32) + if err == nil && codeErr == nil { + _, err = tx.Exec(r.Context(), `INSERT INTO invitation_authorization_codes(id,application_id,user_id,code_digest,code_challenge,expires_at) +VALUES($1,$2,$3,$4,$5,now()+interval '5 minutes')`, kernel.NewID(), applicationID, userID, s.app.Vault.Digest(authorizationCode), request.CodeChallenge) + } else if codeErr != nil { + err = codeErr + } + parsed, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &parsed, "application_invitation.accepted", "application_invitation/"+invitationID, map[string]any{"type": "user", "id": userID}, map[string]any{"invitation_id": invitationID, "user_id": userID, "workspace_id": workspaceID, "status": "accepted"}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "invitation_acceptance_failed", "The invitation could not be accepted.") + return + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"authorization_code": authorizationCode, "expires_in": 300}) +} + +func (s *Server) redeemInvitationAuthorizationCode(w http.ResponseWriter, r *http.Request) { + var request struct { + AuthorizationCode string `json:"authorization_code"` + CodeVerifier string `json:"code_verifier"` + } + if !kernel.DecodeJSON(w, r, &request) { + return + } + if !invitationPKCEVerifierPattern.MatchString(request.CodeVerifier) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_pkce_verifier", "A valid PKCE code verifier is required.") + return + } + digest := sha256.Sum256([]byte(request.CodeVerifier)) + challenge := base64.RawURLEncoding.EncodeToString(digest[:]) + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The invitation authorization code could not be redeemed.") + return + } + defer rollback(tx, r.Context()) + var id, userID, expectedChallenge string + err = tx.QueryRow(r.Context(), `SELECT id,user_id,code_challenge FROM invitation_authorization_codes +WHERE application_id=$1 AND code_digest=$2 AND used_at IS NULL AND expires_at>now() FOR UPDATE`, chi.URLParam(r, "application_id"), s.app.Vault.Digest(request.AuthorizationCode)).Scan(&id, &userID, &expectedChallenge) + if err != nil || !equalBytes([]byte(challenge), []byte(expectedChallenge)) { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_invitation_authorization_code", "The invitation authorization code is invalid, expired, or already used.") + return + } + result, err := tx.Exec(r.Context(), `UPDATE invitation_authorization_codes SET used_at=now() WHERE id=$1 AND used_at IS NULL`, id) + if err != nil || result.RowsAffected() != 1 || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "invitation_authorization_conflict", "The invitation authorization code was already used.") + return + } + s.completePrimaryAuthentication(w, r, userID, []string{"invitation", "pkce"}) +} + +func assignInvitationRoles(ctx context.Context, tx pgx.Tx, applicationID, userID string, workspaceID *string, appRoles, workspaceRoles []string) error { + for _, roleKey := range appRoles { + _, err := tx.Exec(ctx, `INSERT INTO role_assignments(id,application_id,user_id,role_id) +SELECT $1,$2,$3,id FROM roles WHERE application_id=$2 AND key=$4 AND scope='application' ON CONFLICT DO NOTHING`, kernel.NewID(), applicationID, userID, roleKey) + if err != nil { + return err + } + } + if workspaceID != nil { + for _, roleKey := range workspaceRoles { + _, err := tx.Exec(ctx, `INSERT INTO role_assignments(id,application_id,user_id,role_id,workspace_id) +SELECT $1,$2,$3,id,$4 FROM roles WHERE application_id=$2 AND key=$5 AND scope='workspace' ON CONFLICT DO NOTHING`, kernel.NewID(), applicationID, userID, *workspaceID, roleKey) + if err != nil { + return err + } + } + } + return nil +} + +func (s *Server) listWorkspaceAccess(w http.ResponseWriter, r *http.Request) { + if actor(r).Type == "user" && !s.canAccessWorkspace(r, false) { + kernel.WriteProblem(w, r, http.StatusForbidden, "workspace_access_required", "Workspace access is required.") + return + } + applicationID, workspaceID := chi.URLParam(r, "application_id"), chi.URLParam(r, "workspace_id") + items := []map[string]any{} + var ownerID, ownerEmail, firstName, lastName string + if s.app.DB.QueryRow(r.Context(), `SELECT u.id,u.email,u.first_name,u.last_name FROM workspaces w JOIN users u ON u.id=w.owner_user_id +WHERE w.id=$1 AND w.application_id=$2 AND w.deleted_at IS NULL`, workspaceID, applicationID).Scan(&ownerID, &ownerEmail, &firstName, &lastName) != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "workspace_not_found", "The workspace was not found.") + return + } + items = append(items, map[string]any{"entry_type": "user", "status": "owner", "user_id": ownerID, "email": ownerEmail, "first_name": firstName, "last_name": lastName, "role_keys": []string{}}) + rows, _ := s.app.DB.Query(r.Context(), `SELECT u.id,u.email,u.first_name,u.last_name,COALESCE(array_agg(DISTINCT ro.key) FILTER(WHERE ro.key IS NOT NULL),'{}') +FROM workspace_memberships m JOIN users u ON u.id=m.user_id LEFT JOIN role_assignments ra ON ra.user_id=u.id AND ra.workspace_id=m.workspace_id +LEFT JOIN roles ro ON ro.id=ra.role_id WHERE m.application_id=$1 AND m.workspace_id=$2 GROUP BY u.id ORDER BY u.email`, applicationID, workspaceID) + if rows != nil { + defer rows.Close() + for rows.Next() { + var id, email, first, last string + var roles []string + if rows.Scan(&id, &email, &first, &last, &roles) == nil { + items = append(items, map[string]any{"entry_type": "user", "status": "active", "user_id": id, "email": email, "first_name": first, "last_name": last, "role_keys": roles}) + } + } + } + invites, _ := s.app.DB.Query(r.Context(), `SELECT id,normalized_email,workspace_roles,expires_at,last_sent_at,resend_available_at FROM application_invitations +WHERE application_id=$1 AND workspace_id=$2 AND accepted_at IS NULL AND revoked_at IS NULL ORDER BY created_at DESC`, applicationID, workspaceID) + if invites != nil { + defer invites.Close() + for invites.Next() { + var id, email string + var roles []string + var expires, sent, resend time.Time + if invites.Scan(&id, &email, &roles, &expires, &sent, &resend) == nil { + status := "pending" + if expires.Before(s.app.Now()) { + status = "expired" + } + items = append(items, map[string]any{"entry_type": "invitation", "status": status, "invitation_id": id, "email": email, "role_keys": roles, "expires_at": expires, "last_sent_at": sent, "resend_available_at": resend}) + } + } + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) +} diff --git a/internal/httpapi/issuer_lifecycle.go b/internal/httpapi/issuer_lifecycle.go index 77bfeef..8b66c9b 100644 --- a/internal/httpapi/issuer_lifecycle.go +++ b/internal/httpapi/issuer_lifecycle.go @@ -11,6 +11,25 @@ import ( "github.com/supaapps/platform93/internal/secure" ) +func (s *Server) getClient(w http.ResponseWriter, r *http.Request) { + var id, clientID, name, clientType string + var redirectURIs, allowedGrants, allowedScopes []string + var createdAt, updatedAt time.Time + err := s.app.DB.QueryRow(r.Context(), `SELECT id,client_id,name,client_type,redirect_uris,allowed_grants,allowed_scopes,created_at,updated_at +FROM clients WHERE application_id=$1 AND client_id=$2 AND disabled_at IS NULL`, + chi.URLParam(r, "application_id"), chi.URLParam(r, "client_id")).Scan( + &id, &clientID, &name, &clientType, &redirectURIs, &allowedGrants, &allowedScopes, &createdAt, &updatedAt) + if err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "client_not_found", "The client was not found.") + return + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{ + "id": id, "client_id": clientID, "name": name, "client_type": clientType, + "redirect_uris": redirectURIs, "allowed_grants": allowedGrants, "allowed_scopes": allowedScopes, + "created_at": createdAt, "updated_at": updatedAt, + }) +} + func (s *Server) updateClient(w http.ResponseWriter, r *http.Request) { var request struct { Name *string `json:"name"` @@ -21,6 +40,18 @@ func (s *Server) updateClient(w http.ResponseWriter, r *http.Request) { if !kernel.DecodeJSON(w, r, &request) { return } + if request.RedirectURIs != nil { + var clientType string + if err := s.app.DB.QueryRow(r.Context(), `SELECT client_type FROM clients WHERE application_id=$1 AND client_id=$2 AND disabled_at IS NULL`, + chi.URLParam(r, "application_id"), chi.URLParam(r, "client_id")).Scan(&clientType); err != nil { + kernel.WriteProblem(w, r, http.StatusNotFound, "client_not_found", "The client was not found.") + return + } + if err := validateClientRedirectURIs(clientType, request.RedirectURIs); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_redirect_uri", err.Error()) + return + } + } result, err := s.app.DB.Exec(r.Context(), `UPDATE clients SET name=COALESCE($1,name), redirect_uris=CASE WHEN $2::text[] IS NULL THEN redirect_uris ELSE $2 END, allowed_grants=CASE WHEN $3::text[] IS NULL THEN allowed_grants ELSE $3 END, diff --git a/internal/httpapi/lifecycle_worker.go b/internal/httpapi/lifecycle_worker.go new file mode 100644 index 0000000..7ed9d71 --- /dev/null +++ b/internal/httpapi/lifecycle_worker.go @@ -0,0 +1,96 @@ +package httpapi + +import ( + "context" + + "github.com/google/uuid" + "github.com/jackc/pgx/v5" + "github.com/supaapps/platform93/internal/platform" +) + +// RunLifecycleSweep records time-driven transitions exactly once and emits their +// events in the same transaction as the state marker. +func RunLifecycleSweep(ctx context.Context, app *platform.App) error { + for range 100 { + processed, err := expireInvitation(ctx, app) + if err != nil { + return err + } + if !processed { + break + } + } + for range 100 { + processed, err := expireEntitlement(ctx, app) + if err != nil { + return err + } + if !processed { + break + } + } + return nil +} + +func expireInvitation(ctx context.Context, app *platform.App) (bool, error) { + tx, err := app.DB.Begin(ctx) + if err != nil { + return false, err + } + defer tx.Rollback(ctx) + var invitationID string + var applicationID uuid.UUID + var workspaceID *string + err = tx.QueryRow(ctx, `SELECT id,application_id,workspace_id FROM application_invitations +WHERE accepted_at IS NULL AND revoked_at IS NULL AND expiration_recorded_at IS NULL AND expires_at<=now() +ORDER BY expires_at,id FOR UPDATE SKIP LOCKED LIMIT 1`).Scan(&invitationID, &applicationID, &workspaceID) + if err == pgx.ErrNoRows { + return false, nil + } + if err != nil { + return false, err + } + if _, err = tx.Exec(ctx, `UPDATE application_invitations SET expiration_recorded_at=now(),updated_at=now() WHERE id=$1`, invitationID); err != nil { + return false, err + } + if _, err = app.Emit(ctx, tx, &applicationID, "application_invitation.expired", "application_invitation/"+invitationID, map[string]any{"type": "worker"}, map[string]any{"invitation_id": invitationID, "workspace_id": workspaceID, "status": "expired"}); err != nil { + return false, err + } + return true, tx.Commit(ctx) +} + +func expireEntitlement(ctx context.Context, app *platform.App) (bool, error) { + tx, err := app.DB.Begin(ctx) + if err != nil { + return false, err + } + defer tx.Rollback(ctx) + var grantID, subjectType, subjectID string + var applicationID uuid.UUID + var externalReference *string + err = tx.QueryRow(ctx, `SELECT g.id,g.application_id,g.subject_type,g.subject_id,g.external_reference +FROM entitlement_grants g LEFT JOIN LATERAL ( + SELECT action,expires_at FROM entitlement_grant_actions WHERE grant_id=g.id ORDER BY created_at DESC,id DESC LIMIT 1 +) latest ON true +WHERE g.expiration_recorded_at IS NULL AND COALESCE(latest.expires_at,g.expires_at)<=now() +AND COALESCE(latest.action,'active')<>'revoked' +ORDER BY COALESCE(latest.expires_at,g.expires_at),g.id FOR UPDATE OF g SKIP LOCKED LIMIT 1`).Scan(&grantID, &applicationID, &subjectType, &subjectID, &externalReference) + if err == pgx.ErrNoRows { + return false, nil + } + if err != nil { + return false, err + } + if _, err = tx.Exec(ctx, `UPDATE entitlement_grants SET expiration_recorded_at=now() WHERE id=$1`, grantID); err != nil { + return false, err + } + actor := map[string]any{"type": "worker"} + data := map[string]any{"grant_id": grantID, "subject_type": subjectType, "subject_id": subjectID, "external_reference": externalReference, "status": "expired"} + if _, err = app.Emit(ctx, tx, &applicationID, "entitlement.expired", "entitlement/"+grantID, actor, data); err != nil { + return false, err + } + if _, err = app.Emit(ctx, tx, &applicationID, "entitlement.effective_changed", subjectType+"/"+subjectID, actor, data); err != nil { + return false, err + } + return true, tx.Commit(ctx) +} diff --git a/internal/httpapi/local_entitlement_snapshot_test.go b/internal/httpapi/local_entitlement_snapshot_test.go index 37b4999..9f93b2e 100644 --- a/internal/httpapi/local_entitlement_snapshot_test.go +++ b/internal/httpapi/local_entitlement_snapshot_test.go @@ -33,7 +33,7 @@ func TestLocalEntitlementApprovalUsesCheckoutFeatureSnapshot(t *testing.T) { server := &Server{app: platform.New(db, vault, "https://platform93.test")} organizationID, applicationID := kernel.NewID(), kernel.NewID() - userID, operatorID, productID, priceID, featureID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() + userID, controlUserID, productID, priceID, featureID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() suffix := applicationID.String() statements := []struct { query string @@ -41,7 +41,7 @@ func TestLocalEntitlementApprovalUsesCheckoutFeatureSnapshot(t *testing.T) { }{ {`INSERT INTO organizations(id,name,slug) VALUES($1,'Test',$2)`, []any{organizationID, "snapshot-" + suffix}}, {`INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'Test',$3)`, []any{applicationID, organizationID, "snapshot-" + suffix}}, - {`INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, []any{operatorID, "operator-" + suffix + "@example.test"}}, + {`INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, []any{controlUserID, "control_user-" + suffix + "@example.test"}}, {`INSERT INTO users(id,application_id,email,normalized_email) VALUES($1,$2,$3,$3)`, []any{userID, applicationID, "user-" + suffix + "@example.test"}}, {`INSERT INTO products(id,application_id,key,name,status) VALUES($1,$2,$3,'Local','active')`, []any{productID, applicationID, "product-" + suffix}}, {`INSERT INTO prices(id,application_id,product_id,key,mode,amount_minor,currency,validity_seconds) VALUES($1,$2,$3,$4,'local',1000,'CHF',3600)`, []any{priceID, applicationID, productID, "price-" + suffix}}, @@ -54,7 +54,8 @@ func TestLocalEntitlementApprovalUsesCheckoutFeatureSnapshot(t *testing.T) { } } - checkoutRequest := requestWithRoute(t, "POST", `/`, map[string]any{"price_id": priceID}, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "user", ID: userID.String()}) + externalReference := "local-order-" + suffix + checkoutRequest := requestWithRoute(t, "POST", `/`, map[string]any{"price_id": priceID, "external_reference": externalReference}, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "user", ID: userID.String()}) checkoutResponse := httptest.NewRecorder() server.createLocalCheckout(checkoutResponse, checkoutRequest) if checkoutResponse.Code != 201 { @@ -72,7 +73,7 @@ func TestLocalEntitlementApprovalUsesCheckoutFeatureSnapshot(t *testing.T) { approveRequest := requestWithRoute(t, "POST", `/`, map[string]any{"reason": "verified"}, map[string]string{ "application_id": applicationID.String(), "request_id": checkout.ID, - }, kernel.Actor{Type: "operator", ID: operatorID.String()}) + }, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) approveResponse := httptest.NewRecorder() server.approveLocalRequest(approveResponse, approveRequest) if approveResponse.Code != 200 { @@ -89,6 +90,25 @@ func TestLocalEntitlementApprovalUsesCheckoutFeatureSnapshot(t *testing.T) { if value, ok := features["access-"+suffix].(bool); !ok || !value { t.Fatalf("approval used mutable catalog state: %#v", features) } + var requestReference, grantReference string + if err = db.QueryRow(context.Background(), `SELECT r.external_reference,g.external_reference +FROM local_entitlement_requests r JOIN entitlement_grants g ON g.source_id=r.id AND g.source_type='local_request' +WHERE r.id=$1`, checkout.ID).Scan(&requestReference, &grantReference); err != nil { + t.Fatal(err) + } + if requestReference != externalReference || grantReference != externalReference { + t.Fatalf("external reference was not preserved: request=%q grant=%q", requestReference, grantReference) + } + var createdEventReference, approvedEventReference string + if err = db.QueryRow(context.Background(), `SELECT +(SELECT data->>'external_reference' FROM domain_events WHERE application_id=$1 AND event_type='local_entitlement_request.created' AND subject=$2), +(SELECT data->>'external_reference' FROM domain_events WHERE application_id=$1 AND event_type='local_entitlement_request.approved' AND subject=$2)`, + applicationID, "local_entitlement_request/"+checkout.ID).Scan(&createdEventReference, &approvedEventReference); err != nil { + t.Fatal(err) + } + if createdEventReference != externalReference || approvedEventReference != externalReference { + t.Fatalf("external reference was omitted from local lifecycle events: created=%q approved=%q", createdEventReference, approvedEventReference) + } } func requestWithRoute(t *testing.T, method, target string, body any, params map[string]string, current kernel.Actor) *http.Request { diff --git a/internal/httpapi/migration_parity_unit_test.go b/internal/httpapi/migration_parity_unit_test.go new file mode 100644 index 0000000..60ef998 --- /dev/null +++ b/internal/httpapi/migration_parity_unit_test.go @@ -0,0 +1,47 @@ +package httpapi + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/supaapps/platform93/internal/kernel" +) + +func TestMachineNotificationRejectsBrowserRequests(t *testing.T) { + t.Parallel() + request := httptest.NewRequest(http.MethodPost, "/v1/applications/app/notifications", nil) + request.Header.Set("Origin", "https://app.example") + request = request.WithContext(kernel.WithActor(request.Context(), kernel.Actor{Type: "client"})) + recorder := httptest.NewRecorder() + new(Server).queueMachineNotification(recorder, request) + if recorder.Code != http.StatusForbidden { + t.Fatalf("expected browser request to be rejected, got %d", recorder.Code) + } +} + +func TestApplicationServiceAPIsRequireMachineActor(t *testing.T) { + t.Parallel() + request := httptest.NewRequest(http.MethodGet, "/v1/applications/app/users", nil) + request = request.WithContext(kernel.WithActor(request.Context(), kernel.Actor{Type: "user", Permissions: []string{"/applications/app/users/read"}})) + recorder := httptest.NewRecorder() + if requireApplicationPermission(recorder, request, "users/read") { + t.Fatal("application user was accepted by a machine service API") + } + if recorder.Code != http.StatusForbidden { + t.Fatalf("expected forbidden response, got %d", recorder.Code) + } +} + +func TestInvitationPKCEValidation(t *testing.T) { + t.Parallel() + if !invitationPKCEChallengePattern.MatchString("abcdefghijklmnopqrstuvwxyzABCDEFGH012345678") { + t.Fatal("valid 43-character S256 challenge was rejected") + } + if invitationPKCEChallengePattern.MatchString("abcdefghijklmnopqrstuvwxyzABCDEFGH01234567+") { + t.Fatal("non-base64url challenge was accepted") + } + if !invitationPKCEVerifierPattern.MatchString("abcdefghijklmnopqrstuvwxyzABCDEFGH012345678") { + t.Fatal("valid PKCE verifier was rejected") + } +} diff --git a/internal/httpapi/notification_lifecycle.go b/internal/httpapi/notification_lifecycle.go index 5217f5a..5d1a9e8 100644 --- a/internal/httpapi/notification_lifecycle.go +++ b/internal/httpapi/notification_lifecycle.go @@ -480,7 +480,7 @@ func (s *Server) previewNotificationTemplateForScope(w http.ResponseWriter, r *h if request.Variables == nil { request.Variables = map[string]any{} } - request.Variables["recipient_email"] = "operator@example.com" + request.Variables["recipient_email"] = "control_user@example.com" request.Variables["current_year"] = time.Now().UTC().Year() } request.Variables["message_locale"] = template.Locale diff --git a/internal/httpapi/notification_management.go b/internal/httpapi/notification_management.go index 38d02e2..2bfc482 100644 --- a/internal/httpapi/notification_management.go +++ b/internal/httpapi/notification_management.go @@ -218,7 +218,21 @@ func (s *Server) queueNotification(w http.ResponseWriter, r *http.Request) { if !kernel.DecodeJSON(w, r, &request) { return } + if actor(r).Type == "client" && strings.HasPrefix(request.TemplateKey, "platform93.") { + kernel.WriteProblem(w, r, http.StatusForbidden, "system_notification_template_reserved", "Platform93 system templates can only be sent by their owning security or billing flow.") + return + } applicationID := chi.URLParam(r, "application_id") + if actor(r).Type == "client" { + permission := applicationPermission(r, "notifications/send") + if request.UserID == "" { + permission = applicationPermission(r, "notifications/send_external") + } + if !actorHasPermission(actor(r), permission) { + kernel.WriteProblem(w, r, http.StatusForbidden, "notification_permission_required", "The machine client does not have permission to send this notification.") + return + } + } var err error var userLocale string request.Recipient, request.Variables, userLocale, err = s.resolveNotificationTemplateVariables(r.Context(), applicationID, request.UserID, request.Recipient, request.Variables, time.Now()) @@ -318,6 +332,18 @@ VALUES($1,$2,$3,$4,$5,$6)`, kernel.NewID(), id, attachment.Filename, safeContent }) } +func (s *Server) queueMachineNotification(w http.ResponseWriter, r *http.Request) { + if actor(r).Type != "client" { + kernel.WriteProblem(w, r, http.StatusForbidden, "machine_client_required", "A machine client token is required to send notifications.") + return + } + if r.Header.Get("Origin") != "" || r.Header.Get("Sec-Fetch-Mode") != "" { + kernel.WriteProblem(w, r, http.StatusForbidden, "browser_request_forbidden", "Machine notification delivery is available only to backend callers.") + return + } + s.queueNotification(w, r) +} + func (s *Server) listMyNotificationPreferences(w http.ResponseWriter, r *http.Request) { rows, err := s.app.DB.Query(r.Context(), `SELECT category,email_enabled,updated_at FROM notification_preferences WHERE application_id=$1 AND user_id=$2 ORDER BY category`, chi.URLParam(r, "application_id"), actor(r).ID) diff --git a/internal/httpapi/notification_provider_scope_test.go b/internal/httpapi/notification_provider_scope_test.go index 1437486..ea3d2e8 100644 --- a/internal/httpapi/notification_provider_scope_test.go +++ b/internal/httpapi/notification_provider_scope_test.go @@ -31,7 +31,7 @@ func TestInstallationNotificationProviderIsScopeIsolated(t *testing.T) { t.Fatal(err) } server := &Server{app: platform.New(db, vault, "https://platform93.test")} - operatorID := kernel.NewID() + controlUserID := kernel.NewID() organizationID, applicationID := kernel.NewID(), kernel.NewID() installationProviderID, applicationProviderID := kernel.NewID(), kernel.NewID() suffix := applicationID.String() @@ -41,10 +41,10 @@ func TestInstallationNotificationProviderIsScopeIsolated(t *testing.T) { if _, err = db.Exec(context.Background(), `INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'SMTP scope test',$3)`, applicationID, organizationID, "smtp-scope-"+suffix); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, operatorID, "smtp-operator-"+suffix+"@example.test"); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, controlUserID, "smtp-control_user-"+suffix+"@example.test"); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,'admin')`, operatorID); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'admin')`, controlUserID); err != nil { t.Fatal(err) } config, _ := json.Marshal(storedSMTPConfig{Host: "smtp.example.test", Port: 587, TLSMode: "starttls"}) @@ -56,15 +56,15 @@ VALUES($1,NULL,'Installation SMTP',$2,'installation@example.test'),($3,$4,'Appli t.Fatal(err) } - operator := kernel.Actor{Type: "operator", ID: operatorID.String()} - wrongScope := requestWithRoute(t, "GET", "/", nil, map[string]string{"provider_id": applicationProviderID.String()}, operator) + controlUser := kernel.Actor{Type: "control_user", ID: controlUserID.String()} + wrongScope := requestWithRoute(t, "GET", "/", nil, map[string]string{"provider_id": applicationProviderID.String()}, controlUser) response := httptest.NewRecorder() server.getInstallationNotificationProvider(response, wrongScope) if response.Code != 404 { t.Fatalf("application provider escaped into installation scope: %d %s", response.Code, response.Body.String()) } - testRequest := requestWithRoute(t, "POST", "/", map[string]any{"recipient": "operator@example.test"}, map[string]string{"provider_id": installationProviderID.String()}, operator) + testRequest := requestWithRoute(t, "POST", "/", map[string]any{"recipient": "control_user@example.test"}, map[string]string{"provider_id": installationProviderID.String()}, controlUser) response = httptest.NewRecorder() server.testInstallationNotificationProvider(response, testRequest) if response.Code != 202 { diff --git a/internal/httpapi/notification_reporting.go b/internal/httpapi/notification_reporting.go index efeab91..e638c7c 100644 --- a/internal/httpapi/notification_reporting.go +++ b/internal/httpapi/notification_reporting.go @@ -111,6 +111,9 @@ func (s *Server) disableNotificationProviderForScope(w http.ResponseWriter, r *h if !s.authorizeProviderScope(w, r, scope, true) { return } + if scope.name() == "installation" && !s.allowControlSMTPRemoval(w, r, chi.URLParam(r, "provider_id"), r.URL.Query().Get("confirm_affected_users") == "true") { + return + } result, err := s.app.DB.Exec(r.Context(), `UPDATE notification_providers SET disabled_at=now() WHERE id=$1 AND application_id IS NOT DISTINCT FROM $2::uuid AND organization_id IS NOT DISTINCT FROM $3::uuid AND disabled_at IS NULL`, chi.URLParam(r, "provider_id"), scope.ApplicationID, scope.OrganizationID) if err != nil || result.RowsAffected() != 1 { diff --git a/internal/httpapi/notification_system.go b/internal/httpapi/notification_system.go index 5e63e68..0c710a0 100644 --- a/internal/httpapi/notification_system.go +++ b/internal/httpapi/notification_system.go @@ -10,13 +10,14 @@ import ( ) const ( - operatorSignInTemplate = "platform93.operator_sign_in" - applicationSignInTemplate = "platform93.application_sign_in" - verifyEmailTemplate = "platform93.verify_email" - changeEmailTemplate = "platform93.change_email" - passwordResetTemplate = "platform93.password_reset" - organizationInviteTemplate = "platform93.organization_invitation" - workspaceInvitationTemplate = "platform93.workspace_invitation" + controlUserSignInTemplate = "platform93.control_user_sign_in" + controlUserInvitationTemplate = "platform93.control_user_invitation" + applicationSignInTemplate = "platform93.application_sign_in" + verifyEmailTemplate = "platform93.verify_email" + changeEmailTemplate = "platform93.change_email" + passwordResetTemplate = "platform93.password_reset" + organizationInviteTemplate = "platform93.organization_invitation" + workspaceInvitationTemplate = "platform93.workspace_invitation" ) func accountChallengeTemplate(intent string) string { @@ -60,10 +61,15 @@ func (s *Server) renderSystemNotification(ctx context.Context, applicationID *st var err error if applicationID != nil { var applicationName, applicationSlug string - if err = s.app.DB.QueryRow(ctx, `SELECT name,slug FROM applications WHERE id=$1 AND deleted_at IS NULL`, *applicationID).Scan(&applicationName, &applicationSlug); err == nil { + var publicConfigRaw []byte + if err = s.app.DB.QueryRow(ctx, `SELECT name,slug,public_config FROM applications WHERE id=$1 AND deleted_at IS NULL`, *applicationID).Scan(&applicationName, &applicationSlug, &publicConfigRaw); err == nil { + publicConfig := decodeMap(publicConfigRaw) variables["application_id"] = *applicationID variables["application_name"] = applicationName variables["application_slug"] = applicationSlug + variables["support_name"] = stringWithFallback(toString(publicConfig["support_name"]), applicationName) + variables["support_email"] = strings.TrimSpace(toString(publicConfig["support_email"])) + variables["support_url"] = strings.TrimSpace(toString(publicConfig["support_url"])) var recipientLocale string if s.app.DB.QueryRow(ctx, `SELECT locale FROM users WHERE application_id=$1 AND normalized_email=$2 AND status='active'`, *applicationID, recipient).Scan(&recipientLocale) == nil { diff --git a/internal/httpapi/notification_template_variables.go b/internal/httpapi/notification_template_variables.go index 715ac2b..7695684 100644 --- a/internal/httpapi/notification_template_variables.go +++ b/internal/httpapi/notification_template_variables.go @@ -24,6 +24,9 @@ func notificationTemplateVariableCatalog() []notificationTemplateVariableDefinit {Key: "application_id", Label: "Application ID", Description: "Immutable ID of the application sending the message.", Type: "string", Availability: "always", Sample: "01993f4e-7ae1-7000-8000-000000000001"}, {Key: "application_name", Label: "Application name", Description: "Display name of the application sending the message.", Type: "string", Availability: "always", Sample: "Acme Cloud"}, {Key: "application_slug", Label: "Application slug", Description: "Current human-readable application slug.", Type: "string", Availability: "always", Sample: "acme-cloud"}, + {Key: "support_name", Label: "Support name", Description: "Application support name from public configuration, falling back to the application name.", Type: "string", Availability: "always", Sample: "Acme Support"}, + {Key: "support_email", Label: "Support email", Description: "Application support email from public configuration, or an empty string when unset.", Type: "string", Availability: "always", Sample: "support@example.com"}, + {Key: "support_url", Label: "Support URL", Description: "Application support URL from public configuration, or an empty string when unset.", Type: "string", Availability: "always", Sample: "https://example.com/support"}, {Key: "recipient_email", Label: "Recipient email", Description: "Normalized delivery address for this message.", Type: "string", Availability: "always", Sample: "ada@example.com"}, {Key: "current_year", Label: "Current year", Description: "UTC year at the moment the notification is queued.", Type: "integer", Availability: "always", Sample: 2026}, {Key: "message_locale", Label: "Message locale", Description: "BCP 47 locale of the template localization selected for this delivery.", Type: "string", Availability: "always", Sample: "de-CH"}, @@ -104,13 +107,18 @@ func (s *Server) listInstallationNotificationTemplateVariables(w http.ResponseWr func (s *Server) resolveNotificationTemplateVariables(ctx context.Context, applicationID, userID, recipient string, supplied map[string]any, at time.Time) (string, map[string]any, string, error) { var applicationName, applicationSlug string - if err := s.app.DB.QueryRow(ctx, `SELECT name,slug FROM applications WHERE id=$1 AND deleted_at IS NULL`, applicationID).Scan(&applicationName, &applicationSlug); err != nil { + var publicConfigRaw []byte + if err := s.app.DB.QueryRow(ctx, `SELECT name,slug,public_config FROM applications WHERE id=$1 AND deleted_at IS NULL`, applicationID).Scan(&applicationName, &applicationSlug, &publicConfigRaw); err != nil { return "", nil, "", err } + publicConfig := decodeMap(publicConfigRaw) resolved := map[string]any{ "application_id": applicationID, "application_name": applicationName, "application_slug": applicationSlug, + "support_name": stringWithFallback(toString(publicConfig["support_name"]), applicationName), + "support_email": strings.TrimSpace(toString(publicConfig["support_email"])), + "support_url": strings.TrimSpace(toString(publicConfig["support_url"])), "current_year": at.UTC().Year(), } userLocale := "" @@ -142,6 +150,13 @@ FROM users WHERE id=$1 AND application_id=$2 AND status='active'`, userID, appli return recipient, mergeNotificationTemplateVariables(supplied, resolved), userLocale, nil } +func stringWithFallback(value, fallback string) string { + if value = strings.TrimSpace(value); value != "" { + return value + } + return fallback +} + func sampleNotificationTemplateVariables(variables map[string]any) map[string]any { preview := make(map[string]any, len(variables)+len(notificationTemplateVariableCatalog())) for key, value := range variables { diff --git a/internal/httpapi/oauth.go b/internal/httpapi/oauth.go index d4aa9a6..892860d 100644 --- a/internal/httpapi/oauth.go +++ b/internal/httpapi/oauth.go @@ -128,15 +128,29 @@ WHERE id=$1 AND application_id=$2 AND user_id=$3 AND revoked_at IS NULL`, curren return } session := oauthserver.NewSession(current.ID, email, provider.KID, s.app.Now().UTC()) + customClaims, claimsErr := s.customClaimsForUser(r.Context(), chi.URLParam(r, "application_id"), current.ID) + if claimsErr != nil { + provider.OAuth.WriteAuthorizeError(r.Context(), w, request, fosite.ErrServerError) + return + } + effective, accessErr := s.userEffectiveAccess(r, applicationID, current.ID) + if accessErr != nil { + provider.OAuth.WriteAuthorizeError(r.Context(), w, request, fosite.ErrServerError) + return + } + if current.DelegatedBy != "" { + effective.Roles = emptyRoleClaims() + } session.AccessClaims.Extra = map[string]any{ "application_id": chi.URLParam(r, "application_id"), "client_id": request.GetClient().GetID(), "token_kind": "access", "email": email, "email_verified": emailVerified, "is_org_verified": orgVerified, "locale": locale, "actor_type": "user", "scope": strings.Join(current.Permissions, " "), - "sid": current.SessionID, "amr": amr, + "sid": current.SessionID, "amr": amr, "custom_claims": customClaims, "roles": effective.Roles, } session.IDClaims.Extra = map[string]any{ "application_id": chi.URLParam(r, "application_id"), "email": email, "email_verified": emailVerified, "is_org_verified": orgVerified, "locale": locale, "actor_type": "user", "given_name": firstName, "family_name": lastName, "sid": current.SessionID, + "custom_claims": customClaims, "roles": effective.Roles, } session.IDClaims.AuthTime = authenticatedAt session.IDClaims.AuthenticationMethodsReferences = amr @@ -214,12 +228,17 @@ func (s *Server) oauthToken(w http.ResponseWriter, r *http.Request) { request.GrantAudience(s.app.ApplicationAudience(applicationID)) if request.GetGrantTypes().ExactOne("client_credentials") { clientID := request.GetClient().GetID() - replaceApplicationScopes(request, s.clientScopes(r, applicationID, clientID)) + effective, accessErr := s.clientEffectiveAccess(r, applicationID, clientID) + if accessErr != nil { + provider.OAuth.WriteAccessError(r.Context(), w, request, fosite.ErrInvalidGrant) + return + } + replaceApplicationScopes(request, effective.Scopes) session.Subject = clientID session.AccessClaims.Subject = clientID session.AccessClaims.Extra = map[string]any{ "application_id": chi.URLParam(r, "application_id"), "client_id": clientID, - "token_kind": "machine", "actor_type": "client", "amr": []string{"client_credentials"}, + "token_kind": "machine", "actor_type": "client", "amr": []string{"client_credentials"}, "roles": effective.Roles, } request.SetSession(session) } else if request.GetGrantTypes().ExactOne("refresh_token") || request.GetGrantTypes().ExactOne("authorization_code") { @@ -235,7 +254,28 @@ WHERE id=$1 AND application_id=$2 AND status='active')`, storedSession.Subject, provider.OAuth.WriteAccessError(r.Context(), w, request, fosite.ErrInvalidGrant) return } - replaceApplicationScopes(request, s.scopes(r, applicationID, storedSession.Subject)) + effective, accessErr := s.userEffectiveAccess(r, applicationID, storedSession.Subject) + if accessErr != nil { + provider.OAuth.WriteAccessError(r.Context(), w, request, fosite.ErrInvalidGrant) + return + } + replaceApplicationScopes(request, effective.Scopes) + customClaims, claimsErr := s.customClaimsForUser(r.Context(), applicationID.String(), storedSession.Subject) + if claimsErr != nil { + provider.OAuth.WriteAccessError(r.Context(), w, request, fosite.ErrInvalidGrant) + return + } + if storedSession.AccessClaims.Extra == nil { + storedSession.AccessClaims.Extra = map[string]any{} + } + storedSession.AccessClaims.Extra["custom_claims"] = customClaims + storedSession.AccessClaims.Extra["roles"] = effective.Roles + if storedSession.IDClaims.Extra == nil { + storedSession.IDClaims.Extra = map[string]any{} + } + storedSession.IDClaims.Extra["custom_claims"] = customClaims + storedSession.IDClaims.Extra["roles"] = effective.Roles + request.SetSession(storedSession) } response, err := provider.OAuth.NewAccessResponse(r.Context(), request) if err != nil { @@ -296,6 +336,21 @@ FROM users WHERE id=$1 AND application_id=$2`, subject, chi.URLParam(r, "applica return } result := map[string]any{"sub": subject, "is_org_verified": orgVerified} + applicationID, applicationErr := uuid.Parse(chi.URLParam(r, "application_id")) + if applicationErr != nil { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_token", "The token application is invalid.") + return + } + if effective, accessErr := s.userEffectiveAccess(r, applicationID, subject); accessErr == nil { + result["roles"] = effective.Roles + result["scope"] = strings.Join(effective.Scopes, " ") + } else { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_authorization_data", "The subject authorization data is invalid.") + return + } + if customClaims, claimsErr := s.customClaimsForUser(r.Context(), chi.URLParam(r, "application_id"), subject); claimsErr == nil && len(customClaims) > 0 { + result["custom_claims"] = customClaims + } if request.GetGrantedScopes().Has("email") { result["email"] = email result["email_verified"] = verified diff --git a/internal/httpapi/operations.go b/internal/httpapi/operations.go index b51fe3d..59c870a 100644 --- a/internal/httpapi/operations.go +++ b/internal/httpapi/operations.go @@ -109,7 +109,7 @@ func (s *Server) listAudit(w http.ResponseWriter, r *http.Request) { func (s *Server) listOrganizationAudit(w http.ResponseWriter, r *http.Request) { organizationID := chi.URLParam(r, "organization_id") - if !s.operatorBelongsToOrganization(r, organizationID) { + if !s.controlUserBelongsToOrganization(r, organizationID) { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_not_found", "The organization was not found.") return } diff --git a/internal/httpapi/operator_account.go b/internal/httpapi/operator_account.go deleted file mode 100644 index d2c3256..0000000 --- a/internal/httpapi/operator_account.go +++ /dev/null @@ -1,174 +0,0 @@ -package httpapi - -import ( - "net/http" - "strings" - "sync" - "time" - - "github.com/supaapps/platform93/internal/identity" - "github.com/supaapps/platform93/internal/kernel" - "github.com/supaapps/platform93/internal/secure" -) - -var ( - operatorDummyPasswordOnce sync.Once - operatorDummyPasswordHash string -) - -func (s *Server) getOperatorAccount(w http.ResponseWriter, r *http.Request) { - var id, email, displayName, status string - var passwordEnabled bool - var createdAt, updatedAt time.Time - err := s.app.DB.QueryRow(r.Context(), `SELECT id,email,display_name,status,password_hash IS NOT NULL,created_at,updated_at -FROM operators WHERE id=$1`, actor(r).ID).Scan(&id, &email, &displayName, &status, &passwordEnabled, &createdAt, &updatedAt) - if err != nil { - kernel.WriteProblem(w, r, http.StatusNotFound, "operator_not_found", "The signed-in operator account was not found.") - return - } - installationRole, hasInstallationRole := s.installationRole(r) - var installationRoleValue any - if hasInstallationRole { - installationRoleValue = installationRole - } - rows, err := s.app.DB.Query(r.Context(), `SELECT o.id,o.name,m.role FROM organization_memberships m -JOIN organizations o ON o.id=m.organization_id WHERE m.operator_id=$1 AND o.deleted_at IS NULL ORDER BY o.name,o.id`, id) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Operator organization access could not be loaded.") - return - } - defer rows.Close() - organizations := []map[string]any{} - for rows.Next() { - var organizationID, name, role string - if rows.Scan(&organizationID, &name, &role) == nil { - organizations = append(organizations, map[string]any{"id": organizationID, "name": name, "role": role}) - } - } - kernel.WriteJSON(w, http.StatusOK, map[string]any{ - "id": id, "email": email, "display_name": displayName, "status": status, - "installation_role": installationRoleValue, "organizations": organizations, - "sign_in_methods": map[string]any{"email_code": true, "magic_link": true, "password": passwordEnabled, "external_identities": []any{}}, - "created_at": createdAt, "updated_at": updatedAt, - }) -} - -func (s *Server) updateOperatorAccount(w http.ResponseWriter, r *http.Request) { - var request struct { - DisplayName string `json:"display_name"` - } - if !kernel.DecodeJSON(w, r, &request) { - return - } - request.DisplayName = strings.TrimSpace(request.DisplayName) - if request.DisplayName == "" || len(request.DisplayName) > 200 { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_operator_profile", "Display name must contain between 1 and 200 characters.") - return - } - result, err := s.app.DB.Exec(r.Context(), `UPDATE operators SET display_name=$1,updated_at=now() WHERE id=$2 AND status='active'`, request.DisplayName, actor(r).ID) - if err != nil || result.RowsAffected() != 1 { - kernel.WriteProblem(w, r, http.StatusNotFound, "operator_not_found", "The signed-in operator account was not found.") - return - } - w.WriteHeader(http.StatusNoContent) -} - -func (s *Server) changeOperatorPassword(w http.ResponseWriter, r *http.Request) { - var request struct { - CurrentPassword string `json:"current_password"` - NewPassword string `json:"new_password"` - } - if !kernel.DecodeJSON(w, r, &request) { - return - } - var currentHash *string - var sessionCreatedAt time.Time - err := s.app.DB.QueryRow(r.Context(), `SELECT o.password_hash,s.created_at FROM operators o -JOIN operator_sessions s ON s.operator_id=o.id WHERE o.id=$1 AND s.id=$2 AND s.revoked_at IS NULL AND s.expires_at>now()`, actor(r).ID, actor(r).SessionID). - Scan(¤tHash, &sessionCreatedAt) - if err != nil { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "operator_session_required", "An active operator session is required.") - return - } - if currentHash != nil { - if !identity.VerifyPassword(*currentHash, request.CurrentPassword) { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_current_password", "The current password is incorrect.") - return - } - } else if sessionCreatedAt.Before(s.app.Now().Add(-10 * time.Minute)) { - kernel.WriteProblem(w, r, http.StatusConflict, "recent_authentication_required", "Sign in again with an email code or magic link before adding a password.") - return - } - newHash, err := identity.HashPassword(request.NewPassword) - if err != nil { - kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_password", err.Error()) - return - } - tx, err := s.app.DB.Begin(r.Context()) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The operator password could not be changed.") - return - } - defer rollback(tx, r.Context()) - _, err = tx.Exec(r.Context(), `UPDATE operators SET password_hash=$1,updated_at=now() WHERE id=$2`, newHash, actor(r).ID) - if err == nil { - _, err = tx.Exec(r.Context(), `UPDATE operator_sessions SET revoked_at=COALESCE(revoked_at,now()) -WHERE operator_id=$1 AND id<>$2 AND revoked_at IS NULL`, actor(r).ID, actor(r).SessionID) - } - if err != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "operator_password_change_failed", "The operator password could not be committed.") - return - } - w.WriteHeader(http.StatusNoContent) -} - -func (s *Server) operatorPasswordLogin(w http.ResponseWriter, r *http.Request) { - var request struct { - Email string `json:"email"` - Password string `json:"password"` - } - if !kernel.DecodeJSON(w, r, &request) { - return - } - normalized := kernel.NormalizeEmail(request.Email) - if !s.allowAuthAttempt(w, r, "operator_password", normalized, 8, 10*time.Minute) { - return - } - var operatorID, passwordHash string - err := s.app.DB.QueryRow(r.Context(), `SELECT id,password_hash FROM operators -WHERE normalized_email=$1 AND status='active' AND password_hash IS NOT NULL`, normalized).Scan(&operatorID, &passwordHash) - found := err == nil - if !found { - operatorDummyPasswordOnce.Do(func() { - operatorDummyPasswordHash, _ = identity.HashPassword("platform93 timing equalization credential") - }) - passwordHash = operatorDummyPasswordHash - } - validPassword := identity.VerifyPassword(passwordHash, request.Password) - if !found || !validPassword { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_operator_credentials", "The email address or password is incorrect.") - return - } - refresh, err := secure.RandomToken("p93_ops_refresh_", 32) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "credential_generation_failed", "The operator session could not be created.") - return - } - sessionID := kernel.NewID() - tx, err := s.app.DB.Begin(r.Context()) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The operator session could not be created.") - return - } - defer rollback(tx, r.Context()) - _, err = tx.Exec(r.Context(), `INSERT INTO operator_sessions -(id,operator_id,refresh_digest,kind,ip_address,user_agent,expires_at) VALUES($1,$2,$3,'operator',$4,$5,$6)`, - sessionID, operatorID, s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), s.app.Now().Add(12*time.Hour)) - access, tokenErr := s.issueOperatorAccessWithQuerier(r.Context(), tx, operatorID, sessionID.String(), "operator") - if err != nil || tokenErr != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "operator_session_failed", "The operator session could not be committed.") - return - } - s.setOperatorCookies(w, access, refresh, 12*time.Hour) - kernel.WriteJSON(w, http.StatusOK, map[string]any{"access_token": access, "refresh_token": refresh, "token_type": "Bearer", "expires_in": 300}) -} diff --git a/internal/httpapi/operator_account_test.go b/internal/httpapi/operator_account_test.go deleted file mode 100644 index 21556ae..0000000 --- a/internal/httpapi/operator_account_test.go +++ /dev/null @@ -1,107 +0,0 @@ -package httpapi - -import ( - "context" - "net/http" - "net/http/httptest" - "os" - "strings" - "testing" - "time" - - "github.com/supaapps/platform93/internal/database" - "github.com/supaapps/platform93/internal/identity" - "github.com/supaapps/platform93/internal/kernel" - "github.com/supaapps/platform93/internal/platform" - "github.com/supaapps/platform93/internal/secure" -) - -func TestOperatorAccountPasswordLifecycle(t *testing.T) { - databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") - if databaseURL == "" { - t.Skip("PLATFORM93_DATABASE_URL is not configured") - } - if err := database.Migrate(databaseURL); err != nil { - t.Fatal(err) - } - db, err := database.Open(context.Background(), databaseURL) - if err != nil { - t.Fatal(err) - } - defer db.Close() - vault, _ := secure.NewVault(make([]byte, 32)) - app := platform.New(db, vault, "https://platform93.test") - server := &Server{app: app} - operatorID, sessionID := kernel.NewID(), kernel.NewID() - email := "operator-" + operatorID.String() + "@example.test" - refresh := "p93_ops_refresh_" + operatorID.String() - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Test Operator')`, operatorID, email); err != nil { - t.Fatal(err) - } - if _, err = db.Exec(context.Background(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,'owner')`, operatorID); err != nil { - t.Fatal(err) - } - if _, err = db.Exec(context.Background(), `INSERT INTO operator_sessions(id,operator_id,refresh_digest,kind,expires_at) VALUES($1,$2,$3,'operator',$4)`, sessionID, operatorID, vault.Digest(refresh), time.Now().Add(time.Hour)); err != nil { - t.Fatal(err) - } - tx, err := db.Begin(context.Background()) - if err != nil { - t.Fatal(err) - } - if err = app.EnsureSigningKey(context.Background(), tx); err != nil { - t.Fatal(err) - } - if err = tx.Commit(context.Background()); err != nil { - t.Fatal(err) - } - current := kernel.Actor{Type: "operator", ID: operatorID.String(), SessionID: sessionID.String()} - - accountRequest := requestWithRoute(t, http.MethodGet, "/", nil, nil, current) - accountResponse := httptest.NewRecorder() - server.getOperatorAccount(accountResponse, accountRequest) - if accountResponse.Code != http.StatusOK || !strings.Contains(accountResponse.Body.String(), `"password":false`) || !strings.Contains(accountResponse.Body.String(), email) { - t.Fatalf("unexpected operator account response: %d %s", accountResponse.Code, accountResponse.Body.String()) - } - - addRequest := requestWithRoute(t, http.MethodPut, "/", map[string]any{"new_password": "correct horse battery staple"}, nil, current) - addResponse := httptest.NewRecorder() - server.changeOperatorPassword(addResponse, addRequest) - if addResponse.Code != http.StatusNoContent { - t.Fatalf("first operator password was not added: %d %s", addResponse.Code, addResponse.Body.String()) - } - var passwordHash string - if err = db.QueryRow(context.Background(), `SELECT password_hash FROM operators WHERE id=$1`, operatorID).Scan(&passwordHash); err != nil { - t.Fatal(err) - } - if !identity.VerifyPassword(passwordHash, "correct horse battery staple") { - t.Fatal("operator password was not stored as a valid Argon2id hash") - } - - loginRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{"email": email, "password": "correct horse battery staple"}, nil, kernel.Actor{}) - loginResponse := httptest.NewRecorder() - server.operatorPasswordLogin(loginResponse, loginRequest) - if loginResponse.Code != http.StatusOK || !strings.Contains(loginResponse.Header().Get("Set-Cookie"), "p93_operator_access=") { - t.Fatalf("operator password login failed: %d %s", loginResponse.Code, loginResponse.Body.String()) - } - - wrongRequest := requestWithRoute(t, http.MethodPut, "/", map[string]any{"current_password": "incorrect password value", "new_password": "another correct horse battery"}, nil, current) - wrongResponse := httptest.NewRecorder() - server.changeOperatorPassword(wrongResponse, wrongRequest) - if wrongResponse.Code != http.StatusUnauthorized { - t.Fatalf("incorrect current password was accepted: %d %s", wrongResponse.Code, wrongResponse.Body.String()) - } - - changeRequest := requestWithRoute(t, http.MethodPut, "/", map[string]any{"current_password": "correct horse battery staple", "new_password": "another correct horse battery"}, nil, current) - changeResponse := httptest.NewRecorder() - server.changeOperatorPassword(changeResponse, changeRequest) - if changeResponse.Code != http.StatusNoContent { - t.Fatalf("operator password change failed: %d %s", changeResponse.Code, changeResponse.Body.String()) - } - var activeSessions int - if err = db.QueryRow(context.Background(), `SELECT count(*) FROM operator_sessions WHERE operator_id=$1 AND revoked_at IS NULL`, operatorID).Scan(&activeSessions); err != nil { - t.Fatal(err) - } - if activeSessions != 1 { - t.Fatalf("expected only the current session after password change, got %d", activeSessions) - } -} diff --git a/internal/httpapi/operator_boundary_test.go b/internal/httpapi/operator_boundary_test.go deleted file mode 100644 index bfd799f..0000000 --- a/internal/httpapi/operator_boundary_test.go +++ /dev/null @@ -1,106 +0,0 @@ -package httpapi - -import ( - "context" - "net/http" - "net/http/httptest" - "os" - "testing" - "time" - - "github.com/supaapps/platform93/internal/database" - "github.com/supaapps/platform93/internal/kernel" - "github.com/supaapps/platform93/internal/platform" - "github.com/supaapps/platform93/internal/secure" -) - -func TestOperatorMiddlewareEnforcesOrganizationBoundaryAndWriteRole(t *testing.T) { - databaseURL := os.Getenv("PLATFORM93_DATABASE_URL") - if databaseURL == "" { - t.Skip("PLATFORM93_DATABASE_URL is not configured") - } - if err := database.Migrate(databaseURL); err != nil { - t.Fatal(err) - } - db, err := database.Open(context.Background(), databaseURL) - if err != nil { - t.Fatal(err) - } - defer db.Close() - vault, _ := secure.NewVault(make([]byte, 32)) - server := &Server{app: platform.New(db, vault, "https://platform93.test")} - operatorID, sessionID := kernel.NewID(), kernel.NewID() - organizationID, applicationID := kernel.NewID(), kernel.NewID() - suffix := applicationID.String() - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email,display_name) VALUES($1,$2,$2,'Boundary operator')`, operatorID, "boundary-"+suffix+"@example.test"); err != nil { - t.Fatal(err) - } - if _, err = db.Exec(context.Background(), `INSERT INTO operator_sessions(id,operator_id,refresh_digest,kind,expires_at) VALUES($1,$2,$3,'operator',$4)`, sessionID, operatorID, vault.Digest("refresh-"+suffix), time.Now().Add(time.Hour)); err != nil { - t.Fatal(err) - } - tx, err := db.Begin(context.Background()) - if err != nil { - t.Fatal(err) - } - if err = server.app.EnsureSigningKey(context.Background(), tx); err != nil { - t.Fatal(err) - } - if err = tx.Commit(context.Background()); err != nil { - t.Fatal(err) - } - token, err := server.issueOperatorAccess(context.Background(), operatorID.String(), sessionID.String(), "operator") - if err != nil { - t.Fatal(err) - } - if _, err = db.Exec(context.Background(), `INSERT INTO organizations(id,name,slug) VALUES($1,'Boundary org',$2)`, organizationID, "boundary-"+suffix); err != nil { - t.Fatal(err) - } - if _, err = db.Exec(context.Background(), `INSERT INTO applications(id,organization_id,name,slug) VALUES($1,$2,'Boundary app',$3)`, applicationID, organizationID, "boundary-"+suffix); err != nil { - t.Fatal(err) - } - - called := false - handler := server.requireOperator(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { - called = true - w.WriteHeader(http.StatusNoContent) - })) - request := requestWithRoute(t, "GET", "/v1/applications/"+suffix+"/users", nil, map[string]string{"application_id": suffix}, kernel.Actor{}) - request.AddCookie(&http.Cookie{Name: "p93_operator_access", Value: token}) - response := httptest.NewRecorder() - handler.ServeHTTP(response, request) - if response.Code != http.StatusNotFound || called { - t.Fatalf("operator crossed organization boundary: status=%d called=%v", response.Code, called) - } - - if _, err = db.Exec(context.Background(), `INSERT INTO organization_memberships(organization_id,operator_id,role) VALUES($1,$2,'auditor')`, organizationID, operatorID); err != nil { - t.Fatal(err) - } - request = requestWithRoute(t, "POST", "/v1/applications/"+suffix+"/users", map[string]any{}, map[string]string{"application_id": suffix}, kernel.Actor{}) - request.AddCookie(&http.Cookie{Name: "p93_operator_access", Value: token}) - response = httptest.NewRecorder() - handler.ServeHTTP(response, request) - if response.Code != http.StatusForbidden || called { - t.Fatalf("read-only operator gained write access: status=%d called=%v", response.Code, called) - } - - if _, err = db.Exec(context.Background(), `UPDATE organization_memberships SET role='admin' WHERE organization_id=$1 AND operator_id=$2`, organizationID, operatorID); err != nil { - t.Fatal(err) - } - called = false - request = requestWithRoute(t, "POST", "/v1/control/applications/"+suffix+"/users", map[string]any{}, map[string]string{"application_id": suffix}, kernel.Actor{}) - request.Header.Set("Origin", "https://platform93.test") - request.AddCookie(&http.Cookie{Name: "p93_operator_access", Value: token}) - response = httptest.NewRecorder() - handler.ServeHTTP(response, request) - if response.Code != http.StatusNoContent || !called { - t.Fatalf("authorized operator write failed: status=%d called=%v", response.Code, called) - } - var method, path string - if err = db.QueryRow(context.Background(), `SELECT changes->>'method',changes->>'path' FROM audit_records -WHERE actor_id=$1 AND application_id=$2 AND action='http.post' ORDER BY created_at DESC LIMIT 1`, operatorID, applicationID).Scan(&method, &path); err != nil { - t.Fatal(err) - } - if method != http.MethodPost || path != "/v1/control/applications/"+suffix+"/users" { - t.Fatalf("unexpected audit changes: method=%q path=%q", method, path) - } -} diff --git a/internal/httpapi/operator_sessions.go b/internal/httpapi/operator_sessions.go deleted file mode 100644 index a1208f7..0000000 --- a/internal/httpapi/operator_sessions.go +++ /dev/null @@ -1,108 +0,0 @@ -package httpapi - -import ( - "encoding/json" - "net" - "net/http" - "strings" - "time" - - "github.com/go-chi/chi/v5" - "github.com/supaapps/platform93/internal/kernel" - "github.com/supaapps/platform93/internal/secure" -) - -func (s *Server) refreshOperatorSession(w http.ResponseWriter, r *http.Request) { - var request struct { - RefreshToken string `json:"refresh_token"` - } - if cookie, cookieErr := r.Cookie("p93_operator_refresh"); cookieErr == nil { - request.RefreshToken = cookie.Value - } - if r.Body != nil && r.ContentLength != 0 { - _ = json.NewDecoder(r.Body).Decode(&request) - } - if request.RefreshToken == "" { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "operator_refresh_required", "An operator refresh credential is required.") - return - } - token, err := secure.RandomToken("p93_ops_refresh_", 32) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "credential_generation_failed", "The operator session could not be rotated.") - return - } - expiresAt := s.app.Now().Add(12 * time.Hour) - var sessionID, operatorID string - err = s.app.DB.QueryRow(r.Context(), `UPDATE operator_sessions SET refresh_digest=$1,expires_at=$2,last_used_at=now(),ip_address=$3,user_agent=$4 -WHERE refresh_digest=$5 AND kind='operator' AND revoked_at IS NULL AND expires_at>now() -RETURNING id,operator_id`, s.app.Vault.Digest(token), expiresAt, requestIPAddress(r), truncate(r.UserAgent(), 500), s.app.Vault.Digest(request.RefreshToken)).Scan(&sessionID, &operatorID) - if err != nil { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_operator_session", "The operator session could not be refreshed.") - return - } - access, err := s.issueOperatorAccess(r.Context(), operatorID, sessionID, "operator") - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "operator_token_failed", "The operator access token could not be issued.") - return - } - s.setOperatorCookies(w, access, token, 12*time.Hour) - kernel.WriteJSON(w, http.StatusOK, map[string]any{"access_token": access, "refresh_token": token, "token_type": "Bearer", "expires_in": 300, "refresh_expires_at": expiresAt}) -} - -func (s *Server) listOperatorSessions(w http.ResponseWriter, r *http.Request) { - rows, err := s.app.DB.Query(r.Context(), `SELECT id,ip_address::text,user_agent,last_used_at,expires_at,revoked_at,created_at -FROM operator_sessions WHERE operator_id=$1 AND kind='operator' ORDER BY created_at DESC,id DESC LIMIT 101`, actor(r).ID) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Operator sessions could not be loaded.") - return - } - defer rows.Close() - items := []map[string]any{} - for rows.Next() { - var id, userAgent string - var ipAddress *string - var lastUsedAt, expiresAt, createdAt time.Time - var revokedAt *time.Time - if rows.Scan(&id, &ipAddress, &userAgent, &lastUsedAt, &expiresAt, &revokedAt, &createdAt) == nil { - items = append(items, map[string]any{"id": id, "ip_address": ipAddress, "user_agent": userAgent, "last_used_at": lastUsedAt, - "expires_at": expiresAt, "revoked_at": revokedAt, "created_at": createdAt, "current": id == actor(r).SessionID}) - } - } - kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) -} - -func (s *Server) revokeOperatorSession(w http.ResponseWriter, r *http.Request) { - sessionID := chi.URLParam(r, "session_id") - result, err := s.app.DB.Exec(r.Context(), `UPDATE operator_sessions SET revoked_at=COALESCE(revoked_at,now()) -WHERE id=$1 AND operator_id=$2 AND kind='operator'`, sessionID, actor(r).ID) - if err != nil || result.RowsAffected() != 1 { - kernel.WriteProblem(w, r, http.StatusNotFound, "operator_session_not_found", "The operator session was not found.") - return - } - if sessionID == actor(r).SessionID { - s.clearOperatorCookies(w) - } - w.WriteHeader(http.StatusNoContent) -} - -func (s *Server) logoutAllOperatorSessions(w http.ResponseWriter, r *http.Request) { - _, err := s.app.DB.Exec(r.Context(), `UPDATE operator_sessions SET revoked_at=COALESCE(revoked_at,now()) -WHERE operator_id=$1 AND kind='operator'`, actor(r).ID) - if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "operator_logout_failed", "Operator sessions could not be revoked.") - return - } - s.clearOperatorCookies(w) - w.WriteHeader(http.StatusNoContent) -} - -func requestIPAddress(r *http.Request) any { - value := strings.TrimSpace(r.RemoteAddr) - if host, _, err := net.SplitHostPort(value); err == nil { - value = host - } - if net.ParseIP(value) == nil { - return nil - } - return value -} diff --git a/internal/httpapi/organization_policy.go b/internal/httpapi/organization_policy.go index 70e7c20..3b6a321 100644 --- a/internal/httpapi/organization_policy.go +++ b/internal/httpapi/organization_policy.go @@ -80,7 +80,7 @@ func (s *Server) requireOrganizationSetting(w http.ResponseWriter, r *http.Reque func (s *Server) getOrganizationPolicy(w http.ResponseWriter, r *http.Request) { organizationID := chi.URLParam(r, "organization_id") - if actor(r).Type != "management_client" && !s.operatorBelongsToOrganization(r, organizationID) { + if actor(r).Type != "management_client" && !s.controlUserBelongsToOrganization(r, organizationID) { kernel.WriteProblem(w, r, http.StatusNotFound, "organization_not_found", "The organization was not found.") return } diff --git a/internal/httpapi/permission_grants.go b/internal/httpapi/permission_grants.go new file mode 100644 index 0000000..335c592 --- /dev/null +++ b/internal/httpapi/permission_grants.go @@ -0,0 +1,357 @@ +package httpapi + +import ( + "net/http" + "strings" + "time" + + "github.com/go-chi/chi/v5" + "github.com/google/uuid" + platformauthz "github.com/supaapps/platform93/internal/authorization" + "github.com/supaapps/platform93/internal/kernel" +) + +type permissionGrantRequest struct { + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + WorkspaceID *string `json:"workspace_id,omitempty"` + Permission string `json:"permission"` + Reason string `json:"reason,omitempty"` +} + +func (s *Server) createPermissionGrant(w http.ResponseWriter, r *http.Request) { + if strings.TrimSpace(r.Header.Get("Idempotency-Key")) == "" { + kernel.WriteProblem(w, r, http.StatusBadRequest, "idempotency_key_required", "Permission grant creation requires an Idempotency-Key header.") + return + } + var request permissionGrantRequest + if !kernel.DecodeJSON(w, r, &request) { + return + } + if workspaceID := chi.URLParam(r, "workspace_id"); workspaceID != "" { + if request.WorkspaceID != nil && *request.WorkspaceID != workspaceID { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_grant_workspace", "The request workspace must match the route workspace.") + return + } + request.WorkspaceID = &workspaceID + } + request.Reason = strings.TrimSpace(request.Reason) + if request.SubjectType != "user" && request.SubjectType != "client" || request.SubjectID == "" || len(request.Reason) > 500 { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_grant", "A user or client subject and an optional reason of at most 500 characters are required.") + return + } + if err := platformauthz.ValidateRelativePermission(request.Permission); err != nil || strings.Split(request.Permission, ":")[0] == "roles" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission", "Permission must be a lowercase ASCII colon-delimited key; a wildcard is allowed only as the final complete segment.") + return + } + applicationID, err := uuid.Parse(chi.URLParam(r, "application_id")) + if err != nil { + kernel.WriteProblem(w, r, http.StatusBadRequest, "invalid_application_id", "The application identifier is invalid.") + return + } + if _, err = uuid.Parse(request.SubjectID); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_grant_subject", "The permission grant subject identifier is invalid.") + return + } + if request.WorkspaceID != nil { + if _, err = uuid.Parse(*request.WorkspaceID); err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_grant_workspace", "The permission grant workspace identifier is invalid.") + return + } + } + canonical, err := platformauthz.CanonicalScope(applicationID.String(), request.WorkspaceID, request.Permission) + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission", "The permission could not be converted to a canonical application scope.") + return + } + if !s.canManagePermissionGrant(r, applicationID, request.WorkspaceID, canonical) { + kernel.WriteProblem(w, r, http.StatusForbidden, "permission_grant_management_required", "The actor cannot grant this permission in the selected scope.") + return + } + if !s.validPermissionGrantSubject(r, applicationID, request.SubjectType, request.SubjectID, request.WorkspaceID) { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_grant_subject", "The active subject is not eligible for the selected application or workspace.") + return + } + id := kernel.NewID() + current := actor(r) + var userID, clientID *string + if request.SubjectType == "user" { + userID = &request.SubjectID + } else { + clientID = &request.SubjectID + } + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The permission grant could not be created.") + return + } + defer rollback(tx, r.Context()) + _, err = tx.Exec(r.Context(), `INSERT INTO permission_grants +(id,application_id,user_id,client_id,workspace_id,permission,canonical_scope,reason,created_by_type,created_by_id) +VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, id, applicationID, userID, clientID, request.WorkspaceID, request.Permission, canonical, request.Reason, current.Type, current.ID) + if err == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "authorization.permission_grant.created", "permission_grant/"+id.String(), current, + map[string]any{"grant_id": id, "subject_type": request.SubjectType, "subject_id": request.SubjectID, "workspace_id": request.WorkspaceID, "permission": request.Permission, "canonical_scope": canonical}) + } + if err != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "permission_grant_conflict", "An equivalent active permission grant already exists or the grant could not be committed.") + return + } + w.Header().Set("ETag", kernel.ETag(1)) + kernel.WriteJSON(w, http.StatusCreated, map[string]any{"id": id, "application_id": applicationID, "subject_type": request.SubjectType, + "subject_id": request.SubjectID, "workspace_id": request.WorkspaceID, "permission": request.Permission, "canonical_scope": canonical, + "reason": request.Reason, "status": "active", "version": 1, "created_at": s.app.Now()}) +} + +func (s *Server) listPermissionGrants(w http.ResponseWriter, r *http.Request) { + applicationID, err := uuid.Parse(chi.URLParam(r, "application_id")) + if err != nil { + kernel.WriteProblem(w, r, http.StatusBadRequest, "invalid_application_id", "The application identifier is invalid.") + return + } + workspaceID := chi.URLParam(r, "workspace_id") + var workspace *string + if workspaceID != "" { + workspace = &workspaceID + } + if !s.canReadPermissionGrants(r, applicationID, workspace) { + kernel.WriteProblem(w, r, http.StatusForbidden, "permission_grant_read_required", "Permission grant read access is required.") + return + } + subjectType := r.URL.Query().Get("subject_type") + subjectID := r.URL.Query().Get("subject_id") + status := r.URL.Query().Get("status") + if subjectType != "" && subjectType != "user" && subjectType != "client" || status != "" && status != "active" && status != "revoked" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_grant_filter", "Permission grant filters are invalid.") + return + } + var subjectFilter any + if subjectID != "" { + parsedSubjectID, parseErr := uuid.Parse(subjectID) + if parseErr != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_grant_filter", "The permission grant subject filter must be a UUID.") + return + } + subjectFilter = parsedSubjectID + } + rows, err := s.app.DB.Query(r.Context(), `SELECT application_id,id,user_id,client_id,workspace_id,permission,canonical_scope,reason, +created_by_type,created_by_id,revoked_by_type,revoked_by_id,revoked_reason,revoked_at,version,created_at +FROM permission_grants WHERE application_id=$1 +AND ($2::uuid IS NULL OR workspace_id=$2) AND ($3='' OR ($3='user' AND user_id IS NOT NULL) OR ($3='client' AND client_id IS NOT NULL)) +AND ($4::uuid IS NULL OR user_id=$4 OR client_id=$4) +AND ($5='' OR ($5='active' AND revoked_at IS NULL) OR ($5='revoked' AND revoked_at IS NOT NULL)) +ORDER BY created_at DESC,id DESC`, applicationID, workspace, subjectType, subjectFilter, status) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "Permission grants could not be loaded.") + return + } + defer rows.Close() + items := []map[string]any{} + for rows.Next() { + if grant, ok := scanPermissionGrant(rows); ok { + items = append(items, grant) + } + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"items": items, "next_cursor": nil}) +} + +func (s *Server) getPermissionGrant(w http.ResponseWriter, r *http.Request) { + grant, ok := s.loadPermissionGrant(r) + if !ok { + kernel.WriteProblem(w, r, http.StatusNotFound, "permission_grant_not_found", "The permission grant was not found.") + return + } + applicationID, _ := uuid.Parse(chi.URLParam(r, "application_id")) + workspaceID, _ := grant["workspace_id"].(*string) + if routeWorkspace := chi.URLParam(r, "workspace_id"); routeWorkspace != "" && (workspaceID == nil || *workspaceID != routeWorkspace) { + kernel.WriteProblem(w, r, http.StatusNotFound, "permission_grant_not_found", "The permission grant was not found.") + return + } + if !s.canReadPermissionGrants(r, applicationID, workspaceID) { + kernel.WriteProblem(w, r, http.StatusForbidden, "permission_grant_read_required", "Permission grant read access is required.") + return + } + w.Header().Set("ETag", kernel.ETag(grant["version"].(int64))) + kernel.WriteJSON(w, http.StatusOK, grant) +} + +func (s *Server) revokePermissionGrant(w http.ResponseWriter, r *http.Request) { + grant, ok := s.loadPermissionGrant(r) + if !ok { + kernel.WriteProblem(w, r, http.StatusNotFound, "permission_grant_not_found", "The permission grant was not found.") + return + } + applicationID, _ := uuid.Parse(chi.URLParam(r, "application_id")) + workspaceID, _ := grant["workspace_id"].(*string) + if routeWorkspace := chi.URLParam(r, "workspace_id"); routeWorkspace != "" && (workspaceID == nil || *workspaceID != routeWorkspace) { + kernel.WriteProblem(w, r, http.StatusNotFound, "permission_grant_not_found", "The permission grant was not found.") + return + } + canonical := grant["canonical_scope"].(string) + if !s.canManagePermissionGrants(r, applicationID, workspaceID) { + kernel.WriteProblem(w, r, http.StatusForbidden, "permission_grant_management_required", "The actor cannot revoke this permission grant.") + return + } + version := grant["version"].(int64) + if strings.TrimSpace(r.Header.Get("If-Match")) == "" { + kernel.WriteProblem(w, r, http.StatusPreconditionRequired, "if_match_required", "Permission grant revocation requires the current ETag in If-Match.") + return + } + if !kernel.CheckIfMatch(w, r, version) { + return + } + current := actor(r) + reason := strings.TrimSpace(r.Header.Get("X-Audit-Reason")) + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The permission grant could not be revoked.") + return + } + defer rollback(tx, r.Context()) + result, err := tx.Exec(r.Context(), `UPDATE permission_grants SET revoked_by_type=$1,revoked_by_id=$2,revoked_reason=$3, +revoked_at=now(),version=version+1 WHERE id=$4 AND application_id=$5 AND version=$6 AND revoked_at IS NULL`, current.Type, current.ID, reason, + chi.URLParam(r, "grant_id"), applicationID, version) + if err == nil && result.RowsAffected() == 1 { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "authorization.permission_grant.revoked", "permission_grant/"+chi.URLParam(r, "grant_id"), current, + map[string]any{"grant_id": chi.URLParam(r, "grant_id"), "subject_type": grant["subject_type"], "subject_id": grant["subject_id"], + "workspace_id": workspaceID, "permission": grant["permission"], "canonical_scope": canonical}) + } else if err == nil { + err = http.ErrNotSupported + } + if err != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusConflict, "permission_grant_version_conflict", "The active permission grant changed concurrently.") + return + } + w.WriteHeader(http.StatusNoContent) +} + +func (s *Server) effectivePermissionAccess(w http.ResponseWriter, r *http.Request) { + applicationID, err := uuid.Parse(chi.URLParam(r, "application_id")) + if err != nil { + kernel.WriteProblem(w, r, http.StatusBadRequest, "invalid_application_id", "The application identifier is invalid.") + return + } + workspaceID := r.URL.Query().Get("workspace_id") + var workspace *string + if workspaceID != "" { + workspace = &workspaceID + } + if !s.canReadPermissionGrants(r, applicationID, workspace) { + kernel.WriteProblem(w, r, http.StatusForbidden, "permission_grant_read_required", "Effective access read permission is required.") + return + } + subjectType, subjectID := r.URL.Query().Get("subject_type"), r.URL.Query().Get("subject_id") + var access effectiveAccess + if subjectType == "user" { + access, err = s.userEffectiveAccess(r, applicationID, subjectID) + } else if subjectType == "client" { + var clientKey string + err = s.app.DB.QueryRow(r.Context(), `SELECT client_id FROM clients WHERE id=$1 AND application_id=$2 AND disabled_at IS NULL`, subjectID, applicationID).Scan(&clientKey) + if err == nil { + access, err = s.clientEffectiveAccess(r, applicationID, clientKey) + } + } else { + err = http.ErrNotSupported + } + if err != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_permission_subject", "The effective-access subject is invalid or contains invalid authorization data.") + return + } + kernel.WriteJSON(w, http.StatusOK, map[string]any{"subject_type": subjectType, "subject_id": subjectID, "roles": access.Roles, "scopes": access.Scopes, "provenance": access.Provenance}) +} + +func (s *Server) loadPermissionGrant(r *http.Request) (map[string]any, bool) { + return scanPermissionGrant(s.app.DB.QueryRow(r.Context(), `SELECT application_id,id,user_id,client_id,workspace_id,permission,canonical_scope,reason, +created_by_type,created_by_id,revoked_by_type,revoked_by_id,revoked_reason,revoked_at,version,created_at +FROM permission_grants WHERE id=$1 AND application_id=$2`, chi.URLParam(r, "grant_id"), chi.URLParam(r, "application_id"))) +} + +func scanPermissionGrant(row scanner) (map[string]any, bool) { + var applicationID, id, permission, canonical, reason, createdByType, createdByID string + var userID, clientID, workspaceID, revokedByType, revokedByID, revokedReason *string + var revokedAt *time.Time + var version int64 + var createdAt time.Time + if row.Scan(&applicationID, &id, &userID, &clientID, &workspaceID, &permission, &canonical, &reason, &createdByType, &createdByID, + &revokedByType, &revokedByID, &revokedReason, &revokedAt, &version, &createdAt) != nil { + return nil, false + } + subjectType, subjectID := "client", clientID + if userID != nil { + subjectType, subjectID = "user", userID + } + status := "active" + if revokedAt != nil { + status = "revoked" + } + return map[string]any{"id": id, "application_id": applicationID, "subject_type": subjectType, "subject_id": *subjectID, "workspace_id": workspaceID, + "permission": permission, "canonical_scope": canonical, "reason": reason, "created_by": map[string]any{"type": createdByType, "id": createdByID}, + "revoked_by": nullableActor(revokedByType, revokedByID), "revoked_reason": revokedReason, "revoked_at": revokedAt, + "status": status, "version": version, "created_at": createdAt}, true +} + +func nullableActor(actorType, actorID *string) any { + if actorType == nil || actorID == nil { + return nil + } + return map[string]any{"type": *actorType, "id": *actorID} +} + +func (s *Server) validPermissionGrantSubject(r *http.Request, applicationID uuid.UUID, subjectType, subjectID string, workspaceID *string) bool { + var valid bool + if subjectType == "user" { + if workspaceID == nil { + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM users WHERE id=$1 AND application_id=$2 AND status='active')`, subjectID, applicationID).Scan(&valid) + } else { + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM users u JOIN workspaces w ON w.application_id=u.application_id +WHERE u.id=$1 AND u.application_id=$2 AND u.status='active' AND w.id=$3 AND w.deleted_at IS NULL +AND (w.owner_user_id=u.id OR EXISTS(SELECT 1 FROM workspace_memberships m WHERE m.workspace_id=w.id AND m.user_id=u.id)))`, subjectID, applicationID, *workspaceID).Scan(&valid) + } + } else { + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM clients WHERE id=$1 AND application_id=$2 AND disabled_at IS NULL)`, subjectID, applicationID).Scan(&valid) + } + return valid +} + +func (s *Server) canReadPermissionGrants(r *http.Request, applicationID uuid.UUID, workspaceID *string) bool { + current := actor(r) + if current.Type == "control_user" { + return true + } + permission, err := platformauthz.CanonicalScope(applicationID.String(), workspaceID, "authorization:grants:read") + if err == nil && actorHasPermission(current, permission) { + return true + } + manage, err := platformauthz.CanonicalScope(applicationID.String(), workspaceID, "authorization:grants:manage") + if err == nil && actorHasPermission(current, manage) { + return true + } + return workspaceID != nil && current.Type == "user" && s.permissionGrantWorkspaceOwner(r, applicationID, current.ID, *workspaceID) +} + +func (s *Server) canManagePermissionGrant(r *http.Request, applicationID uuid.UUID, workspaceID *string, grantedScope string) bool { + if actor(r).Type == "control_user" { + return true + } + return s.canManagePermissionGrants(r, applicationID, workspaceID) && actorHasPermission(actor(r), grantedScope) +} + +func (s *Server) canManagePermissionGrants(r *http.Request, applicationID uuid.UUID, workspaceID *string) bool { + current := actor(r) + if current.Type == "control_user" { + return true + } + manage, err := platformauthz.CanonicalScope(applicationID.String(), workspaceID, "authorization:grants:manage") + manager := err == nil && actorHasPermission(current, manage) + if workspaceID != nil && current.Type == "user" && s.permissionGrantWorkspaceOwner(r, applicationID, current.ID, *workspaceID) { + manager = true + } + return manager +} + +func (s *Server) permissionGrantWorkspaceOwner(r *http.Request, applicationID uuid.UUID, userID, workspaceID string) bool { + var owner bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM workspaces +WHERE id=$1 AND application_id=$2 AND owner_user_id=$3 AND deleted_at IS NULL)`, workspaceID, applicationID, userID).Scan(&owner) + return owner +} diff --git a/internal/httpapi/provider_inheritance_updates_test.go b/internal/httpapi/provider_inheritance_updates_test.go index c1fd58b..27357a2 100644 --- a/internal/httpapi/provider_inheritance_updates_test.go +++ b/internal/httpapi/provider_inheritance_updates_test.go @@ -32,12 +32,12 @@ func TestProviderInheritanceUpdatesPreserveHealth(t *testing.T) { t.Fatal(err) } server := &Server{app: platform.New(db, vault, "https://platform93.test")} - operatorID, smtpID, stripeID, storageID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() + controlUserID, smtpID, stripeID, storageID := kernel.NewID(), kernel.NewID(), kernel.NewID(), kernel.NewID() suffix := smtpID.String() - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, operatorID, "provider-health-"+suffix+"@example.test"); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, controlUserID, "provider-health-"+suffix+"@example.test"); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,'owner')`, operatorID); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'owner')`, controlUserID); err != nil { t.Fatal(err) } smtpCiphertext, err := vault.Encrypt([]byte(`{"host":"smtp.example.test","port":587,"tls_mode":"starttls"}`), "notification-provider:"+smtpID.String()) @@ -67,7 +67,7 @@ VALUES($1,'Installation storage','http://127.0.0.1:9000','local','public',$2,tru t.Fatal(err) } - smtpRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": false}, map[string]string{"provider_id": smtpID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + smtpRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": false}, map[string]string{"provider_id": smtpID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) smtpResponse := httptest.NewRecorder() server.updateInstallationNotificationProvider(smtpResponse, smtpRequest) if smtpResponse.Code != http.StatusOK { @@ -82,7 +82,7 @@ VALUES($1,'Installation storage','http://127.0.0.1:9000','local','public',$2,tru t.Fatalf("SMTP health changed with inheritance: verified=%v inheritable=%v", storedVerifiedAt, smtpInheritable) } - stripeRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": false}, map[string]string{"provider_id": stripeID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + stripeRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": false}, map[string]string{"provider_id": stripeID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) stripeResponse := httptest.NewRecorder() server.updateInstallationBillingProvider(stripeResponse, stripeRequest) if stripeResponse.Code != http.StatusNoContent { @@ -97,7 +97,7 @@ VALUES($1,'Installation storage','http://127.0.0.1:9000','local','public',$2,tru t.Fatalf("Stripe health changed with inheritance: status=%s inheritable=%v", stripeStatus, stripeInheritable) } - storageRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": false}, map[string]string{"provider_id": storageID.String()}, kernel.Actor{Type: "operator", ID: operatorID.String()}) + storageRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"inheritable": false}, map[string]string{"provider_id": storageID.String()}, kernel.Actor{Type: "control_user", ID: controlUserID.String()}) storageResponse := httptest.NewRecorder() server.updateInstallationStorageProvider(storageResponse, storageRequest) if storageResponse.Code != http.StatusOK { diff --git a/internal/httpapi/provider_scope.go b/internal/httpapi/provider_scope.go index 38443ff..c681d75 100644 --- a/internal/httpapi/provider_scope.go +++ b/internal/httpapi/provider_scope.go @@ -47,7 +47,7 @@ func (s *Server) authorizeProviderScope(w http.ResponseWriter, r *http.Request, kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "An organization owner or administrator is required to manage application providers.") return false } - } else if !s.operatorBelongsToOrganization(r, organizationID) { + } else if !s.controlUserBelongsToOrganization(r, organizationID) { kernel.WriteProblem(w, r, http.StatusNotFound, "application_not_found", "The application was not found.") return false } @@ -72,7 +72,7 @@ FROM organization_policies WHERE organization_id=$1`, *scope.OrganizationID).Sca kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "An organization owner or administrator is required to manage providers.") return false } - if s.operatorBelongsToOrganization(r, *scope.OrganizationID) { + if s.controlUserBelongsToOrganization(r, *scope.OrganizationID) { return true } kernel.WriteProblem(w, r, http.StatusNotFound, "organization_not_found", "The organization was not found.") diff --git a/internal/httpapi/provider_scope_authorization_test.go b/internal/httpapi/provider_scope_authorization_test.go index 07b9fd0..fe151f0 100644 --- a/internal/httpapi/provider_scope_authorization_test.go +++ b/internal/httpapi/provider_scope_authorization_test.go @@ -39,21 +39,21 @@ func TestProviderScopeAuthorization(t *testing.T) { t.Fatal(err) } for id, prefix := range map[string]string{organizationAdminID.String(): "org-admin", organizationAuditorID.String(): "org-auditor", installationAuditorID.String(): "install-auditor", outsiderID.String(): "outsider"} { - if _, err = db.Exec(context.Background(), `INSERT INTO operators(id,email,normalized_email) VALUES($1,$2,$2)`, id, prefix+"-"+suffix+"@example.test"); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO control_users(id,email,normalized_email) VALUES($1,$2,$2)`, id, prefix+"-"+suffix+"@example.test"); err != nil { t.Fatal(err) } } - if _, err = db.Exec(context.Background(), `INSERT INTO organization_memberships(organization_id,operator_id,role) VALUES($1,$2,'auditor')`, organizationID, organizationAuditorID); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO organization_memberships(organization_id,control_user_id,role) VALUES($1,$2,'auditor')`, organizationID, organizationAuditorID); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO organization_memberships(organization_id,operator_id,role) VALUES($1,$2,'admin')`, organizationID, organizationAdminID); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO organization_memberships(organization_id,control_user_id,role) VALUES($1,$2,'admin')`, organizationID, organizationAdminID); err != nil { t.Fatal(err) } - if _, err = db.Exec(context.Background(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,'auditor')`, installationAuditorID); err != nil { + if _, err = db.Exec(context.Background(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'auditor')`, installationAuditorID); err != nil { t.Fatal(err) } - request := requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "operator", ID: organizationAuditorID.String()}) + request := requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "control_user", ID: organizationAuditorID.String()}) if !server.authorizeProviderScope(httptest.NewRecorder(), request, organizationProviderScope(organizationID.String()), false) { t.Fatal("organization auditor could not read organization providers") } @@ -75,7 +75,7 @@ func TestProviderScopeAuthorization(t *testing.T) { if _, err = db.Exec(context.Background(), `UPDATE organization_policies SET enabled_settings=jsonb_set(enabled_settings,'{application_provider_overrides}','false') WHERE organization_id=$1`, organizationID); err != nil { t.Fatal(err) } - request = requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "operator", ID: organizationAdminID.String()}) + request = requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "control_user", ID: organizationAdminID.String()}) if !server.authorizeApplicationStorageControl(httptest.NewRecorder(), request, applicationID.String(), true) { t.Fatal("organization admin could not manage application objects when provider overrides were disabled") } @@ -84,7 +84,7 @@ func TestProviderScopeAuthorization(t *testing.T) { t.Fatalf("organization admin configured an application provider while overrides were disabled: %d", response.Code) } - request = requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "operator", ID: outsiderID.String()}) + request = requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "control_user", ID: outsiderID.String()}) response = httptest.NewRecorder() if server.authorizeProviderScope(response, request, organizationProviderScope(organizationID.String()), false) || response.Code != 404 { t.Fatalf("organization provider scope leaked to outsider: %d", response.Code) @@ -94,7 +94,7 @@ func TestProviderScopeAuthorization(t *testing.T) { t.Fatalf("application provider scope leaked to outsider: %d", response.Code) } - request = requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "operator", ID: installationAuditorID.String()}) + request = requestWithRoute(t, "GET", "/", nil, nil, kernel.Actor{Type: "control_user", ID: installationAuditorID.String()}) if !server.authorizeProviderScope(httptest.NewRecorder(), request, installationProviderScope(), false) { t.Fatal("installation auditor could not read installation providers") } diff --git a/internal/httpapi/server.go b/internal/httpapi/server.go index 93b087c..41595d3 100644 --- a/internal/httpapi/server.go +++ b/internal/httpapi/server.go @@ -8,7 +8,9 @@ import ( "encoding/json" "io/fs" "log/slog" + "net" "net/http" + "net/url" "os" pathpkg "path" "regexp" @@ -45,7 +47,7 @@ func New(app *platform.App, adminAssets string) http.Handler { s := &Server{app: app, adminAssets: adminAssets} r := chi.NewRouter() // Do not trust forwarding headers until an explicit trusted-proxy boundary is configured. - r.Use(middleware.Recoverer, s.requestContext, s.accessLog, s.securityHeaders) + r.Use(middleware.Recoverer, s.requestContext, s.accessLog, s.securityHeaders, s.cors) r.Get("/healthz", s.health) r.Get("/readyz", s.ready) r.Get("/version", s.version) @@ -56,20 +58,27 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Post("/setup/bootstrap", s.bootstrap) r.With(s.requireSetup).Post("/setup/complete", s.completeSetup) r.With(s.requireSetup).Post("/setup/notification-providers", s.createInstallationNotificationProvider) - r.Post("/control/auth/email/start", s.operatorEmailStart) - r.Post("/control/auth/email/verify", s.operatorEmailVerify) - r.Post("/control/auth/password", s.operatorPasswordLogin) - r.Post("/control/auth/token/refresh", s.refreshOperatorSession) - r.Post("/control/auth/logout", s.operatorLogout) - r.Post("/control/organization-invitations/accept", s.acceptOrganizationInvitation) + r.Get("/auth/providers/google/callback", s.routeGoogleCallback) + r.Post("/auth/providers/apple/callback", s.routeAppleCallback) + r.Get("/control/auth/methods", s.controlAuthMethods) + r.Post("/control/auth/providers/{provider}/start", s.startControlProviderLogin) + r.Post("/control/invitations/providers/{provider}/start", s.startControlInvitationProvider) + r.Post("/control/auth/email/start", s.controlUserEmailStart) + r.Post("/control/auth/email/verify", s.controlUserEmailVerify) + r.Post("/control/auth/password", s.controlUserPasswordLogin) + r.Post("/control/auth/token/refresh", s.refreshControlUserSession) + r.Post("/control/auth/logout", s.controlUserLogout) + r.Post("/control/invitations/accept", s.acceptOrganizationInvitation) r.Group(func(r chi.Router) { - r.Use(s.requireOperator) - r.Get("/control/auth/sessions", s.listOperatorSessions) - r.Get("/control/auth/me", s.getOperatorAccount) - r.Patch("/control/auth/me", s.updateOperatorAccount) - r.Put("/control/auth/password", s.changeOperatorPassword) - r.Delete("/control/auth/sessions/{session_id}", s.revokeOperatorSession) - r.Post("/control/auth/logout-all", s.logoutAllOperatorSessions) + r.Use(s.requireControlUser) + r.Get("/control/auth/sessions", s.listControlUserSessions) + r.Get("/control/auth/me", s.getControlUserAccount) + r.Patch("/control/auth/me", s.updateControlUserAccount) + r.Put("/control/auth/password", s.changeControlUserPassword) + r.Post("/control/auth/providers/{provider}/link", s.startControlProviderLink) + r.Delete("/control/auth/identities/{identity_id}", s.unlinkControlUserIdentity) + r.Delete("/control/auth/sessions/{session_id}", s.revokeControlUserSession) + r.Post("/control/auth/logout-all", s.logoutAllControlUserSessions) r.Get("/control/organizations", s.listOrganizations) r.Get("/control/installation/management-api", s.getManagementAPIStatus) r.Patch("/control/installation/management-api", s.updateManagementAPIStatus) @@ -77,10 +86,15 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Post("/control/installation/management-clients", s.createManagementClient) r.Post("/control/installation/management-clients/{management_client_id}/rotate-secret", s.rotateManagementClientSecret) r.Delete("/control/installation/management-clients/{management_client_id}", s.disableManagementClient) - r.Get("/control/installation/operators", s.listInstallationOperators) - r.Post("/control/installation/operators", s.createInstallationOperator) - r.Patch("/control/installation/operators/{operator_id}", s.updateInstallationOperator) - r.Delete("/control/installation/operators/{operator_id}", s.deleteInstallationOperator) + r.Get("/control/installation/users", s.listInstallationControlUsers) + r.Patch("/control/installation/users/{control_user_id}", s.updateInstallationControlUser) + r.Delete("/control/installation/users/{control_user_id}", s.deleteInstallationControlUser) + r.Get("/control/installation/invitations", s.listInstallationControlUserInvitations) + r.Post("/control/installation/invitations", s.createInstallationControlUserInvitation) + r.Post("/control/installation/invitations/{invitation_id}/resend", s.resendInstallationControlUserInvitation) + r.Delete("/control/installation/invitations/{invitation_id}", s.revokeInstallationControlUserInvitation) + r.Get("/control/installation/auth-policy", s.getControlAuthPolicy) + r.Patch("/control/installation/auth-policy", s.updateControlAuthPolicy) r.Post("/control/installation/notification-providers", s.createInstallationNotificationProvider) r.Get("/control/installation/notification-providers", s.listInstallationNotificationProviders) r.Get("/control/installation/notification-providers/{provider_id}", s.getInstallationNotificationProvider) @@ -182,6 +196,7 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Delete("/control/applications/{application_id}/domains/{domain_id}", s.deleteApplicationDomain) r.Post("/control/applications/{application_id}/clients", s.createClient) r.Get("/control/applications/{application_id}/clients", s.listClients) + r.Get("/control/applications/{application_id}/clients/{client_id}", s.getClient) r.Patch("/control/applications/{application_id}/clients/{client_id}", s.updateClient) r.Post("/control/applications/{application_id}/clients/{client_id}/rotate-secret", s.rotateClientSecret) r.Delete("/control/applications/{application_id}/clients/{client_id}", s.disableClient) @@ -204,13 +219,20 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Post("/control/applications/{application_id}/role-assignments", s.assignRole) r.Get("/control/applications/{application_id}/role-assignments", s.listRoleAssignments) r.Delete("/control/applications/{application_id}/role-assignments/{assignment_id}", s.deleteRoleAssignment) + r.With(s.idempotent).Post("/control/applications/{application_id}/permission-grants", s.createPermissionGrant) + r.Get("/control/applications/{application_id}/permission-grants", s.listPermissionGrants) + r.Get("/control/applications/{application_id}/permission-grants/effective", s.effectivePermissionAccess) + r.Get("/control/applications/{application_id}/permission-grants/{grant_id}", s.getPermissionGrant) + r.Delete("/control/applications/{application_id}/permission-grants/{grant_id}", s.revokePermissionGrant) r.Post("/control/applications/{application_id}/delegations", s.createDelegation) r.Get("/control/applications/{application_id}/delegations", s.listDelegations) r.Get("/control/applications/{application_id}/delegations/{delegation_id}", s.getDelegation) r.Post("/control/applications/{application_id}/delegations/{delegation_id}/revoke", s.revokeDelegation) - r.Post("/control/applications/{application_id}/workspace-invitations", s.createWorkspaceInvitation) - r.Get("/control/applications/{application_id}/workspace-invitations", s.listWorkspaceInvitations) - r.Delete("/control/applications/{application_id}/workspace-invitations/{invitation_id}", s.revokeWorkspaceInvitation) + r.Post("/control/applications/{application_id}/invitations", s.createControlInvitation) + r.Get("/control/applications/{application_id}/invitations", s.listInvitations) + r.Post("/control/applications/{application_id}/invitations/{invitation_id}/resend", s.resendInvitation) + r.Get("/control/applications/{application_id}/invitations/{invitation_id}", s.getInvitation) + r.Delete("/control/applications/{application_id}/invitations/{invitation_id}", s.revokeInvitation) r.Post("/control/applications/{application_id}/users", s.adminCreateUser) r.Get("/control/applications/{application_id}/users", s.adminListUsers) r.Get("/control/applications/{application_id}/users/{user_id}", s.adminGetUser) @@ -237,6 +259,7 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Post("/control/applications/{application_id}/entitlements", s.createEntitlement) r.Get("/control/applications/{application_id}/entitlements", s.listEntitlements) r.Get("/control/applications/{application_id}/entitlements/{entitlement_id}", s.getEntitlement) + r.Post("/control/applications/{application_id}/entitlements/{entitlement_id}/adjust", s.adjustEntitlement) r.Post("/control/applications/{application_id}/entitlements/{entitlement_id}/revoke", s.revokeEntitlement) r.Post("/control/applications/{application_id}/entitlements/{entitlement_id}/restore", s.restoreEntitlement) r.Post("/control/applications/{application_id}/local-entitlement-requests/{request_id}/approve", s.approveLocalRequest) @@ -322,7 +345,6 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Post("/control/applications/{application_id}/notification-templates/{template_id}/preview", s.previewNotificationTemplate) r.Post("/control/applications/{application_id}/notification-templates/{template_id}/publish", s.publishNotificationTemplate) r.Post("/control/applications/{application_id}/notification-templates/{template_id}/archive", s.archiveNotificationTemplate) - r.With(s.idempotent).Post("/control/applications/{application_id}/notifications", s.queueNotification) r.Get("/control/applications/{application_id}/notifications", s.listNotifications) r.Get("/control/applications/{application_id}/notifications/statistics", s.notificationStatistics) r.Get("/control/applications/{application_id}/notifications/{notification_id}", s.getNotification) @@ -341,16 +363,34 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Post("/applications/{application_id}/auth/password/reset/verify", s.passwordResetVerify) r.Get("/applications/{application_id}/auth/providers", s.listAuthProviders) r.Post("/applications/{application_id}/auth/providers/google/start", s.startGoogleAuth) - r.Get("/applications/{application_id}/auth/providers/google/callback", s.googleCallback) r.Post("/applications/{application_id}/auth/providers/google/exchange", s.exchangeGoogleAuth) r.Post("/applications/{application_id}/auth/providers/apple/start", s.startAppleAuth) - r.Post("/applications/{application_id}/auth/providers/apple/callback", s.appleCallback) r.Post("/applications/{application_id}/auth/providers/apple/exchange", s.exchangeAppleAuth) r.Post("/applications/{application_id}/auth/mfa/verify", s.verifyMFA) r.Post("/applications/{application_id}/auth/mfa/webauthn/options", s.beginWebAuthnAuthentication) r.Post("/applications/{application_id}/auth/mfa/webauthn/verify", s.finishWebAuthnAuthentication) + r.Post("/applications/{application_id}/auth/invitations/exchange", s.exchangeInvitation) + r.Post("/applications/{application_id}/auth/invitations/token", s.redeemInvitationAuthorizationCode) r.Post("/applications/{application_id}/delegations/{delegation_id}/exchange", s.exchangeDelegation) r.With(s.requireApplicationActor, s.idempotent).Post("/applications/{application_id}/events", s.publishCustomEvent) + r.With(s.requireApplicationActor, s.idempotent).Post("/applications/{application_id}/notifications", s.queueMachineNotification) + r.With(s.requireApplicationActor).Post("/applications/{application_id}/invitations", s.createApplicationInvitation) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/invitations", s.listInvitations) + r.With(s.requireApplicationActor).Post("/applications/{application_id}/invitations/{invitation_id}/resend", s.resendInvitation) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/invitations/{invitation_id}", s.getInvitation) + r.With(s.requireApplicationActor).Delete("/applications/{application_id}/invitations/{invitation_id}", s.revokeInvitation) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/users", s.serviceListUsers) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/users/{user_id}", s.serviceGetUser) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/workspaces", s.serviceListWorkspaces) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/service/workspaces/{workspace_id}", s.serviceGetWorkspace) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/service/workspaces/{workspace_id}/access", s.serviceWorkspaceAccess) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements", s.serviceSubjectEntitlements) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing", s.serviceSubjectBilling) + r.With(s.requireApplicationActor, s.idempotent).Post("/applications/{application_id}/permission-grants", s.createPermissionGrant) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/permission-grants", s.listPermissionGrants) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/permission-grants/effective", s.effectivePermissionAccess) + r.With(s.requireApplicationActor).Get("/applications/{application_id}/permission-grants/{grant_id}", s.getPermissionGrant) + r.With(s.requireApplicationActor).Delete("/applications/{application_id}/permission-grants/{grant_id}", s.revokePermissionGrant) r.With(s.requireApplicationActor).Get("/applications/{application_id}/storage/objects", s.listApplicationStorageObjects) r.With(s.requireApplicationActor, s.idempotent).Post("/applications/{application_id}/storage/uploads", s.createApplicationStorageUpload) r.With(s.requireApplicationActor).Post("/applications/{application_id}/storage/uploads/{object_id}/complete", s.completeApplicationStorageUpload) @@ -424,8 +464,15 @@ func New(app *platform.App, adminAssets string) http.Handler { r.Post("/applications/{application_id}/workspaces/{workspace_id}/addresses/{address_id}/activate", s.activateAddress) r.Delete("/applications/{application_id}/workspaces/{workspace_id}/addresses/{address_id}", s.deleteAddress) r.Post("/applications/{application_id}/workspaces/{workspace_id}/invitations", s.createWorkspaceInvitation) - r.Get("/applications/{application_id}/me/workspace-invitations", s.listMyWorkspaceInvitations) - r.Post("/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept", s.acceptWorkspaceInvitation) + r.Get("/applications/{application_id}/workspaces/{workspace_id}/invitations", s.listInvitations) + r.Post("/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend", s.resendInvitation) + r.Delete("/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}", s.revokeInvitation) + r.Get("/applications/{application_id}/workspaces/{workspace_id}/access", s.listWorkspaceAccess) + r.With(s.idempotent).Post("/applications/{application_id}/workspaces/{workspace_id}/permission-grants", s.createPermissionGrant) + r.Get("/applications/{application_id}/workspaces/{workspace_id}/permission-grants", s.listPermissionGrants) + r.Get("/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}", s.getPermissionGrant) + r.Delete("/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}", s.revokePermissionGrant) + r.Get("/applications/{application_id}/me/workspace-invitations", s.listMyInvitations) r.Post("/applications/{application_id}/me/permissions/check", s.checkPermissions) r.Get("/applications/{application_id}/me/oauth-consents", s.listMyOAuthConsents) r.Delete("/applications/{application_id}/me/oauth-consents/{client_id}", s.revokeMyOAuthConsent) @@ -506,55 +553,62 @@ func (s *Server) accessLog(next http.Handler) http.Handler { func (s *Server) securityHeaders(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-Content-Type-Options", "nosniff") + w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("Referrer-Policy", "no-referrer") w.Header().Set("Permissions-Policy", "camera=(), microphone=(), geolocation=()") w.Header().Set("Content-Security-Policy", "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'") + if strings.HasPrefix(s.app.PublicURL, "https://") { + w.Header().Set("Strict-Transport-Security", "max-age=31536000") + } + if strings.HasPrefix(r.URL.Path, "/v1/control/") || strings.HasPrefix(r.URL.Path, "/v1/setup/") { + w.Header().Set("Cache-Control", "no-store") + } next.ServeHTTP(w, r) }) } -func (s *Server) requireOperator(next http.Handler) http.Handler { - return s.operatorMiddleware(false, next) +func (s *Server) requireControlUser(next http.Handler) http.Handler { + return s.controlUserMiddleware(false, next) } func (s *Server) requireSetup(next http.Handler) http.Handler { - return s.operatorMiddleware(true, next) + return s.controlUserMiddleware(true, next) } -func (s *Server) operatorMiddleware(setup bool, next http.Handler) http.Handler { +func (s *Server) controlUserMiddleware(setup bool, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { credential := "" fromCookie := false authorization := strings.TrimSpace(r.Header.Get("Authorization")) if strings.HasPrefix(strings.ToLower(authorization), "bearer ") { credential = strings.TrimSpace(authorization[7:]) - } else if cookie, cookieErr := r.Cookie("p93_operator_access"); cookieErr == nil { + } else if cookie, cookieErr := r.Cookie("p93_control_access"); cookieErr == nil { credential, fromCookie = cookie.Value, true } if credential == "" { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "operator_access_required", "An operator access JWT is required.") + kernel.WriteProblem(w, r, http.StatusUnauthorized, "control_user_access_required", "A Platform user access JWT is required.") return } claims, err := identity.Verify(credential, func(kid string) (*rsa.PublicKey, error) { return s.app.ResolvePublicKey(r.Context(), kid) }, s.app.Issuer(), s.app.ControlAudience(), s.app.Now()) - if err != nil || claims.ActorType != "operator" || setup && claims.TokenKind != "setup" || !setup && claims.TokenKind != "operator" { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_operator_session", "The operator session is invalid or expired.") + if err != nil || claims.ActorType != "control_user" || setup && claims.TokenKind != "setup" || !setup && claims.TokenKind != "control" { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_control_user_session", "The Platform user session is invalid or expired.") return } var live bool - err = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM operator_sessions s JOIN operators o ON o.id=s.operator_id -WHERE s.id=$1 AND s.operator_id=$2 AND s.kind=$3 AND s.revoked_at IS NULL AND s.expires_at>now() AND o.status='active')`, + err = s.app.DB.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM control_user_sessions s JOIN control_users o ON o.id=s.control_user_id +WHERE s.id=$1 AND s.control_user_id=$2 AND s.kind=$3 AND s.revoked_at IS NULL AND s.expires_at>now() AND o.status='active')`, claims.SessionID, claims.Subject, claims.TokenKind).Scan(&live) if err != nil || !live { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_operator_session", "The operator session is invalid or revoked.") + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_control_user_session", "The Platform user session is invalid or revoked.") return } - actor := kernel.Actor{Type: "operator", ID: claims.Subject, SessionID: claims.SessionID, Permissions: strings.Fields(claims.Scope)} - _, _ = s.app.DB.Exec(r.Context(), `UPDATE operator_sessions SET last_used_at=now(),ip_address=$1,user_agent=$2 + actor := kernel.Actor{Type: "control_user", ID: claims.Subject, SessionID: claims.SessionID, Permissions: strings.Fields(claims.Scope)} + _, _ = s.app.DB.Exec(r.Context(), `UPDATE control_user_sessions SET last_used_at=now(),ip_address=$1,user_agent=$2 WHERE id=$3 AND last_used_atnow() FOR UPDATE`, request.ChallengeID).Scan(&normalized, &codeDigest, &linkDigest, &attempts) + err = tx.QueryRow(r.Context(), `SELECT normalized_email,code_digest,link_digest,attempts FROM control_user_login_challenges + WHERE id=$1 AND consumed_at IS NULL AND expires_at>now() FOR UPDATE`, request.ChallengeID).Scan(&normalized, &codeDigest, &linkDigest, &attempts) + policy, policyErr := s.loadControlAuthPolicy(r.Context()) + if policyErr != nil || request.Code != "" && !policy.EmailCodeEnabled || request.LinkToken != "" && !policy.MagicLinkEnabled { + kernel.WriteProblem(w, r, http.StatusServiceUnavailable, "control_email_login_unavailable", "The selected Platform email sign-in method is unavailable.") + return + } valid := err == nil && attempts < 8 && ((request.Code != "" && equalBytes(codeDigest, s.app.Vault.Digest(strings.ToUpper(request.Code)))) || (request.LinkToken != "" && equalBytes(linkDigest, s.app.Vault.Digest(request.LinkToken)))) if !valid { if err == nil { - _, _ = tx.Exec(r.Context(), "UPDATE operator_login_challenges SET attempts=attempts+1 WHERE id=$1", request.ChallengeID) + _, _ = tx.Exec(r.Context(), "UPDATE control_user_login_challenges SET attempts=attempts+1 WHERE id=$1", request.ChallengeID) _ = tx.Commit(r.Context()) } - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_operator_challenge", "The operator challenge is invalid or expired.") + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_control_user_challenge", "The Platform user challenge is invalid or expired.") return } - var operatorID string - if tx.QueryRow(r.Context(), "SELECT id FROM operators WHERE normalized_email=$1 AND status='active'", normalized).Scan(&operatorID) != nil { - kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_operator_challenge", "The operator challenge is invalid or expired.") + var controlUserID string + if tx.QueryRow(r.Context(), "SELECT id FROM control_users WHERE normalized_email=$1 AND status='active'", normalized).Scan(&controlUserID) != nil { + kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_control_user_challenge", "The Platform user challenge is invalid or expired.") return } - refresh, _ := secure.RandomToken("p93_ops_refresh_", 32) + refresh, _ := secure.RandomToken("p93_control_refresh_", 32) sessionID := kernel.NewID() - _, err = tx.Exec(r.Context(), "UPDATE operator_login_challenges SET consumed_at=now() WHERE id=$1", request.ChallengeID) + _, err = tx.Exec(r.Context(), "UPDATE control_user_login_challenges SET consumed_at=now() WHERE id=$1", request.ChallengeID) if err == nil { - _, err = tx.Exec(r.Context(), `INSERT INTO operator_sessions -(id,operator_id,refresh_digest,kind,ip_address,user_agent,expires_at) VALUES ($1,$2,$3,'operator',$4,$5,$6)`, sessionID, operatorID, s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), s.app.Now().Add(12*time.Hour)) + amr := []string{"email_code"} + if request.LinkToken != "" { + amr = []string{"magic_link"} + } + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_sessions +(id,control_user_id,refresh_digest,kind,ip_address,user_agent,amr,expires_at) VALUES ($1,$2,$3,'control',$4,$5,$6,$7)`, sessionID, controlUserID, s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), amr, s.app.Now().Add(12*time.Hour)) } - access, tokenErr := s.issueOperatorAccess(r.Context(), operatorID, sessionID.String(), "operator") + access, tokenErr := s.issueControlUserAccessWithQuerier(r.Context(), tx, controlUserID, sessionID.String(), "control") if err != nil || tokenErr != nil || tx.Commit(r.Context()) != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "operator_session_failed", "The operator session could not be created.") + kernel.WriteProblem(w, r, http.StatusInternalServerError, "control_user_session_failed", "The Platform user session could not be created.") return } - s.setOperatorCookies(w, access, refresh, 12*time.Hour) + s.setControlUserCookies(w, access, refresh, 12*time.Hour) kernel.WriteJSON(w, http.StatusOK, map[string]any{"access_token": access, "refresh_token": refresh, "token_type": "Bearer", "expires_in": 300}) } func (s *Server) setupStatus(w http.ResponseWriter, r *http.Request) { - var available, operatorEmailLoginAvailable bool + var available, smtp, emailCode, magicLink, password bool err := s.app.DB.QueryRow(r.Context(), `SELECT setup_completed_at IS NULL AND bootstrap_digest IS NOT NULL, -EXISTS(SELECT 1 FROM notification_providers WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL) -FROM installations ORDER BY created_at LIMIT 1`).Scan(&available, &operatorEmailLoginAvailable) +EXISTS(SELECT 1 FROM notification_providers WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL), +control_email_code_enabled,control_magic_link_enabled,control_password_enabled +FROM installations ORDER BY created_at LIMIT 1`).Scan(&available, &smtp, &emailCode, &magicLink, &password) if err != nil { available = false - operatorEmailLoginAvailable = false + smtp = false + } + providers := []string{} + rows, queryErr := s.app.DB.Query(r.Context(), `SELECT provider FROM auth_provider_configs +WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL AND control_login_enabled ORDER BY provider`) + if queryErr == nil { + defer rows.Close() + for rows.Next() { + var provider string + if rows.Scan(&provider) == nil { + providers = append(providers, provider) + } + } } - kernel.WriteJSON(w, http.StatusOK, map[string]bool{ - "available": available, - "operator_email_login_available": operatorEmailLoginAvailable, + kernel.WriteJSON(w, http.StatusOK, map[string]any{ + "available": available, + "control_user_email_login_available": smtp && (emailCode || magicLink), + "control_auth_methods": map[string]any{"email_code": smtp && emailCode, "magic_link": smtp && magicLink, + "password": password, "providers": providers}, }) } @@ -163,7 +199,7 @@ func (s *Server) bootstrap(w http.ResponseWriter, r *http.Request) { } normalized := kernel.NormalizeEmail(request.Email) if normalized == "" || len(request.Credential) < 32 { - kernel.WriteProblem(w, r, http.StatusBadRequest, "invalid_bootstrap_request", "A valid credential and operator email are required.") + kernel.WriteProblem(w, r, http.StatusBadRequest, "invalid_bootstrap_request", "A valid credential and Platform user email are required.") return } tx, err := s.app.DB.Begin(r.Context()) @@ -181,16 +217,16 @@ FROM installations ORDER BY created_at LIMIT 1 FOR UPDATE`).Scan(&digest, &compl kernel.WriteProblem(w, r, http.StatusUnauthorized, "invalid_bootstrap_credential", "The bootstrap credential is invalid or unavailable.") return } - var operatorID string - err = tx.QueryRow(r.Context(), `INSERT INTO operators (id,email,normalized_email,display_name) + var controlUserID string + err = tx.QueryRow(r.Context(), `INSERT INTO control_users (id,email,normalized_email,display_name) VALUES ($1,$2,$3,$4) ON CONFLICT (normalized_email) DO UPDATE SET display_name=EXCLUDED.display_name -RETURNING id`, kernel.NewID(), request.Email, normalized, request.DisplayName).Scan(&operatorID) +RETURNING id`, kernel.NewID(), request.Email, normalized, request.DisplayName).Scan(&controlUserID) if err != nil { - kernel.WriteProblem(w, r, http.StatusConflict, "operator_creation_failed", "The initial operator could not be created.") + kernel.WriteProblem(w, r, http.StatusConflict, "control_user_creation_failed", "The initial Platform user could not be created.") return } - _, err = tx.Exec(r.Context(), `INSERT INTO installation_operator_roles(operator_id,role) VALUES($1,'owner') -ON CONFLICT (operator_id) DO UPDATE SET role='owner',updated_at=now()`, operatorID) + _, err = tx.Exec(r.Context(), `INSERT INTO installation_control_user_roles(control_user_id,role) VALUES($1,'owner') +ON CONFLICT (control_user_id) DO UPDATE SET role='owner',updated_at=now()`, controlUserID) if err == nil { err = s.app.EnsureSigningKey(r.Context(), tx) } @@ -198,29 +234,53 @@ ON CONFLICT (operator_id) DO UPDATE SET role='owner',updated_at=now()`, operator kernel.WriteProblem(w, r, http.StatusInternalServerError, "installation_security_setup_failed", "The installation owner or signing key could not be created.") return } - refresh, err := secure.RandomToken("p93_ops_refresh_", 32) + refresh, err := secure.RandomToken("p93_control_refresh_", 32) if err != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "credential_generation_failed", "The setup session could not be created.") return } sessionID := kernel.NewID() - _, err = tx.Exec(r.Context(), `INSERT INTO operator_sessions -(id,operator_id,refresh_digest,kind,ip_address,user_agent,expires_at) VALUES ($1,$2,$3,'setup',$4,$5,$6)`, - sessionID, operatorID, s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), s.app.Now().Add(30*time.Minute)) - access, tokenErr := s.issueOperatorAccessWithQuerier(r.Context(), tx, operatorID, sessionID.String(), "setup") + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_sessions +(id,control_user_id,refresh_digest,kind,ip_address,user_agent,amr,expires_at) VALUES ($1,$2,$3,'setup',$4,$5,$6,$7)`, + sessionID, controlUserID, s.app.Vault.Digest(refresh), requestIPAddress(r), truncate(r.UserAgent(), 500), []string{"bootstrap"}, s.app.Now().Add(30*time.Minute)) + access, tokenErr := s.issueControlUserAccessWithQuerier(r.Context(), tx, controlUserID, sessionID.String(), "setup") if err != nil || tokenErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "setup_session_failed", "The setup session could not be committed.") return } - s.setOperatorCookies(w, access, refresh, 30*time.Minute) - kernel.WriteJSON(w, http.StatusCreated, map[string]any{"operator_id": operatorID, "access_token": access, "refresh_token": refresh, "token_type": "Bearer", "expires_in": 300}) + s.setControlUserCookies(w, access, refresh, 30*time.Minute) + kernel.WriteJSON(w, http.StatusCreated, map[string]any{"control_user_id": controlUserID, "access_token": access, "refresh_token": refresh, "token_type": "Bearer", "expires_in": 300}) } func (s *Server) completeSetup(w http.ResponseWriter, r *http.Request) { current := actor(r) - operatorRefresh, err := secure.RandomToken("p93_ops_refresh_", 32) + var request struct { + Password string `json:"password,omitempty"` + } + if r.Body != nil && r.ContentLength != 0 && !kernel.DecodeJSON(w, r, &request) { + return + } + var smtp, durableExternal bool + _ = s.app.DB.QueryRow(r.Context(), `SELECT +EXISTS(SELECT 1 FROM notification_providers WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL), +EXISTS(SELECT 1 FROM control_user_identities i JOIN auth_provider_configs p ON p.id=i.auth_provider_config_id +WHERE i.control_user_id=$1 AND p.disabled_at IS NULL AND p.control_login_enabled)`, current.ID).Scan(&smtp, &durableExternal) + var passwordHash string + if !smtp && !durableExternal { + if strings.TrimSpace(request.Password) == "" { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "durable_control_login_required", "Configure installation email delivery or set a Platform owner password before completing setup.") + return + } + var hashErr error + passwordHash, hashErr = identity.HashPassword(request.Password) + if hashErr != nil { + kernel.WriteProblem(w, r, http.StatusUnprocessableEntity, "invalid_password", hashErr.Error()) + return + } + } + controlUserRefresh, err := secure.RandomToken("p93_control_refresh_", 32) if err != nil { - kernel.WriteProblem(w, r, http.StatusInternalServerError, "credential_generation_failed", "The operator session could not be created.") + kernel.WriteProblem(w, r, http.StatusInternalServerError, "credential_generation_failed", "The Platform user session could not be created.") return } tx, err := s.app.DB.Begin(r.Context()) @@ -235,69 +295,74 @@ WHERE setup_completed_at IS NULL`) kernel.WriteProblem(w, r, http.StatusConflict, "setup_already_complete", "Installation setup is already complete.") return } - _, err = tx.Exec(r.Context(), "UPDATE operator_sessions SET revoked_at=now() WHERE id=$1", current.SessionID) + if err == nil && passwordHash != "" { + _, err = tx.Exec(r.Context(), `UPDATE control_users SET password_hash=$1,updated_at=now() WHERE id=$2`, passwordHash, current.ID) + } + if err == nil { + _, err = tx.Exec(r.Context(), "UPDATE control_user_sessions SET revoked_at=now() WHERE id=$1", current.SessionID) + } newSessionID := kernel.NewID() if err == nil { - _, err = tx.Exec(r.Context(), `INSERT INTO operator_sessions -(id,operator_id,refresh_digest,kind,ip_address,user_agent,expires_at) VALUES ($1,$2,$3,'operator',$4,$5,$6)`, - newSessionID, current.ID, s.app.Vault.Digest(operatorRefresh), requestIPAddress(r), truncate(r.UserAgent(), 500), s.app.Now().Add(12*time.Hour)) + _, err = tx.Exec(r.Context(), `INSERT INTO control_user_sessions +(id,control_user_id,refresh_digest,kind,ip_address,user_agent,amr,expires_at) VALUES ($1,$2,$3,'control',$4,$5,$6,$7)`, + newSessionID, current.ID, s.app.Vault.Digest(controlUserRefresh), requestIPAddress(r), truncate(r.UserAgent(), 500), []string{"bootstrap"}, s.app.Now().Add(12*time.Hour)) } - access, tokenErr := s.issueOperatorAccess(r.Context(), current.ID, newSessionID.String(), "operator") + access, tokenErr := s.issueControlUserAccessWithQuerier(r.Context(), tx, current.ID, newSessionID.String(), "control") if err != nil || tokenErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "setup_completion_failed", "Setup could not be completed.") return } - s.setOperatorCookies(w, access, operatorRefresh, 12*time.Hour) - kernel.WriteJSON(w, http.StatusOK, map[string]any{"completed": true, "access_token": access, "refresh_token": operatorRefresh, "token_type": "Bearer", "expires_in": 300}) + s.setControlUserCookies(w, access, controlUserRefresh, 12*time.Hour) + kernel.WriteJSON(w, http.StatusOK, map[string]any{"completed": true, "access_token": access, "refresh_token": controlUserRefresh, "token_type": "Bearer", "expires_in": 300}) } -func (s *Server) operatorLogout(w http.ResponseWriter, r *http.Request) { - if cookie, err := r.Cookie("p93_operator_refresh"); err == nil { - _, _ = s.app.DB.Exec(r.Context(), "UPDATE operator_sessions SET revoked_at=now() WHERE refresh_digest=$1", s.app.Vault.Digest(cookie.Value)) +func (s *Server) controlUserLogout(w http.ResponseWriter, r *http.Request) { + if cookie, err := r.Cookie("p93_control_refresh"); err == nil { + _, _ = s.app.DB.Exec(r.Context(), "UPDATE control_user_sessions SET revoked_at=now() WHERE refresh_digest=$1", s.app.Vault.Digest(cookie.Value)) } - s.clearOperatorCookies(w) + s.clearControlUserCookies(w) w.WriteHeader(http.StatusNoContent) } -func operatorCookie(name, value string, ttl time.Duration, secure bool) *http.Cookie { +func controlUserCookie(name, value string, ttl time.Duration, secure bool) *http.Cookie { return &http.Cookie{Name: name, Value: value, Path: "/", HttpOnly: true, Secure: secure, SameSite: http.SameSiteStrictMode, MaxAge: int(ttl.Seconds())} } -func (s *Server) setOperatorCookies(w http.ResponseWriter, access, refresh string, refreshTTL time.Duration) { +func (s *Server) setControlUserCookies(w http.ResponseWriter, access, refresh string, refreshTTL time.Duration) { secureCookie := strings.HasPrefix(s.app.PublicURL, "https://") - http.SetCookie(w, operatorCookie("p93_operator_access", access, 5*time.Minute, secureCookie)) - http.SetCookie(w, operatorCookie("p93_operator_refresh", refresh, refreshTTL, secureCookie)) + http.SetCookie(w, controlUserCookie("p93_control_access", access, 5*time.Minute, secureCookie)) + http.SetCookie(w, controlUserCookie("p93_control_refresh", refresh, refreshTTL, secureCookie)) } -func (s *Server) clearOperatorCookies(w http.ResponseWriter) { +func (s *Server) clearControlUserCookies(w http.ResponseWriter) { secureCookie := strings.HasPrefix(s.app.PublicURL, "https://") - http.SetCookie(w, operatorCookie("p93_operator_access", "", -time.Hour, secureCookie)) - http.SetCookie(w, operatorCookie("p93_operator_refresh", "", -time.Hour, secureCookie)) + http.SetCookie(w, controlUserCookie("p93_control_access", "", -time.Hour, secureCookie)) + http.SetCookie(w, controlUserCookie("p93_control_refresh", "", -time.Hour, secureCookie)) } -func (s *Server) issueOperatorAccess(ctx context.Context, operatorID, sessionID, kind string) (string, error) { - return s.issueOperatorAccessWithQuerier(ctx, s.app.DB, operatorID, sessionID, kind) +func (s *Server) issueControlUserAccess(ctx context.Context, controlUserID, sessionID, kind string) (string, error) { + return s.issueControlUserAccessWithQuerier(ctx, s.app.DB, controlUserID, sessionID, kind) } -type operatorTokenQuerier interface { +type controlUserTokenQuerier interface { Query(context.Context, string, ...any) (pgx.Rows, error) QueryRow(context.Context, string, ...any) pgx.Row } -func (s *Server) issueOperatorAccessWithQuerier(ctx context.Context, q operatorTokenQuerier, operatorID, sessionID, kind string) (string, error) { +func (s *Server) issueControlUserAccessWithQuerier(ctx context.Context, q controlUserTokenQuerier, controlUserID, sessionID, kind string) (string, error) { scopes := []string{"/control/setup/*"} - if kind == "operator" { + if kind == "control" { scopes = scopes[:0] var role string - if q.QueryRow(ctx, "SELECT role FROM installation_operator_roles WHERE operator_id=$1", operatorID).Scan(&role) == nil { + if q.QueryRow(ctx, "SELECT role FROM installation_control_user_roles WHERE control_user_id=$1", controlUserID).Scan(&role) == nil { if role == "owner" || role == "admin" { scopes = append(scopes, "/control/*") } else { scopes = append(scopes, "/control/read") } } - rows, err := q.Query(ctx, "SELECT organization_id::text,role FROM organization_memberships WHERE operator_id=$1 ORDER BY organization_id", operatorID) + rows, err := q.Query(ctx, "SELECT organization_id::text,role FROM organization_memberships WHERE control_user_id=$1 ORDER BY organization_id", controlUserID) if err == nil { defer rows.Close() for rows.Next() { @@ -317,8 +382,10 @@ func (s *Server) issueOperatorAccessWithQuerier(ctx context.Context, q operatorT return "", err } now := s.app.Now() - return identity.Sign(privateKey, kid, identity.Claims{Issuer: s.app.Issuer(), Subject: operatorID, + amr := []string{} + _ = q.QueryRow(ctx, "SELECT amr FROM control_user_sessions WHERE id=$1 AND control_user_id=$2", sessionID, controlUserID).Scan(&amr) + return identity.Sign(privateKey, kid, identity.Claims{Issuer: s.app.Issuer(), Subject: controlUserID, Audience: []string{s.app.ControlAudience()}, ExpiresAt: now.Add(5 * time.Minute).Unix(), IssuedAt: now.Unix(), NotBefore: now.Add(-5 * time.Second).Unix(), JWTID: kernel.NewID().String(), SessionID: sessionID, - TokenKind: kind, ActorType: "operator", Scope: strings.Join(scopes, " "), AMR: []string{"email"}}) + TokenKind: kind, ActorType: "control_user", Scope: strings.Join(scopes, " "), AMR: amr}) } diff --git a/internal/httpapi/storage_objects.go b/internal/httpapi/storage_objects.go index 06227d3..d52613b 100644 --- a/internal/httpapi/storage_objects.go +++ b/internal/httpapi/storage_objects.go @@ -675,7 +675,7 @@ func (s *Server) authorizeApplicationStorageControl(w http.ResponseWriter, r *ht kernel.WriteProblem(w, r, http.StatusForbidden, "organization_permission_required", "An organization owner or administrator is required to manage application storage.") return false } - if s.operatorBelongsToOrganization(r, organizationID) { + if s.controlUserBelongsToOrganization(r, organizationID) { return true } kernel.WriteProblem(w, r, http.StatusNotFound, "application_not_found", "The application was not found.") diff --git a/internal/httpapi/system_notification_templates_test.go b/internal/httpapi/system_notification_templates_test.go index 1492140..cf2a543 100644 --- a/internal/httpapi/system_notification_templates_test.go +++ b/internal/httpapi/system_notification_templates_test.go @@ -59,7 +59,7 @@ VALUES($1,NULL,$2,'en','transactional',1,'English','English {{message_locale}}', } queueRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{ "template_key": localizedKey, "user_id": localizedUserID.String(), - }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "operator"}) + }, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "control_user"}) queueResponse := httptest.NewRecorder() server.queueNotification(queueResponse, queueRequest) if queueResponse.Code != http.StatusAccepted || !strings.Contains(queueResponse.Body.String(), `"resolved_locale":"de"`) || !strings.Contains(queueResponse.Body.String(), `"fallback_used":true`) { @@ -70,7 +70,7 @@ VALUES($1,NULL,$2,'en','transactional',1,'English','English {{message_locale}}', t.Fatalf("notification stored the wrong resolved locale: %q %v", storedLocale, err) } - listRequest := requestWithRoute(t, http.MethodGet, "/", nil, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "operator"}) + listRequest := requestWithRoute(t, http.MethodGet, "/", nil, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "control_user"}) listResponse := httptest.NewRecorder() server.listNotificationTemplates(listResponse, listRequest) if listResponse.Code != http.StatusOK || !strings.Contains(listResponse.Body.String(), `"key":"platform93.application_sign_in"`) || !strings.Contains(listResponse.Body.String(), `"inherited":true`) { @@ -84,7 +84,7 @@ WHERE application_id IS NULL AND key=$1 AND status='published'`, applicationSign } updateRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{ "subject_template": "Custom sign in to {{application_name}}", - }, map[string]string{"application_id": applicationID.String(), "template_id": installationTemplateID}, kernel.Actor{Type: "operator"}) + }, map[string]string{"application_id": applicationID.String(), "template_id": installationTemplateID}, kernel.Actor{Type: "control_user"}) updateResponse := httptest.NewRecorder() server.updateNotificationTemplate(updateResponse, updateRequest) if updateResponse.Code != http.StatusCreated { @@ -96,7 +96,7 @@ WHERE application_id IS NULL AND key=$1 AND status='published'`, applicationSign if json.Unmarshal(updateResponse.Body.Bytes(), &created) != nil || created.ID == "" { t.Fatal("template override response did not contain an id") } - publishRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{}, map[string]string{"application_id": applicationID.String(), "template_id": created.ID}, kernel.Actor{Type: "operator"}) + publishRequest := requestWithRoute(t, http.MethodPost, "/", map[string]any{}, map[string]string{"application_id": applicationID.String(), "template_id": created.ID}, kernel.Actor{Type: "control_user"}) publishResponse := httptest.NewRecorder() server.publishNotificationTemplate(publishResponse, publishRequest) if publishResponse.Code != http.StatusNoContent { @@ -116,7 +116,7 @@ VALUES($1,$2,'web','Web','public',ARRAY['https://app.example/auth/callback'],ARR } configRequest := requestWithRoute(t, http.MethodPatch, "/", map[string]any{"flows": map[string]any{ "oauth_client_id": "web", "sign_in_redirect_uri": "https://app.example/auth/callback", "invitation_redirect_uri": "https://app.example/invitations/accept", - }}, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "operator"}) + }}, map[string]string{"application_id": applicationID.String()}, kernel.Actor{Type: "control_user"}) configResponse := httptest.NewRecorder() server.updateAuthConfig(configResponse, configRequest) if configResponse.Code != http.StatusNoContent { diff --git a/internal/httpapi/webhooks.go b/internal/httpapi/webhooks.go index 9bf19b8..0202379 100644 --- a/internal/httpapi/webhooks.go +++ b/internal/httpapi/webhooks.go @@ -173,7 +173,7 @@ func (s *Server) testWebhook(w http.ResponseWriter, r *http.Request) { } defer rollback(tx, r.Context()) eventID, deliveryID := kernel.NewID(), kernel.NewID() - actorJSON, _ := json.Marshal(map[string]any{"type": "operator", "id": actor(r).ID}) + actorJSON, _ := json.Marshal(map[string]any{"type": "control_user", "id": actor(r).ID}) dataJSON, _ := json.Marshal(map[string]any{"webhook_endpoint_id": webhookID, "test": true}) result, err := tx.Exec(r.Context(), `INSERT INTO domain_events(id,application_id,event_type,schema_version,contract_source,subject,actor,data) SELECT $1,$2,d.name,d.schema_version,'platform93',$3::text,$4,$5 FROM webhook_endpoints w diff --git a/internal/httpapi/workspace_management.go b/internal/httpapi/workspace_management.go index 3d662b9..25b1ba6 100644 --- a/internal/httpapi/workspace_management.go +++ b/internal/httpapi/workspace_management.go @@ -64,7 +64,13 @@ func (s *Server) updateWorkspace(w http.ResponseWriter, r *http.Request) { } metadata = encoded } - result, err := s.app.DB.Exec(r.Context(), `UPDATE workspaces SET + tx, err := s.app.DB.Begin(r.Context()) + if err != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "database_error", "The workspace could not be updated.") + return + } + defer rollback(tx, r.Context()) + result, err := tx.Exec(r.Context(), `UPDATE workspaces SET name=CASE WHEN $1::text IS NULL THEN name ELSE $1 END, metadata=CASE WHEN $2::jsonb IS NULL THEN metadata ELSE $2 END, version=version+1,updated_at=now() WHERE id=$3 AND application_id=$4 AND version=$5 AND deleted_at IS NULL`, request.Name, metadata, chi.URLParam(r, "workspace_id"), chi.URLParam(r, "application_id"), version) @@ -72,12 +78,27 @@ version=version+1,updated_at=now() WHERE id=$3 AND application_id=$4 AND version kernel.WriteProblem(w, r, http.StatusConflict, "workspace_version_conflict", "The workspace changed concurrently.") return } + applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) + if parseErr == nil { + changedFields := []string{} + if request.Name != nil { + changedFields = append(changedFields, "name") + } + if request.Metadata != nil { + changedFields = append(changedFields, "metadata") + } + _, err = s.app.Emit(r.Context(), tx, &applicationID, "workspace.updated", "workspace/"+chi.URLParam(r, "workspace_id"), actor(r), map[string]any{"workspace_id": chi.URLParam(r, "workspace_id"), "changed_fields": changedFields, "status": "active"}) + } + if parseErr != nil || err != nil || tx.Commit(r.Context()) != nil { + kernel.WriteProblem(w, r, http.StatusInternalServerError, "workspace_update_failed", "The workspace could not be updated.") + return + } w.Header().Set("ETag", kernel.ETag(version+1)) w.WriteHeader(http.StatusNoContent) } func (s *Server) deleteWorkspace(w http.ResponseWriter, r *http.Request) { - if !s.isWorkspaceOwnerOrOperator(r) { + if !s.isWorkspaceOwnerOrControlUser(r) { kernel.WriteProblem(w, r, http.StatusForbidden, "workspace_owner_required", "The workspace owner or an organization administrator is required.") return } @@ -94,14 +115,18 @@ WHERE id=$1 AND application_id=$2 AND deleted_at IS NULL`, workspaceID, applicat kernel.WriteProblem(w, r, http.StatusNotFound, "workspace_not_found", "The active workspace was not found.") return } - if _, err = tx.Exec(r.Context(), `UPDATE workspace_invitations SET revoked_at=COALESCE(revoked_at,now()) + if _, err = tx.Exec(r.Context(), `UPDATE application_invitations SET revoked_at=COALESCE(revoked_at,now()),updated_at=now() WHERE workspace_id=$1 AND application_id=$2 AND accepted_at IS NULL`, workspaceID, applicationID); err == nil { _, err = tx.Exec(r.Context(), `DELETE FROM role_assignments WHERE workspace_id=$1 AND application_id=$2`, workspaceID, applicationID) } if err == nil { _, err = tx.Exec(r.Context(), `DELETE FROM workspace_memberships WHERE workspace_id=$1 AND application_id=$2`, workspaceID, applicationID) } - if err != nil || tx.Commit(r.Context()) != nil { + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &parsedApplicationID, "workspace.archived", "workspace/"+workspaceID, actor(r), map[string]any{"workspace_id": workspaceID, "status": "archived"}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "workspace_retirement_failed", "The workspace could not be retired atomically.") return } @@ -191,6 +216,8 @@ AND EXISTS(SELECT 1 FROM users WHERE id=$4 AND application_id=$1 AND status='act kernel.WriteProblem(w, r, http.StatusConflict, "workspace_owner_not_member", "The workspace owner cannot also be stored as a member.") return } + var existingMember bool + _ = tx.QueryRow(r.Context(), `SELECT EXISTS(SELECT 1 FROM workspace_memberships WHERE application_id=$1 AND workspace_id=$2 AND user_id=$3)`, applicationID, workspaceID, userID).Scan(&existingMember) _, err = tx.Exec(r.Context(), `INSERT INTO workspace_memberships(application_id,workspace_id,user_id) VALUES($1,$2,$3) ON CONFLICT(workspace_id,user_id) DO NOTHING`, applicationID, workspaceID, userID) if err == nil { @@ -201,7 +228,15 @@ VALUES($1,$2,$3) ON CONFLICT(workspace_id,user_id) DO NOTHING`, applicationID, w _, err = tx.Exec(r.Context(), `INSERT INTO role_assignments(id,application_id,user_id,role_id,workspace_id) VALUES($1,$2,$3,$4,$5)`, kernel.NewID(), applicationID, userID, roleID, workspaceID) } } - if err != nil || tx.Commit(r.Context()) != nil { + parsedApplicationID, parseErr := uuid.Parse(applicationID) + if err == nil && parseErr == nil { + eventType := "workspace.member_added" + if existingMember { + eventType = "workspace.member_updated" + } + _, err = s.app.Emit(r.Context(), tx, &parsedApplicationID, eventType, "workspace/"+workspaceID, actor(r), map[string]any{"workspace_id": workspaceID, "user_id": userID, "role_keys": request.RoleKeys, "status": "active"}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusInternalServerError, "workspace_membership_update_failed", "Workspace membership could not be updated atomically.") return } @@ -224,7 +259,11 @@ func (s *Server) deleteWorkspaceMember(w http.ResponseWriter, r *http.Request) { if err == nil { err = tx.QueryRow(r.Context(), `DELETE FROM workspace_memberships WHERE application_id=$1 AND workspace_id=$2 AND user_id=$3 RETURNING user_id`, chi.URLParam(r, "application_id"), chi.URLParam(r, "workspace_id"), chi.URLParam(r, "user_id")).Scan(&removed) } - if err != nil || tx.Commit(r.Context()) != nil { + applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "workspace.member_removed", "workspace/"+chi.URLParam(r, "workspace_id"), actor(r), map[string]any{"workspace_id": chi.URLParam(r, "workspace_id"), "user_id": chi.URLParam(r, "user_id"), "status": "removed"}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "workspace_member_not_found", "The workspace member was not found.") return } @@ -300,7 +339,7 @@ func (s *Server) leaveWorkspace(w http.ResponseWriter, r *http.Request) { kernel.WriteProblem(w, r, http.StatusForbidden, "user_required", "Only application users can leave a workspace.") return } - if s.isWorkspaceOwnerOrOperator(r) { + if s.isWorkspaceOwnerOrControlUser(r) { kernel.WriteProblem(w, r, http.StatusConflict, "workspace_owner_cannot_leave", "Transfer workspace ownership before leaving.") return } @@ -315,7 +354,11 @@ func (s *Server) leaveWorkspace(w http.ResponseWriter, r *http.Request) { if err == nil { err = tx.QueryRow(r.Context(), `DELETE FROM workspace_memberships WHERE application_id=$1 AND workspace_id=$2 AND user_id=$3 RETURNING user_id`, chi.URLParam(r, "application_id"), chi.URLParam(r, "workspace_id"), actor(r).ID).Scan(&removed) } - if err != nil || tx.Commit(r.Context()) != nil { + applicationID, parseErr := uuid.Parse(chi.URLParam(r, "application_id")) + if err == nil && parseErr == nil { + _, err = s.app.Emit(r.Context(), tx, &applicationID, "workspace.member_removed", "workspace/"+chi.URLParam(r, "workspace_id"), actor(r), map[string]any{"workspace_id": chi.URLParam(r, "workspace_id"), "user_id": actor(r).ID, "status": "removed"}) + } + if err != nil || parseErr != nil || tx.Commit(r.Context()) != nil { kernel.WriteProblem(w, r, http.StatusNotFound, "workspace_membership_not_found", "The user is not a member of this workspace.") return } @@ -323,7 +366,7 @@ func (s *Server) leaveWorkspace(w http.ResponseWriter, r *http.Request) { } func (s *Server) canAccessWorkspace(r *http.Request, manage bool) bool { - if actor(r).Type == "operator" { + if actor(r).Type == "control_user" { return true } applicationID, workspaceID := chi.URLParam(r, "application_id"), chi.URLParam(r, "workspace_id") @@ -346,8 +389,8 @@ FROM workspaces WHERE id=$1 AND application_id=$2 AND deleted_at IS NULL`, works return false } -func (s *Server) isWorkspaceOwnerOrOperator(r *http.Request) bool { - if actor(r).Type == "operator" { +func (s *Server) isWorkspaceOwnerOrControlUser(r *http.Request) bool { + if actor(r).Type == "control_user" { return true } var owner bool diff --git a/internal/httpapi/workspace_management_test.go b/internal/httpapi/workspace_management_test.go index 91ee2f7..ee95efc 100644 --- a/internal/httpapi/workspace_management_test.go +++ b/internal/httpapi/workspace_management_test.go @@ -49,14 +49,14 @@ func TestWorkspaceMemberRoleReplacementIsAtomic(t *testing.T) { } params := map[string]string{"application_id": applicationID.String(), "workspace_id": workspaceID.String(), "user_id": userID.String()} - replace := requestWithRoute(t, "PUT", "/", map[string]any{"role_keys": []string{"one-" + suffix, "two-" + suffix}}, params, kernel.Actor{Type: "operator"}) + replace := requestWithRoute(t, "PUT", "/", map[string]any{"role_keys": []string{"one-" + suffix, "two-" + suffix}}, params, kernel.Actor{Type: "control_user"}) response := httptest.NewRecorder() server.replaceWorkspaceMemberRoles(response, replace) if response.Code != 200 { t.Fatalf("initial role replacement failed: %d %s", response.Code, response.Body.String()) } - replace = requestWithRoute(t, "PUT", "/", map[string]any{"role_keys": []string{"two-" + suffix}}, params, kernel.Actor{Type: "operator"}) + replace = requestWithRoute(t, "PUT", "/", map[string]any{"role_keys": []string{"two-" + suffix}}, params, kernel.Actor{Type: "control_user"}) response = httptest.NewRecorder() server.replaceWorkspaceMemberRoles(response, replace) if response.Code != 200 { diff --git a/internal/identity/token.go b/internal/identity/token.go index 45d3503..3823773 100644 --- a/internal/identity/token.go +++ b/internal/identity/token.go @@ -15,28 +15,36 @@ import ( "time" "github.com/google/uuid" + platformauthz "github.com/supaapps/platform93/internal/authorization" ) +type RoleClaims struct { + Application []string `json:"application"` + Workspaces map[string][]string `json:"workspaces"` +} + type Claims struct { - Issuer string `json:"iss"` - Subject string `json:"sub"` - Audience []string `json:"aud"` - ExpiresAt int64 `json:"exp"` - IssuedAt int64 `json:"iat"` - NotBefore int64 `json:"nbf"` - JWTID string `json:"jti"` - SessionID string `json:"sid,omitempty"` - ApplicationID string `json:"application_id,omitempty"` - ClientID string `json:"client_id,omitempty"` - TokenKind string `json:"token_kind"` - ActorType string `json:"actor_type"` - Scope string `json:"scope,omitempty"` - Email string `json:"email,omitempty"` - Locale string `json:"locale,omitempty"` - EmailVerified bool `json:"email_verified,omitempty"` - IsOrgVerified bool `json:"is_org_verified,omitempty"` - AMR []string `json:"amr,omitempty"` - Actor *Actor `json:"act,omitempty"` + Issuer string `json:"iss"` + Subject string `json:"sub"` + Audience []string `json:"aud"` + ExpiresAt int64 `json:"exp"` + IssuedAt int64 `json:"iat"` + NotBefore int64 `json:"nbf"` + JWTID string `json:"jti"` + SessionID string `json:"sid,omitempty"` + ApplicationID string `json:"application_id,omitempty"` + ClientID string `json:"client_id,omitempty"` + TokenKind string `json:"token_kind"` + ActorType string `json:"actor_type"` + Scope string `json:"scope,omitempty"` + Roles RoleClaims `json:"roles"` + Email string `json:"email,omitempty"` + Locale string `json:"locale,omitempty"` + EmailVerified bool `json:"email_verified,omitempty"` + IsOrgVerified bool `json:"is_org_verified,omitempty"` + CustomClaims map[string]any `json:"custom_claims,omitempty"` + AMR []string `json:"amr,omitempty"` + Actor *Actor `json:"act,omitempty"` } type Actor struct { @@ -70,6 +78,17 @@ func PublicJWK(kid string, key *rsa.PublicKey) map[string]any { } func Sign(privatePEM []byte, kid string, claims Claims) (string, error) { + if claims.ApplicationID != "" { + if err := platformauthz.ValidateScopeClaim(claims.Scope, claims.ApplicationID); err != nil { + return "", fmt.Errorf("refuse to sign invalid token scope: %w", err) + } + if err := validateRoleClaims(claims.Roles); err != nil { + return "", fmt.Errorf("refuse to sign invalid token roles: %w", err) + } + if claims.Actor != nil && (len(claims.Roles.Application) != 0 || len(claims.Roles.Workspaces) != 0) { + return "", fmt.Errorf("refuse to sign delegated token with normal roles") + } + } block, _ := pem.Decode(privatePEM) if block == nil { return "", fmt.Errorf("invalid RSA private key") @@ -122,9 +141,52 @@ func Verify(token string, resolve func(kid string) (*rsa.PublicKey, error), issu if claims.Issuer != issuer || !contains(claims.Audience, audience) || claims.ExpiresAt <= now.Unix() || claims.NotBefore > now.Add(30*time.Second).Unix() { return Claims{}, fmt.Errorf("token claims rejected") } + if claims.ApplicationID != "" { + if err := platformauthz.ValidateScopeClaim(claims.Scope, claims.ApplicationID); err != nil { + return Claims{}, fmt.Errorf("token scope rejected: %w", err) + } + if err := validateRoleClaims(claims.Roles); err != nil { + return Claims{}, fmt.Errorf("token roles rejected: %w", err) + } + if claims.Actor != nil && (len(claims.Roles.Application) != 0 || len(claims.Roles.Workspaces) != 0) { + return Claims{}, fmt.Errorf("delegated token roles rejected") + } + } return claims, nil } +func validateRoleClaims(roles RoleClaims) error { + if roles.Application == nil || roles.Workspaces == nil { + return fmt.Errorf("structured roles claim is required") + } + seen := map[string]struct{}{} + for _, role := range roles.Application { + if err := platformauthz.ValidateRoleKey(role); err != nil { + return err + } + if _, duplicate := seen[role]; duplicate { + return fmt.Errorf("application role is duplicated") + } + seen[role] = struct{}{} + } + for workspaceID, workspaceRoles := range roles.Workspaces { + if _, err := uuid.Parse(workspaceID); err != nil || workspaceRoles == nil { + return fmt.Errorf("workspace role context is invalid") + } + workspaceSeen := map[string]struct{}{} + for _, role := range workspaceRoles { + if err := platformauthz.ValidateRoleKey(role); err != nil { + return err + } + if _, duplicate := workspaceSeen[role]; duplicate { + return fmt.Errorf("workspace role is duplicated") + } + workspaceSeen[role] = struct{}{} + } + } + return nil +} + func contains(values []string, wanted string) bool { for _, value := range values { if value == wanted { diff --git a/internal/identity/token_test.go b/internal/identity/token_test.go index a6d2bc4..3d1679e 100644 --- a/internal/identity/token_test.go +++ b/internal/identity/token_test.go @@ -14,7 +14,9 @@ func TestRS256ClaimsAreStrictlyBound(t *testing.T) { t.Fatal(err) } now := time.Unix(1_800_000_000, 0) - claims := Claims{Issuer: "https://issuer.example/oidc/env", Subject: "user", Audience: []string{"platform93-api"}, ExpiresAt: now.Add(time.Minute).Unix(), IssuedAt: now.Unix(), NotBefore: now.Add(-time.Second).Unix(), JWTID: "jti", ApplicationID: "env", TokenKind: "access"} + applicationID := "01900000-0000-7000-8000-000000000001" + audience := "platform93:application:" + applicationID + claims := Claims{Issuer: "https://issuer.example/oidc", Subject: "01900000-0000-7000-8000-000000000002", Audience: []string{audience}, ExpiresAt: now.Add(time.Minute).Unix(), IssuedAt: now.Unix(), NotBefore: now.Add(-time.Second).Unix(), JWTID: "01900000-0000-7000-8000-000000000003", ApplicationID: applicationID, TokenKind: "access", ActorType: "user", Roles: RoleClaims{Application: []string{}, Workspaces: map[string][]string{}}, Scope: "/applications/" + applicationID + "/profile/read"} token, err := Sign(pair.PrivatePEM, pair.KID, claims) if err != nil { t.Fatal(err) @@ -26,8 +28,8 @@ func TestRS256ClaimsAreStrictlyBound(t *testing.T) { t.Fatalf("unexpected kid %s", kid) } return &key.PublicKey, nil - }, claims.Issuer, "platform93-api", now) - if err != nil || verified.Subject != "user" { + }, claims.Issuer, audience, now) + if err != nil || verified.Subject != claims.Subject { t.Fatalf("valid token rejected: %v", err) } if _, err := Verify(token, func(string) (*rsa.PublicKey, error) { return &key.PublicKey, nil }, claims.Issuer, "wrong-audience", now); err == nil { diff --git a/internal/jobs/runner.go b/internal/jobs/runner.go index ec3b3e4..8660722 100644 --- a/internal/jobs/runner.go +++ b/internal/jobs/runner.go @@ -78,6 +78,7 @@ func (r *Runner) RunWorker(ctx context.Context) error { river.AddWorker(workers, &deliverySweepWorker{runner: r}) river.AddWorker(workers, &billingReconciliationWorker{runner: r}) river.AddWorker(workers, &storageSweepWorker{runner: r}) + river.AddWorker(workers, &lifecycleSweepWorker{runner: r}) client, err := river.NewClient(riverpgxv5.New(r.app.DB), &river.Config{ ID: r.instanceID, Workers: workers, @@ -92,6 +93,9 @@ func (r *Runner) RunWorker(ctx context.Context) error { river.NewPeriodicJob(river.PeriodicInterval(30*time.Second), func() (river.JobArgs, *river.InsertOpts) { return storageSweepArgs{}, nil }, &river.PeriodicJobOpts{ID: "platform93-storage-sweep", RunOnStart: true}), + river.NewPeriodicJob(river.PeriodicInterval(30*time.Second), func() (river.JobArgs, *river.InsertOpts) { + return lifecycleSweepArgs{}, nil + }, &river.PeriodicJobOpts{ID: "platform93-lifecycle-sweep", RunOnStart: true}), }, }) if err != nil { @@ -121,6 +125,19 @@ type storageSweepArgs struct{} func (storageSweepArgs) Kind() string { return "platform93_storage_sweep" } +type lifecycleSweepArgs struct{} + +func (lifecycleSweepArgs) Kind() string { return "platform93_lifecycle_sweep" } + +type lifecycleSweepWorker struct { + river.WorkerDefaults[lifecycleSweepArgs] + runner *Runner +} + +func (w *lifecycleSweepWorker) Work(ctx context.Context, _ *river.Job[lifecycleSweepArgs]) error { + return httpapi.RunLifecycleSweep(ctx, w.runner.app) +} + type storageSweepWorker struct { river.WorkerDefaults[storageSweepArgs] runner *Runner diff --git a/internal/jobs/smtp.go b/internal/jobs/smtp.go index e694293..c8725ac 100644 --- a/internal/jobs/smtp.go +++ b/internal/jobs/smtp.go @@ -153,7 +153,7 @@ func (r *Runner) notificationContent(payload map[string]any) (string, string, st parts = append(parts, "Use the application invitation flow to accept this membership. If you did not expect this invitation, ignore this message.") return "Workspace invitation", strings.Join(parts, "\r\n\r\n"), "" } - operator, _ := payload["operator"].(bool) + controlUser, _ := payload["control_user"].(bool) subject := "Your Platform93 sign-in code" parts := []string{"A sign-in was requested for your account."} if code, ok := payload["code"].(string); ok && code != "" { @@ -161,8 +161,8 @@ func (r *Runner) notificationContent(payload map[string]any) (string, string, st } if token, ok := payload["link_token"].(string); ok && token != "" { if challenge, ok := payload["challenge_id"].(string); ok { - base := r.app.PublicURL + "/?operator_challenge=true" - if !operator { + base := r.app.PublicURL + "/?control_user_challenge=true" + if !controlUser { if redirect, ok := payload["redirect_uri"].(string); ok && redirect != "" { base = redirect } diff --git a/migrations/00001_foundation.sql b/migrations/00001_foundation.sql index 8576337..f724c58 100644 --- a/migrations/00001_foundation.sql +++ b/migrations/00001_foundation.sql @@ -1,492 +1,195 @@ -- +goose Up -CREATE EXTENSION IF NOT EXISTS pgcrypto; - -CREATE TABLE installations ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - setup_completed_at timestamptz, - bootstrap_digest bytea, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); -CREATE UNIQUE INDEX installations_singleton ON installations ((true)); - -CREATE TABLE signing_keys ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - kid text NOT NULL UNIQUE, - public_jwk jsonb NOT NULL, - private_key_ciphertext text NOT NULL, - status text NOT NULL CHECK (status IN ('prepared','active','retiring','retired')), - activates_at timestamptz, - retires_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE operators ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - email text NOT NULL, - normalized_email text NOT NULL UNIQUE, - display_name text NOT NULL DEFAULT '', - status text NOT NULL DEFAULT 'active' CHECK (status IN ('active','suspended','deleted')), - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE operator_sessions ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - operator_id uuid NOT NULL REFERENCES operators(id), - refresh_digest bytea NOT NULL UNIQUE, - kind text NOT NULL DEFAULT 'operator' CHECK (kind IN ('setup','operator')), - ip_address inet, - user_agent text NOT NULL DEFAULT '', - last_used_at timestamptz NOT NULL DEFAULT now(), - expires_at timestamptz NOT NULL, - revoked_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE installation_operator_roles ( - operator_id uuid PRIMARY KEY REFERENCES operators(id), - role text NOT NULL CHECK (role IN ('owner','admin','auditor')), - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE operator_login_challenges ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - normalized_email text NOT NULL, - code_digest bytea, - link_digest bytea, - attempts integer NOT NULL DEFAULT 0, - expires_at timestamptz NOT NULL, - consumed_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE auth_rate_limits ( - bucket_digest bytea PRIMARY KEY, - attempts integer NOT NULL, - window_started_at timestamptz NOT NULL, - expires_at timestamptz NOT NULL -); -CREATE INDEX auth_rate_limits_expiry ON auth_rate_limits(expires_at); - -CREATE TABLE organizations ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - name text NOT NULL, - slug text NOT NULL UNIQUE, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - deleted_at timestamptz -); - -CREATE TABLE organization_memberships ( - organization_id uuid NOT NULL REFERENCES organizations(id), - operator_id uuid NOT NULL REFERENCES operators(id), - role text NOT NULL CHECK (role IN ('owner','admin','member','auditor')), - created_at timestamptz NOT NULL DEFAULT now(), - PRIMARY KEY (organization_id, operator_id) -); - -CREATE TABLE organization_invitations ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - organization_id uuid NOT NULL REFERENCES organizations(id), - normalized_email text NOT NULL, - role text NOT NULL CHECK (role IN ('owner','admin','member','auditor')), - credential_digest bytea NOT NULL, - invited_by uuid NOT NULL REFERENCES operators(id), - accepted_by uuid REFERENCES operators(id), - expires_at timestamptz NOT NULL, - accepted_at timestamptz, - revoked_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); -CREATE UNIQUE INDEX organization_invitations_pending ON organization_invitations(organization_id,normalized_email) -WHERE accepted_at IS NULL AND revoked_at IS NULL; - -CREATE TABLE applications ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - organization_id uuid NOT NULL REFERENCES organizations(id), - name text NOT NULL, - slug text NOT NULL, - auth_config jsonb NOT NULL DEFAULT '{"registration_enabled":true,"password_enabled":true,"passwordless_enabled":true,"personal_api_keys":{"enabled":false}}', - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - deleted_at timestamptz, - UNIQUE (organization_id, slug) -); - -CREATE TABLE application_domains ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - hostname text NOT NULL, - verification_ciphertext text NOT NULL, - verified_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, hostname) -); - -CREATE TABLE application_secrets ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - kind text NOT NULL, - name text NOT NULL, - ciphertext text NOT NULL, - metadata jsonb NOT NULL DEFAULT '{}', - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, kind, name) -); - -CREATE TABLE clients ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - client_id text NOT NULL, - name text NOT NULL, - client_type text NOT NULL CHECK (client_type IN ('public','confidential','machine')), - redirect_uris text[] NOT NULL DEFAULT '{}', - post_logout_redirect_uris text[] NOT NULL DEFAULT '{}', - allowed_grants text[] NOT NULL DEFAULT '{}', - allowed_scopes text[] NOT NULL DEFAULT '{}', - secret_digest bytea, - disabled_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (client_id) -); - -CREATE TABLE users ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - email text NOT NULL, - normalized_email text NOT NULL, - first_name text NOT NULL DEFAULT '', - last_name text NOT NULL DEFAULT '', - username text, - password_hash text, - email_verified_at timestamptz, - is_org_verified boolean NOT NULL DEFAULT false, - status text NOT NULL DEFAULT 'active' CHECK (status IN ('active','suspended','pending_deletion','anonymized','deleted')), - custom_attributes jsonb NOT NULL DEFAULT '{}', - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - deleted_at timestamptz, - UNIQUE (application_id, normalized_email) -); -CREATE UNIQUE INDEX users_application_identity ON users(application_id,id); - -CREATE TABLE user_identities ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - provider text NOT NULL, - provider_subject text NOT NULL, - metadata jsonb NOT NULL DEFAULT '{}', - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, provider, provider_subject) -); - -CREATE TABLE login_challenges ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - normalized_email text NOT NULL, - requested_by_user_id uuid REFERENCES users(id), - intent text NOT NULL CHECK (intent IN ('sign_in','sign_up','automatic','verify_email','change_email','password_reset')), - code_digest bytea, - link_digest bytea, - redirect_uri text, - attempts integer NOT NULL DEFAULT 0, - expires_at timestamptz NOT NULL, - consumed_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); +-- +goose StatementBegin +SET LOCAL check_function_bodies = false; -CREATE TABLE external_auth_challenges ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider text NOT NULL, - flow text NOT NULL CHECK (flow IN ('sign_in','sign_up','automatic','link')), - requested_by_user_id uuid REFERENCES users(id), - app_redirect_uri text NOT NULL, - state_digest bytea NOT NULL UNIQUE, - nonce_digest bytea NOT NULL, - verifier_ciphertext text NOT NULL, - expires_at timestamptz NOT NULL, - locked_until timestamptz, - consumed_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE external_auth_exchanges ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - credential_digest bytea NOT NULL UNIQUE, - expires_at timestamptz NOT NULL, - consumed_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE delegations ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - operator_id uuid NOT NULL REFERENCES operators(id), - user_id uuid NOT NULL REFERENCES users(id), - workspace_id uuid, - reason text NOT NULL, - redirect_uri text NOT NULL, - permissions text[] NOT NULL, - exchange_digest bytea NOT NULL UNIQUE, - expires_at timestamptz NOT NULL, - exchanged_at timestamptz, - revoked_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE user_sessions ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - delegation_id uuid REFERENCES delegations(id), - refresh_digest bytea NOT NULL UNIQUE, - previous_refresh_digest bytea, - previous_valid_until timestamptz, - user_agent text, - ip_hash bytea, - authenticated_at timestamptz NOT NULL DEFAULT now(), - mfa_authenticated_at timestamptz, - amr text[] NOT NULL DEFAULT '{}', - expires_at timestamptz NOT NULL, - revoked_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - last_used_at timestamptz -); - -CREATE TABLE user_authentication_methods ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - method_type text NOT NULL CHECK (method_type IN ('totp','webauthn')), - label text NOT NULL DEFAULT '', - secret_ciphertext text, - credential_id bytea, - credential_ciphertext text, - webauthn_rp_id text, - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','active','disabled')), - created_at timestamptz NOT NULL DEFAULT now(), - activated_at timestamptz, - last_used_at timestamptz, - disabled_at timestamptz -); -CREATE INDEX user_authentication_methods_user ON user_authentication_methods(application_id,user_id,status); -CREATE UNIQUE INDEX user_authentication_methods_webauthn_credential ON user_authentication_methods(application_id,credential_id) -WHERE method_type='webauthn' AND status<>'disabled'; - -CREATE TABLE user_recovery_codes ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - code_digest bytea NOT NULL, - used_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id,code_digest) -); +CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public; -CREATE TABLE mfa_login_challenges ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - primary_amr text[] NOT NULL, - attempts integer NOT NULL DEFAULT 0, - expires_at timestamptz NOT NULL, - consumed_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE webauthn_ceremonies ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - user_session_id uuid REFERENCES user_sessions(id), - mfa_challenge_id uuid REFERENCES mfa_login_challenges(id), - intent text NOT NULL CHECK (intent IN ('register','authenticate')), - origin text NOT NULL, - label text NOT NULL DEFAULT '', - session_ciphertext text NOT NULL, - expires_at timestamptz NOT NULL, - consumed_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); +COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions'; --- Fosite stores only token signatures and sanitized request state. Raw OAuth --- credentials never enter PostgreSQL and cannot be reconstructed from it. -CREATE TABLE oauth_sessions ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - signature_digest bytea NOT NULL, - kind text NOT NULL CHECK (kind IN ('authorize_code','pkce','openid','access','refresh')), - request_id text NOT NULL, - request_payload jsonb NOT NULL, - access_signature_digest bytea, - expires_at timestamptz NOT NULL, - active boolean NOT NULL DEFAULT true, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, kind, signature_digest) -); -CREATE INDEX oauth_sessions_request ON oauth_sessions(application_id,request_id,kind) WHERE active; -CREATE INDEX oauth_sessions_expiry ON oauth_sessions(expires_at); +CREATE FUNCTION public.valid_permission_key(value text) RETURNS boolean + LANGUAGE sql IMMUTABLE + AS $$ +SELECT value IS NOT NULL + AND length(value) BETWEEN 1 AND 160 + AND octet_length(value)=length(value) + AND value ~ '^(\*|[a-z0-9][a-z0-9._-]{0,63}(:[a-z0-9][a-z0-9._-]{0,63})*(:\*)?)$'; +$$; -CREATE TABLE oauth_client_assertion_jtis ( - application_id uuid NOT NULL REFERENCES applications(id), - jti_digest bytea NOT NULL, - expires_at timestamptz NOT NULL, - created_at timestamptz NOT NULL DEFAULT now(), - PRIMARY KEY (application_id,jti_digest) -); -CREATE INDEX oauth_client_assertion_jtis_expiry ON oauth_client_assertion_jtis(expires_at); - -CREATE TABLE oauth_consents ( - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - client_id uuid NOT NULL REFERENCES clients(id), - scopes text[] NOT NULL DEFAULT '{}', - granted_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - revoked_at timestamptz, - PRIMARY KEY (application_id,user_id,client_id) -); - -CREATE TABLE personal_api_keys ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - label text, - token_prefix text NOT NULL, - token_digest bytea NOT NULL UNIQUE, - scopes text[] NOT NULL DEFAULT '{}', - expires_at timestamptz NOT NULL, - last_used_at timestamptz, - revoked_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE billing_profiles ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - subject_type text NOT NULL CHECK (subject_type IN ('user','workspace')), - subject_id uuid NOT NULL, - name text NOT NULL DEFAULT '', - email text, - tax_id text, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id,subject_type,subject_id) -); +CREATE FUNCTION public.valid_canonical_scope(application uuid, value text) RETURNS boolean + LANGUAGE sql IMMUTABLE + AS $$ +SELECT value IS NOT NULL + AND octet_length(value)=length(value) + AND value LIKE '/applications/' || application::text || '/%' + AND value ~ '^/applications/[0-9a-f-]+/(\*|[a-z0-9][a-z0-9._-]{0,63}(/[a-z0-9][a-z0-9._-]{0,63})*(/\*)?)$'; +$$; -CREATE TABLE addresses ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - billing_profile_id uuid NOT NULL REFERENCES billing_profiles(id), - name text NOT NULL DEFAULT '', - line1 text NOT NULL, - line2 text NOT NULL DEFAULT '', - city text NOT NULL, - region text NOT NULL DEFAULT '', - postal_code text NOT NULL, - country_code char(2) NOT NULL, - is_active boolean NOT NULL DEFAULT false, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); -CREATE UNIQUE INDEX addresses_one_active ON addresses(billing_profile_id) WHERE is_active; +CREATE FUNCTION public.valid_canonical_scopes(application uuid, scope_values text[], allow_empty boolean) RETURNS boolean + LANGUAGE sql IMMUTABLE + AS $$ +SELECT scope_values IS NOT NULL + AND (allow_empty OR cardinality(scope_values)>0) + AND cardinality(scope_values)<=200 + AND cardinality(scope_values)=cardinality(ARRAY(SELECT DISTINCT item FROM unnest(scope_values) item)) + AND NOT EXISTS (SELECT 1 FROM unnest(scope_values) item WHERE NOT public.valid_canonical_scope(application,item)); +$$; -CREATE TABLE roles ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - key text NOT NULL, - name text NOT NULL, - scope text NOT NULL CHECK (scope IN ('application','workspace')), - permissions text[] NOT NULL DEFAULT '{}', - built_in boolean NOT NULL DEFAULT false, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, key) -); +CREATE FUNCTION public.valid_permission_keys(permission_values text[]) RETURNS boolean + LANGUAGE sql IMMUTABLE + AS $$ +SELECT permission_values IS NOT NULL + AND cardinality(permission_values) BETWEEN 1 AND 200 + AND cardinality(permission_values)=cardinality(ARRAY(SELECT DISTINCT item FROM unnest(permission_values) item)) + AND NOT EXISTS (SELECT 1 FROM unnest(permission_values) item WHERE NOT public.valid_permission_key(item)); +$$; -CREATE TABLE workspaces ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - owner_user_id uuid NOT NULL, - key text NOT NULL, - name text NOT NULL, - metadata jsonb NOT NULL DEFAULT '{}', - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - deleted_at timestamptz, - UNIQUE (application_id, key), - UNIQUE (application_id, id), - FOREIGN KEY (application_id,owner_user_id) REFERENCES users(application_id,id) -); +CREATE FUNCTION public.enforce_permission_grant() RETURNS trigger + LANGUAGE plpgsql + AS $$ +DECLARE + expected_scope text; +BEGIN + IF TG_OP='UPDATE' AND ( + NEW.application_id IS DISTINCT FROM OLD.application_id OR NEW.user_id IS DISTINCT FROM OLD.user_id OR + NEW.client_id IS DISTINCT FROM OLD.client_id OR NEW.workspace_id IS DISTINCT FROM OLD.workspace_id OR + NEW.permission IS DISTINCT FROM OLD.permission OR NEW.canonical_scope IS DISTINCT FROM OLD.canonical_scope OR + NEW.reason IS DISTINCT FROM OLD.reason OR NEW.created_by_type IS DISTINCT FROM OLD.created_by_type OR + NEW.created_by_id IS DISTINCT FROM OLD.created_by_id OR NEW.created_at IS DISTINCT FROM OLD.created_at OR + OLD.revoked_at IS NOT NULL AND NEW.revoked_at IS NULL + ) THEN + RAISE EXCEPTION 'permission grants are immutable except for one-way revocation'; + END IF; + IF NOT public.valid_permission_key(NEW.permission) OR split_part(NEW.permission,':',1)='roles' THEN + RAISE EXCEPTION 'permission grant contains an invalid or reserved permission'; + END IF; + IF NEW.user_id IS NOT NULL AND NOT EXISTS ( + SELECT 1 FROM users u WHERE u.id=NEW.user_id AND u.application_id=NEW.application_id AND u.status='active' + ) THEN + RAISE EXCEPTION 'permission grant user must be active in the application'; + END IF; + IF NEW.client_id IS NOT NULL AND NOT EXISTS ( + SELECT 1 FROM clients c WHERE c.id=NEW.client_id AND c.application_id=NEW.application_id AND c.disabled_at IS NULL + ) THEN + RAISE EXCEPTION 'permission grant client must be active in the application'; + END IF; + IF NEW.workspace_id IS NOT NULL AND NOT EXISTS ( + SELECT 1 FROM workspaces w WHERE w.id=NEW.workspace_id AND w.application_id=NEW.application_id AND w.deleted_at IS NULL + ) THEN + RAISE EXCEPTION 'permission grant workspace must be active in the application'; + END IF; + IF NEW.workspace_id IS NOT NULL AND NEW.user_id IS NOT NULL AND NOT EXISTS ( + SELECT 1 FROM workspaces w WHERE w.id=NEW.workspace_id AND w.application_id=NEW.application_id + AND (w.owner_user_id=NEW.user_id OR EXISTS ( + SELECT 1 FROM workspace_memberships m WHERE m.workspace_id=w.id AND m.user_id=NEW.user_id + )) + ) THEN + RAISE EXCEPTION 'permission grant user must belong to the workspace'; + END IF; + expected_scope := '/applications/' || NEW.application_id::text || + CASE WHEN NEW.workspace_id IS NULL THEN '' ELSE '/workspaces/' || NEW.workspace_id::text END || + '/' || replace(NEW.permission,':','/'); + IF NEW.canonical_scope<>expected_scope THEN + RAISE EXCEPTION 'permission grant canonical scope is invalid'; + END IF; + RETURN NEW; +END; +$$; -CREATE TABLE workspace_memberships ( - application_id uuid NOT NULL, - workspace_id uuid NOT NULL, - user_id uuid NOT NULL, - created_at timestamptz NOT NULL DEFAULT now(), - PRIMARY KEY (workspace_id,user_id), - FOREIGN KEY (application_id,workspace_id) REFERENCES workspaces(application_id,id), - FOREIGN KEY (application_id,user_id) REFERENCES users(application_id,id) -); +CREATE FUNCTION public.create_default_organization_policy() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + INSERT INTO organization_policies(organization_id) VALUES(NEW.id); + RETURN NEW; +END; +$$; --- +goose StatementBegin -CREATE FUNCTION workspace_accessible_to_user(target_application_id uuid, target_workspace_id uuid, target_user_id uuid) -RETURNS boolean LANGUAGE sql STABLE PARALLEL SAFE AS $$ - SELECT EXISTS( - SELECT 1 FROM workspaces w - WHERE w.application_id=target_application_id AND w.id=target_workspace_id AND w.deleted_at IS NULL - AND (w.owner_user_id=target_user_id OR EXISTS( - SELECT 1 FROM workspace_memberships m - WHERE m.application_id=w.application_id AND m.workspace_id=w.id AND m.user_id=target_user_id - )) - ); +CREATE FUNCTION public.enforce_application_subject() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + IF NEW.subject_type='user' AND NOT EXISTS ( + SELECT 1 FROM users u WHERE u.application_id=NEW.application_id AND u.id=NEW.subject_id + ) THEN + RAISE EXCEPTION 'user subject must belong to the row application'; + ELSIF NEW.subject_type='workspace' AND NOT EXISTS ( + SELECT 1 FROM workspaces w WHERE w.application_id=NEW.application_id AND w.id=NEW.subject_id + ) THEN + RAISE EXCEPTION 'workspace subject must belong to the row application'; + END IF; + RETURN NEW; +END; $$; --- +goose StatementEnd -CREATE TABLE role_assignments ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid REFERENCES users(id), - client_id uuid REFERENCES clients(id), - role_id uuid NOT NULL REFERENCES roles(id), - workspace_id uuid REFERENCES workspaces(id), - created_at timestamptz NOT NULL DEFAULT now(), - CHECK ((user_id IS NOT NULL) <> (client_id IS NOT NULL)) -); -CREATE UNIQUE INDEX role_assignments_unique_user ON role_assignments(application_id,user_id,role_id,workspace_id) NULLS NOT DISTINCT WHERE user_id IS NOT NULL; -CREATE UNIQUE INDEX role_assignments_unique_client ON role_assignments(application_id,client_id,role_id,workspace_id) NULLS NOT DISTINCT WHERE client_id IS NOT NULL; +CREATE FUNCTION public.enforce_notification_template_asset_scope() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM notification_templates t JOIN storage_objects o ON o.id=NEW.storage_object_id + WHERE t.id=NEW.notification_template_id AND o.status='ready' AND o.visibility='public' + AND o.content_type IN ('image/png','image/jpeg','image/gif') + AND ((t.application_id IS NULL AND o.owner_type='installation') OR + (t.application_id IS NOT NULL AND ( + (o.application_id=t.application_id AND o.owner_type='application') OR + o.owner_type='installation' + ))) + ) THEN + RAISE EXCEPTION 'template assets must be ready public images from the template scope'; + END IF; + RETURN NEW; +END; +$$; --- +goose StatementBegin -CREATE FUNCTION enforce_workspace_owner_membership_separation() RETURNS trigger LANGUAGE plpgsql AS $$ +CREATE FUNCTION public.enforce_storage_object_scope() RETURNS trigger + LANGUAGE plpgsql + AS $$ +DECLARE + provider_application uuid; + provider_organization uuid; + provider_public_bucket text; + provider_private_bucket text; BEGIN - IF EXISTS (SELECT 1 FROM workspaces w WHERE w.id=NEW.workspace_id AND w.owner_user_id=NEW.user_id) THEN - RAISE EXCEPTION 'workspace owner cannot also be a member'; + SELECT application_id,organization_id,public_bucket,private_bucket + INTO provider_application,provider_organization,provider_public_bucket,provider_private_bucket + FROM storage_providers WHERE id=NEW.storage_provider_id; + IF NEW.bucket_role='public' AND provider_public_bucket IS DISTINCT FROM NEW.bucket_name THEN + RAISE EXCEPTION 'public object bucket must match its storage provider'; + END IF; + IF NEW.bucket_role='private' AND provider_private_bucket IS DISTINCT FROM NEW.bucket_name THEN + RAISE EXCEPTION 'private object bucket must match its storage provider'; + END IF; + IF NEW.owner_type='installation' THEN + IF provider_application IS NOT NULL OR provider_organization IS NOT NULL THEN + RAISE EXCEPTION 'installation assets require an installation storage provider'; + END IF; + RETURN NEW; + END IF; + IF provider_application IS NOT NULL AND provider_application<>NEW.application_id THEN + RAISE EXCEPTION 'storage provider belongs to another application'; + END IF; + IF provider_organization IS NOT NULL AND NOT EXISTS ( + SELECT 1 FROM applications a WHERE a.id=NEW.application_id AND a.organization_id=provider_organization + ) THEN + RAISE EXCEPTION 'storage provider belongs to another organization'; + END IF; + IF NEW.owner_type='user' AND NOT EXISTS ( + SELECT 1 FROM users u WHERE u.id=NEW.owner_id AND u.application_id=NEW.application_id AND u.status='active' + ) THEN + RAISE EXCEPTION 'storage object user must be active in the application'; + END IF; + IF NEW.owner_type='workspace' AND NOT EXISTS ( + SELECT 1 FROM workspaces w WHERE w.id=NEW.owner_id AND w.application_id=NEW.application_id AND w.deleted_at IS NULL + ) THEN + RAISE EXCEPTION 'storage object workspace must be active in the application'; END IF; RETURN NEW; END; $$; --- +goose StatementEnd -CREATE TRIGGER workspace_memberships_owner_guard BEFORE INSERT OR UPDATE ON workspace_memberships -FOR EACH ROW EXECUTE FUNCTION enforce_workspace_owner_membership_separation(); --- +goose StatementBegin -CREATE FUNCTION enforce_workspace_owner_is_active_non_member() RETURNS trigger LANGUAGE plpgsql AS $$ +CREATE FUNCTION public.enforce_workspace_owner_is_active_non_member() RETURNS trigger + LANGUAGE plpgsql + AS $$ DECLARE owner_status text; BEGIN @@ -502,12 +205,21 @@ BEGIN RETURN NEW; END; $$; --- +goose StatementEnd -CREATE TRIGGER workspaces_owner_guard BEFORE INSERT OR UPDATE OF owner_user_id ON workspaces -FOR EACH ROW EXECUTE FUNCTION enforce_workspace_owner_is_active_non_member(); --- +goose StatementBegin -CREATE FUNCTION prevent_inactive_workspace_owner() RETURNS trigger LANGUAGE plpgsql AS $$ +CREATE FUNCTION public.enforce_workspace_owner_membership_separation() RETURNS trigger + LANGUAGE plpgsql + AS $$ +BEGIN + IF EXISTS (SELECT 1 FROM workspaces w WHERE w.id=NEW.workspace_id AND w.owner_user_id=NEW.user_id) THEN + RAISE EXCEPTION 'workspace owner cannot also be a member'; + END IF; + RETURN NEW; +END; +$$; + +CREATE FUNCTION public.prevent_inactive_workspace_owner() RETURNS trigger + LANGUAGE plpgsql + AS $$ BEGIN IF OLD.status='active' AND NEW.status<>'active' AND EXISTS ( SELECT 1 FROM workspaces w @@ -518,621 +230,2431 @@ BEGIN RETURN NEW; END; $$; --- +goose StatementEnd -CREATE TRIGGER users_active_workspace_owner_guard BEFORE UPDATE OF status ON users -FOR EACH ROW EXECUTE FUNCTION prevent_inactive_workspace_owner(); -CREATE TABLE workspace_invitations ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - workspace_id uuid NOT NULL REFERENCES workspaces(id), - normalized_email text NOT NULL, - credential_digest bytea NOT NULL, - roles text[] NOT NULL DEFAULT '{}', - expires_at timestamptz NOT NULL, - accepted_at timestamptz, - revoked_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() -); -ALTER TABLE delegations ADD CONSTRAINT delegations_workspace_fk -FOREIGN KEY (workspace_id) REFERENCES workspaces(id); -CREATE UNIQUE INDEX workspace_invitations_pending_email ON workspace_invitations(application_id,workspace_id,normalized_email) -WHERE accepted_at IS NULL AND revoked_at IS NULL; - -CREATE TABLE features ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - key text NOT NULL, - name text NOT NULL, - value_type text NOT NULL CHECK (value_type IN ('boolean','quantity','configuration')), - metadata jsonb NOT NULL DEFAULT '{}', - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, key) +CREATE FUNCTION public.workspace_accessible_to_user(target_application_id uuid, target_workspace_id uuid, target_user_id uuid) RETURNS boolean + LANGUAGE sql STABLE PARALLEL SAFE + AS $$ + SELECT EXISTS( + SELECT 1 FROM workspaces w + WHERE w.application_id=target_application_id AND w.id=target_workspace_id AND w.deleted_at IS NULL + AND (w.owner_user_id=target_user_id OR EXISTS( + SELECT 1 FROM workspace_memberships m + WHERE m.application_id=w.application_id AND m.workspace_id=w.id AND m.user_id=target_user_id + )) + ); +$$; + + + +CREATE TABLE public.addresses ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + billing_profile_id uuid NOT NULL, + name text DEFAULT ''::text NOT NULL, + line1 text NOT NULL, + line2 text DEFAULT ''::text NOT NULL, + city text NOT NULL, + region text DEFAULT ''::text NOT NULL, + postal_code text NOT NULL, + country_code character(2) NOT NULL, + is_active boolean DEFAULT false NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE TABLE products ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - key text NOT NULL, - name text NOT NULL, - description text NOT NULL DEFAULT '', - listable boolean NOT NULL DEFAULT true, - status text NOT NULL DEFAULT 'active' CHECK (status IN ('draft','active','archived')), - metadata jsonb NOT NULL DEFAULT '{}', - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, key) -); - -CREATE TABLE prices ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - product_id uuid NOT NULL REFERENCES products(id), - key text NOT NULL, - mode text NOT NULL CHECK (mode IN ('recurring','one_time','local')), - amount_minor bigint NOT NULL CHECK (amount_minor >= 0), - currency char(3) NOT NULL, - currency_exponent smallint NOT NULL DEFAULT 2, - interval_unit text CHECK (interval_unit IN ('day','week','month','year')), - interval_count integer, - validity_seconds bigint, - grace_seconds bigint NOT NULL DEFAULT 0, - tax_behavior text NOT NULL DEFAULT 'inclusive' CHECK (tax_behavior IN ('inclusive','exclusive','unspecified')), - checkout_config jsonb NOT NULL DEFAULT '{}', - entitlement_config jsonb NOT NULL DEFAULT '{}', - active boolean NOT NULL DEFAULT true, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, key) -); - -CREATE TABLE price_features ( - price_id uuid NOT NULL REFERENCES prices(id), - feature_id uuid NOT NULL REFERENCES features(id), - boolean_value boolean, - quantity_value bigint, - configuration_value jsonb, - PRIMARY KEY (price_id, feature_id) +CREATE TABLE public.application_domains ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + hostname text NOT NULL, + verification_ciphertext text NOT NULL, + verified_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE TABLE entitlement_grants ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - subject_type text NOT NULL CHECK (subject_type IN ('user','workspace')), - subject_id uuid NOT NULL, - product_id uuid REFERENCES products(id), - price_id uuid REFERENCES prices(id), - source_type text NOT NULL CHECK (source_type IN ('manual','local_request','subscription','one_time','system')), - source_id uuid, - feature_values jsonb NOT NULL DEFAULT '{}', - configuration jsonb NOT NULL DEFAULT '{}', - starts_at timestamptz NOT NULL, - expires_at timestamptz, - revoked_at timestamptz, - revocation_reason text, - created_by uuid, - created_at timestamptz NOT NULL DEFAULT now() +CREATE TABLE public.application_invitations ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + workspace_id uuid, + normalized_email text NOT NULL, + link_credential_digest bytea NOT NULL, + workspace_roles text[] DEFAULT '{}'::text[] NOT NULL, + expires_at timestamp with time zone NOT NULL, + accepted_at timestamp with time zone, + revoked_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + code_credential_digest bytea, + application_roles text[] DEFAULT '{}'::text[] NOT NULL, + inviter_type text DEFAULT 'control_user'::text NOT NULL, + inviter_id uuid, + last_sent_at timestamp with time zone DEFAULT now() NOT NULL, + resend_available_at timestamp with time zone DEFAULT (now() + '00:01:00'::interval) NOT NULL, + expiration_recorded_at timestamp with time zone, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT application_invitations_inviter_type_check CHECK ((inviter_type = ANY (ARRAY['control_user'::text, 'user'::text, 'client'::text]))) +); + +CREATE TABLE public.application_secrets ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + kind text NOT NULL, + name text NOT NULL, + ciphertext text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE INDEX entitlement_grants_effective ON entitlement_grants(application_id, subject_type, subject_id, starts_at, expires_at); -CREATE UNIQUE INDEX entitlement_grants_unique_source ON entitlement_grants(application_id,source_type,source_id,product_id) WHERE source_id IS NOT NULL; -CREATE TABLE entitlement_grant_actions ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - grant_id uuid NOT NULL REFERENCES entitlement_grants(id) ON DELETE CASCADE, - action text NOT NULL CHECK (action IN ('adjusted','revoked','restored')), - action_key text, - expires_at timestamptz, - reason text, - actor_type text NOT NULL CHECK (actor_type IN ('operator','provider','system')), - actor_id uuid, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE NULLS DISTINCT (grant_id,action_key) +CREATE TABLE public.applications ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + organization_id uuid NOT NULL, + name text NOT NULL, + slug text NOT NULL, + auth_config jsonb DEFAULT '{}'::jsonb NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + deleted_at timestamp with time zone, + public_config jsonb DEFAULT '{}'::jsonb NOT NULL, + internal_config jsonb DEFAULT '{"password_enabled": true, "registration_mode": "public", "delegation_enabled": false, "passwordless_enabled": true, "custom_token_claim_keys": [], "user_invitations_enabled": false, "personal_api_keys_enabled": false}'::jsonb NOT NULL, + CONSTRAINT applications_internal_config_check CHECK (((jsonb_typeof(public_config) = 'object'::text) AND (jsonb_typeof(internal_config) = 'object'::text) AND (internal_config ?& ARRAY['registration_mode'::text, 'password_enabled'::text, 'passwordless_enabled'::text, 'personal_api_keys_enabled'::text, 'delegation_enabled'::text, 'user_invitations_enabled'::text, 'custom_token_claim_keys'::text]) AND ((internal_config ->> 'registration_mode'::text) = ANY (ARRAY['public'::text, 'invite_only'::text])) AND (jsonb_typeof((internal_config -> 'password_enabled'::text)) = 'boolean'::text) AND (jsonb_typeof((internal_config -> 'passwordless_enabled'::text)) = 'boolean'::text) AND (jsonb_typeof((internal_config -> 'personal_api_keys_enabled'::text)) = 'boolean'::text) AND (jsonb_typeof((internal_config -> 'delegation_enabled'::text)) = 'boolean'::text) AND (jsonb_typeof((internal_config -> 'user_invitations_enabled'::text)) = 'boolean'::text) AND (jsonb_typeof((internal_config -> 'custom_token_claim_keys'::text)) = 'array'::text))) +); + +CREATE TABLE public.audit_exports ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + organization_id uuid, + application_id uuid, + requested_by uuid NOT NULL, + filter_snapshot jsonb DEFAULT '{}'::jsonb NOT NULL, + payload_ciphertext text NOT NULL, + record_count integer NOT NULL, + expires_at timestamp with time zone NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE INDEX entitlement_grant_actions_history ON entitlement_grant_actions(grant_id,created_at,id); -CREATE TABLE local_entitlement_requests ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - requester_user_id uuid NOT NULL REFERENCES users(id), - subject_type text NOT NULL CHECK (subject_type IN ('user','workspace')), - subject_id uuid NOT NULL, - product_id uuid NOT NULL REFERENCES products(id), - price_id uuid NOT NULL REFERENCES prices(id), - product_snapshot jsonb NOT NULL, - price_snapshot jsonb NOT NULL, - feature_snapshot jsonb NOT NULL DEFAULT '{}', - address_snapshot jsonb, - local_reference text, - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','approved','rejected','canceled')), - decision_reason text, - reviewed_by uuid REFERENCES operators(id), - reviewed_at timestamptz, - entitlement_grant_id uuid REFERENCES entitlement_grants(id), - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE local_entitlement_request_actions ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - request_id uuid NOT NULL REFERENCES local_entitlement_requests(id) ON DELETE CASCADE, - action text NOT NULL CHECK (action IN ('created','approved','rejected','canceled','reopened')), - actor_type text NOT NULL CHECK (actor_type IN ('user','operator')), - actor_id uuid NOT NULL, +CREATE TABLE public.audit_records ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + organization_id uuid, + application_id uuid, + actor_type text NOT NULL, + actor_id uuid, + action text NOT NULL, + target_type text, + target_id uuid, reason text, - created_at timestamptz NOT NULL DEFAULT now() + request_id text, + changes jsonb DEFAULT '{}'::jsonb NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE INDEX local_entitlement_request_actions_history ON local_entitlement_request_actions(request_id,created_at,id); -CREATE TABLE provider_connections ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), +CREATE TABLE public.auth_provider_configs ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + organization_id uuid, + application_id uuid, provider text NOT NULL, - public_id text NOT NULL UNIQUE, - api_version text NOT NULL, - secret_ciphertext text NOT NULL, - webhook_secret_ciphertext text, - status text NOT NULL DEFAULT 'active' CHECK (status IN ('active','disabled','error')), - metadata jsonb NOT NULL DEFAULT '{}', - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE provider_mappings ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), - object_type text NOT NULL CHECK (object_type IN ('product','price')), - internal_id uuid NOT NULL, - provider_id text NOT NULL, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (provider_connection_id, object_type, internal_id), - UNIQUE (provider_connection_id, object_type, provider_id) + client_id text NOT NULL, + config_ciphertext text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + inheritable boolean DEFAULT false NOT NULL, + control_login_enabled boolean DEFAULT false NOT NULL, + disabled_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT auth_provider_configs_check CHECK ((((application_id IS NOT NULL) AND (organization_id IS NULL)) OR ((application_id IS NULL) AND (organization_id IS NOT NULL)) OR ((application_id IS NULL) AND (organization_id IS NULL)))), + CONSTRAINT auth_provider_configs_provider_check CHECK ((provider = ANY (ARRAY['google'::text, 'apple'::text]))), + CONSTRAINT auth_provider_configs_control_login_scope_check CHECK ((control_login_enabled = false) OR ((application_id IS NULL) AND (organization_id IS NULL))) +); + +CREATE TABLE public.auth_rate_limits ( + bucket_digest bytea NOT NULL, + attempts integer NOT NULL, + window_started_at timestamp with time zone NOT NULL, + expires_at timestamp with time zone NOT NULL ); -CREATE TABLE billing_customers ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - subject_type text NOT NULL CHECK (subject_type IN ('user','workspace')), +CREATE TABLE public.billing_customers ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + subject_type text NOT NULL, subject_id uuid NOT NULL, - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), + provider_connection_id uuid NOT NULL, provider_customer_id text, name text, email text, address_snapshot jsonb, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (provider_connection_id, subject_type, subject_id) + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT billing_customers_subject_type_check CHECK ((subject_type = ANY (ARRAY['user'::text, 'workspace'::text]))) +); + +CREATE TABLE public.billing_profiles ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + subject_type text NOT NULL, + subject_id uuid NOT NULL, + name text DEFAULT ''::text NOT NULL, + email text, + tax_id text, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT billing_profiles_subject_type_check CHECK ((subject_type = ANY (ARRAY['user'::text, 'workspace'::text]))) ); -CREATE TABLE checkout_sessions ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - subject_type text NOT NULL CHECK (subject_type IN ('user','workspace')), +CREATE TABLE public.checkout_sessions ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + subject_type text NOT NULL, subject_id uuid NOT NULL, - price_id uuid NOT NULL REFERENCES prices(id), - provider_connection_id uuid REFERENCES provider_connections(id), + price_id uuid NOT NULL, + provider_connection_id uuid, provider_session_id text, - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','open','completed','expired','failed')), - payment_methods text[] NOT NULL DEFAULT '{}', + status text DEFAULT 'pending'::text NOT NULL, + payment_methods text[] DEFAULT '{}'::text[] NOT NULL, policy_snapshot jsonb NOT NULL, success_uri text NOT NULL, cancel_uri text NOT NULL, checkout_uri text, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + external_reference text, + CONSTRAINT checkout_sessions_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'open'::text, 'completed'::text, 'expired'::text, 'failed'::text]))), + CONSTRAINT checkout_sessions_subject_type_check CHECK ((subject_type = ANY (ARRAY['user'::text, 'workspace'::text]))) +); + +CREATE TABLE public.clients ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + client_id text NOT NULL, + name text NOT NULL, + client_type text NOT NULL, + redirect_uris text[] DEFAULT '{}'::text[] NOT NULL, + post_logout_redirect_uris text[] DEFAULT '{}'::text[] NOT NULL, + allowed_grants text[] DEFAULT '{}'::text[] NOT NULL, + allowed_scopes text[] DEFAULT '{}'::text[] NOT NULL, + secret_digest bytea, + disabled_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT clients_client_type_check CHECK ((client_type = ANY (ARRAY['public'::text, 'confidential'::text, 'machine'::text]))) +); + +CREATE TABLE public.delegations ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + control_user_id uuid NOT NULL, + user_id uuid NOT NULL, + workspace_id uuid, + reason text NOT NULL, + redirect_uri text NOT NULL, + permissions text[] NOT NULL, + exchange_digest bytea NOT NULL, + expires_at timestamp with time zone NOT NULL, + exchanged_at timestamp with time zone, + revoked_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT delegations_permissions_format_check CHECK (public.valid_canonical_scopes(application_id,permissions,false) AND cardinality(permissions)<=50) ); -CREATE TABLE subscriptions ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), +CREATE TABLE public.disputes ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, + provider_payment_id text, + payment_id uuid, + provider_dispute_id text NOT NULL, + status text NOT NULL, + amount_minor bigint NOT NULL, + currency character(3) NOT NULL, + reason text, + evidence_due_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.domain_events ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid, + event_type text NOT NULL, + schema_version text DEFAULT '1.0'::text NOT NULL, + subject text, + actor jsonb, + correlation_id uuid, + causation_id uuid, + data jsonb NOT NULL, + occurred_at timestamp with time zone DEFAULT now() NOT NULL, + contract_source text DEFAULT 'platform93'::text NOT NULL, + CONSTRAINT domain_events_contract_source_check CHECK ((contract_source = ANY (ARRAY['platform93'::text, 'application'::text]))) +); + +CREATE TABLE public.entitlement_grant_actions ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + grant_id uuid NOT NULL, + action text NOT NULL, + action_key text, + expires_at timestamp with time zone, + reason text, + actor_type text NOT NULL, + actor_id uuid, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT entitlement_grant_actions_action_check CHECK ((action = ANY (ARRAY['adjusted'::text, 'revoked'::text, 'restored'::text]))), + CONSTRAINT entitlement_grant_actions_actor_type_check CHECK ((actor_type = ANY (ARRAY['control_user'::text, 'provider'::text, 'system'::text]))) +); + +CREATE TABLE public.entitlement_grants ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, subject_type text NOT NULL, subject_id uuid NOT NULL, - price_id uuid NOT NULL REFERENCES prices(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), - provider_subscription_id text NOT NULL, - provider_item_id text, - status text NOT NULL, - current_period_start timestamptz, - current_period_end timestamptz, - cancel_at timestamptz, - canceled_at timestamptz, - trial_end timestamptz, - cancel_at_period_end boolean NOT NULL DEFAULT false, - metadata jsonb NOT NULL DEFAULT '{}', - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (provider_connection_id, provider_subscription_id) -); - -CREATE TABLE invoices ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), + product_id uuid, + price_id uuid, + source_type text NOT NULL, + source_id uuid, + feature_values jsonb DEFAULT '{}'::jsonb NOT NULL, + configuration jsonb DEFAULT '{}'::jsonb NOT NULL, + starts_at timestamp with time zone NOT NULL, + expires_at timestamp with time zone, + revoked_at timestamp with time zone, + revocation_reason text, + created_by uuid, + created_at timestamp with time zone DEFAULT now() NOT NULL, + external_reference text, + expiration_recorded_at timestamp with time zone, + CONSTRAINT entitlement_grants_source_type_check CHECK ((source_type = ANY (ARRAY['manual'::text, 'local_request'::text, 'subscription'::text, 'one_time'::text, 'system'::text]))), + CONSTRAINT entitlement_grants_subject_type_check CHECK ((subject_type = ANY (ARRAY['user'::text, 'workspace'::text]))) +); + +CREATE TABLE public.event_type_definitions ( + id uuid NOT NULL, + application_id uuid, + name text NOT NULL, + description text DEFAULT ''::text NOT NULL, + schema_version text DEFAULT '1.0'::text NOT NULL, + data_schema jsonb DEFAULT '{}'::jsonb NOT NULL, + source text NOT NULL, + status text DEFAULT 'active'::text NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + example_subject text DEFAULT 'resource/example'::text NOT NULL, + example_data jsonb DEFAULT '{}'::jsonb NOT NULL, + CONSTRAINT event_type_definition_contract_check CHECK (((example_subject <> ''::text) AND (length(example_subject) <= 500) AND (jsonb_typeof(data_schema) = 'object'::text) AND (jsonb_typeof(example_data) = 'object'::text))), + CONSTRAINT event_type_definitions_check CHECK ((((source = 'platform93'::text) AND (application_id IS NULL)) OR ((source = 'application'::text) AND (application_id IS NOT NULL)))), + CONSTRAINT event_type_definitions_name_check CHECK ((name ~ '^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$'::text)), + CONSTRAINT event_type_definitions_schema_version_check CHECK ((schema_version ~ '^[1-9][0-9]*\.[0-9]+$'::text)), + CONSTRAINT event_type_definitions_source_check CHECK ((source = ANY (ARRAY['platform93'::text, 'application'::text]))), + CONSTRAINT event_type_definitions_status_check CHECK ((status = ANY (ARRAY['active'::text, 'archived'::text]))) +); + +CREATE TABLE public.external_auth_challenges ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider text NOT NULL, + flow text NOT NULL, + requested_by_user_id uuid, + app_redirect_uri text NOT NULL, + state_digest bytea NOT NULL, + nonce_digest bytea NOT NULL, + verifier_ciphertext text NOT NULL, + expires_at timestamp with time zone NOT NULL, + locked_until timestamp with time zone, + consumed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT external_auth_challenges_flow_check CHECK ((flow = ANY (ARRAY['sign_in'::text, 'sign_up'::text, 'automatic'::text, 'link'::text]))) +); + +CREATE TABLE public.external_auth_exchanges ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + credential_digest bytea NOT NULL, + expires_at timestamp with time zone NOT NULL, + consumed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.features ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + key text NOT NULL, + name text NOT NULL, + value_type text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + free_form_format text, + CONSTRAINT features_free_form_format_check CHECK ((((value_type = 'free_form'::text) AND (free_form_format = ANY (ARRAY['text'::text, 'csv'::text, 'json'::text]))) OR ((value_type <> 'free_form'::text) AND (free_form_format IS NULL)))), + CONSTRAINT features_value_type_check CHECK ((value_type = ANY (ARRAY['boolean'::text, 'quantity'::text, 'free_form'::text]))) +); + +CREATE TABLE public.idempotency_records ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid, + actor_key text NOT NULL, + idempotency_key text NOT NULL, + request_hash bytea NOT NULL, + response_status integer, + response_headers jsonb, + response_body bytea, + locked_until timestamp with time zone, + expires_at timestamp with time zone NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.installation_control_user_roles ( + control_user_id uuid NOT NULL, + role text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT installation_control_user_roles_role_check CHECK ((role = ANY (ARRAY['owner'::text, 'admin'::text, 'auditor'::text]))) +); + +CREATE TABLE public.installations ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + setup_completed_at timestamp with time zone, + bootstrap_digest bytea, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + management_api_enabled boolean DEFAULT false NOT NULL, + control_email_code_enabled boolean DEFAULT true NOT NULL, + control_magic_link_enabled boolean DEFAULT true NOT NULL, + control_password_enabled boolean DEFAULT true NOT NULL +); + +COMMENT ON COLUMN public.installations.management_api_enabled IS 'Live kill switch for machine-only installation organization management.'; + +CREATE TABLE public.invitation_authorization_codes ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + code_digest bytea NOT NULL, + code_challenge text NOT NULL, + expires_at timestamp with time zone NOT NULL, + used_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.invoices ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, provider_invoice_id text NOT NULL, provider_customer_id text, provider_subscription_id text, - billing_customer_id uuid REFERENCES billing_customers(id), - subscription_id uuid REFERENCES subscriptions(id), + billing_customer_id uuid, + subscription_id uuid, status text NOT NULL, - amount_due_minor bigint NOT NULL DEFAULT 0, - amount_paid_minor bigint NOT NULL DEFAULT 0, - tax_minor bigint NOT NULL DEFAULT 0, - currency char(3) NOT NULL, - due_at timestamptz, - paid_at timestamptz, + amount_due_minor bigint DEFAULT 0 NOT NULL, + amount_paid_minor bigint DEFAULT 0 NOT NULL, + tax_minor bigint DEFAULT 0 NOT NULL, + currency character(3) NOT NULL, + due_at timestamp with time zone, + paid_at timestamp with time zone, hosted_uri text, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (provider_connection_id, provider_invoice_id) + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + external_reference text ); -CREATE TABLE payments ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), - provider_payment_id text NOT NULL, - provider_customer_id text, - provider_invoice_id text, - billing_customer_id uuid REFERENCES billing_customers(id), - checkout_session_id uuid REFERENCES checkout_sessions(id), - invoice_id uuid REFERENCES invoices(id), - status text NOT NULL, - amount_minor bigint NOT NULL DEFAULT 0, - amount_received_minor bigint NOT NULL DEFAULT 0, - currency char(3) NOT NULL, - payment_method_type text, - failure_code text, - failure_message text, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (provider_connection_id, provider_payment_id) +CREATE TABLE public.local_entitlement_request_actions ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + request_id uuid NOT NULL, + action text NOT NULL, + actor_type text NOT NULL, + actor_id uuid NOT NULL, + reason text, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT local_entitlement_request_actions_action_check CHECK ((action = ANY (ARRAY['created'::text, 'approved'::text, 'rejected'::text, 'canceled'::text, 'reopened'::text]))), + CONSTRAINT local_entitlement_request_actions_actor_type_check CHECK ((actor_type = ANY (ARRAY['user'::text, 'control_user'::text]))) ); -CREATE TABLE refunds ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), - provider_payment_id text, - payment_id uuid REFERENCES payments(id), - provider_refund_id text NOT NULL, - status text NOT NULL, - amount_minor bigint NOT NULL, - currency char(3) NOT NULL, - reason text, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (provider_connection_id, provider_refund_id) +CREATE TABLE public.local_entitlement_requests ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + requester_user_id uuid NOT NULL, + subject_type text NOT NULL, + subject_id uuid NOT NULL, + product_id uuid NOT NULL, + price_id uuid NOT NULL, + product_snapshot jsonb NOT NULL, + price_snapshot jsonb NOT NULL, + feature_snapshot jsonb DEFAULT '{}'::jsonb NOT NULL, + address_snapshot jsonb, + external_reference text, + status text DEFAULT 'pending'::text NOT NULL, + decision_reason text, + reviewed_by uuid, + reviewed_at timestamp with time zone, + entitlement_grant_id uuid, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT local_entitlement_requests_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'approved'::text, 'rejected'::text, 'canceled'::text]))), + CONSTRAINT local_entitlement_requests_subject_type_check CHECK ((subject_type = ANY (ARRAY['user'::text, 'workspace'::text]))) ); -CREATE TABLE disputes ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), - provider_payment_id text, - payment_id uuid REFERENCES payments(id), - provider_dispute_id text NOT NULL, +CREATE TABLE public.login_challenges ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + normalized_email text NOT NULL, + requested_by_user_id uuid, + intent text NOT NULL, + code_digest bytea, + link_digest bytea, + redirect_uri text, + attempts integer DEFAULT 0 NOT NULL, + expires_at timestamp with time zone NOT NULL, + consumed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT login_challenges_intent_check CHECK ((intent = ANY (ARRAY['sign_in'::text, 'sign_up'::text, 'automatic'::text, 'verify_email'::text, 'change_email'::text, 'password_reset'::text]))) +); + +CREATE TABLE public.management_clients ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + client_id text NOT NULL, + name text NOT NULL, + secret_digest bytea NOT NULL, + allowed_scopes text[] DEFAULT ARRAY['/management/organizations/*'::text] NOT NULL, + disabled_at timestamp with time zone, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.mfa_login_challenges ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + primary_amr text[] NOT NULL, + attempts integer DEFAULT 0 NOT NULL, + expires_at timestamp with time zone NOT NULL, + consumed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.notification_attachments ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + notification_id uuid NOT NULL, + filename text NOT NULL, + content_type text NOT NULL, + content bytea NOT NULL, + size_bytes integer NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT notification_attachments_size_bytes_check CHECK (((size_bytes >= 0) AND (size_bytes <= 2097152))) +); + +CREATE TABLE public.notification_attempts ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + notification_id uuid NOT NULL, + notification_provider_id uuid, + attempt_number integer NOT NULL, status text NOT NULL, - amount_minor bigint NOT NULL, - currency char(3) NOT NULL, - reason text, - evidence_due_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (provider_connection_id, provider_dispute_id) -); - -CREATE TABLE reconciliation_runs ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), - status text NOT NULL CHECK (status IN ('pending','running','completed','failed')), - findings jsonb NOT NULL DEFAULT '[]', - repairs jsonb NOT NULL DEFAULT '[]', - last_error text, - started_at timestamptz, - completed_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() + error text, + started_at timestamp with time zone DEFAULT now() NOT NULL, + completed_at timestamp with time zone, + CONSTRAINT notification_attempts_status_check CHECK ((status = ANY (ARRAY['sending'::text, 'delivered'::text, 'failed'::text]))) ); -CREATE TABLE provider_events ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - provider_connection_id uuid NOT NULL REFERENCES provider_connections(id), - provider_event_id text NOT NULL, - api_version text, - event_type text NOT NULL, - raw_body_ciphertext text NOT NULL, - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','processed','failed','ignored')), - attempts integer NOT NULL DEFAULT 0, - last_error text, - received_at timestamptz NOT NULL DEFAULT now(), - processed_at timestamptz, - UNIQUE (provider_connection_id, provider_event_id) +CREATE TABLE public.notification_preferences ( + application_id uuid NOT NULL, + user_id uuid NOT NULL, + category text NOT NULL, + email_enabled boolean DEFAULT true NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE TABLE notification_providers ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid REFERENCES applications(id), - provider text NOT NULL DEFAULT 'smtp', +CREATE TABLE public.notification_providers ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid, + provider text DEFAULT 'smtp'::text NOT NULL, name text NOT NULL, config_ciphertext text NOT NULL, sender_email text NOT NULL, - sender_name text NOT NULL DEFAULT '', - verified_at timestamptz, - disabled_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() + sender_name text DEFAULT ''::text NOT NULL, + verified_at timestamp with time zone, + disabled_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + organization_id uuid, + inheritable boolean DEFAULT false NOT NULL, + CONSTRAINT notification_provider_scope_check CHECK ((((application_id IS NOT NULL) AND (organization_id IS NULL)) OR ((application_id IS NULL) AND (organization_id IS NOT NULL)) OR ((application_id IS NULL) AND (organization_id IS NULL)))) ); -CREATE TABLE sender_identities ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid REFERENCES applications(id), - notification_provider_id uuid NOT NULL REFERENCES notification_providers(id), - email text NOT NULL, - name text NOT NULL DEFAULT '', - is_default boolean NOT NULL DEFAULT false, - verified_at timestamptz, - disabled_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (notification_provider_id, email) +CREATE TABLE public.notification_template_assets ( + notification_template_id uuid NOT NULL, + storage_object_id uuid NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE TABLE notification_templates ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), +CREATE TABLE public.notification_templates ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid, key text NOT NULL, - locale text NOT NULL DEFAULT 'en', + locale text DEFAULT 'en'::text NOT NULL, category text NOT NULL, version integer NOT NULL, subject_template text NOT NULL, text_template text NOT NULL, html_template text, - variable_schema jsonb NOT NULL DEFAULT '{}', - status text NOT NULL DEFAULT 'draft' CHECK (status IN ('draft','published','archived')), - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (application_id, key, locale, version) -); - -CREATE TABLE notifications ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid REFERENCES applications(id), - template_id uuid REFERENCES notification_templates(id), - notification_provider_id uuid REFERENCES notification_providers(id), - user_id uuid REFERENCES users(id), + variable_schema jsonb DEFAULT '{}'::jsonb NOT NULL, + status text DEFAULT 'draft'::text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + system_managed boolean DEFAULT false NOT NULL, + CONSTRAINT notification_templates_status_check CHECK ((status = ANY (ARRAY['draft'::text, 'published'::text, 'archived'::text]))) +); + +CREATE TABLE public.notifications ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid, + template_id uuid, + notification_provider_id uuid, + user_id uuid, recipient text NOT NULL, - category text NOT NULL DEFAULT 'security', - locale text NOT NULL DEFAULT 'en', + category text DEFAULT 'security'::text NOT NULL, + locale text DEFAULT 'en'::text NOT NULL, payload_ciphertext text NOT NULL, - status text NOT NULL DEFAULT 'queued' CHECK (status IN ('queued','sending','delivered','failed','dead','suppressed')), - attempt_count integer NOT NULL DEFAULT 0, - next_attempt_at timestamptz NOT NULL DEFAULT now(), + status text DEFAULT 'queued'::text NOT NULL, + attempt_count integer DEFAULT 0 NOT NULL, + next_attempt_at timestamp with time zone DEFAULT now() NOT NULL, last_error text, - delivered_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now() + delivered_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + organization_id uuid, + CONSTRAINT notification_scope_check CHECK (((application_id IS NULL) OR (organization_id IS NULL))), + CONSTRAINT notifications_status_check CHECK ((status = ANY (ARRAY['queued'::text, 'sending'::text, 'delivered'::text, 'failed'::text, 'dead'::text, 'suppressed'::text]))) ); -CREATE TABLE notification_preferences ( - application_id uuid NOT NULL REFERENCES applications(id), - user_id uuid NOT NULL REFERENCES users(id), - category text NOT NULL, - email_enabled boolean NOT NULL DEFAULT true, - updated_at timestamptz NOT NULL DEFAULT now(), - PRIMARY KEY (application_id,user_id,category) +CREATE TABLE public.oauth_client_assertion_jtis ( + application_id uuid NOT NULL, + jti_digest bytea NOT NULL, + expires_at timestamp with time zone NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL ); -CREATE TABLE notification_attachments ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - notification_id uuid NOT NULL REFERENCES notifications(id) ON DELETE CASCADE, - filename text NOT NULL, - content_type text NOT NULL, - content bytea NOT NULL, - size_bytes integer NOT NULL CHECK (size_bytes>=0 AND size_bytes<=2097152), - created_at timestamptz NOT NULL DEFAULT now() +CREATE TABLE public.oauth_consents ( + application_id uuid NOT NULL, + user_id uuid NOT NULL, + client_id uuid NOT NULL, + scopes text[] DEFAULT '{}'::text[] NOT NULL, + granted_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + revoked_at timestamp with time zone ); -CREATE TABLE notification_attempts ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - notification_id uuid NOT NULL REFERENCES notifications(id) ON DELETE CASCADE, - notification_provider_id uuid REFERENCES notification_providers(id), - attempt_number integer NOT NULL, - status text NOT NULL CHECK (status IN ('sending','delivered','failed')), - error text, - started_at timestamptz NOT NULL DEFAULT now(), - completed_at timestamptz, - UNIQUE (notification_id,attempt_number) +CREATE TABLE public.oauth_sessions ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + signature_digest bytea NOT NULL, + kind text NOT NULL, + request_id text NOT NULL, + request_payload jsonb NOT NULL, + access_signature_digest bytea, + expires_at timestamp with time zone NOT NULL, + active boolean DEFAULT true NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT oauth_sessions_kind_check CHECK ((kind = ANY (ARRAY['authorize_code'::text, 'pkce'::text, 'openid'::text, 'access'::text, 'refresh'::text]))) ); -CREATE TABLE domain_events ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid REFERENCES applications(id), - event_type text NOT NULL, - schema_version text NOT NULL DEFAULT '1.0', - subject text, - actor jsonb, - correlation_id uuid, - causation_id uuid, - data jsonb NOT NULL, - occurred_at timestamptz NOT NULL DEFAULT now() +CREATE TABLE public.control_user_login_challenges ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + normalized_email text NOT NULL, + code_digest bytea, + link_digest bytea, + attempts integer DEFAULT 0 NOT NULL, + expires_at timestamp with time zone NOT NULL, + consumed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.control_user_sessions ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + control_user_id uuid NOT NULL, + refresh_digest bytea NOT NULL, + kind text DEFAULT 'control'::text NOT NULL, + ip_address inet, + user_agent text DEFAULT ''::text NOT NULL, + authenticated_at timestamp with time zone DEFAULT now() NOT NULL, + amr text[] DEFAULT '{}'::text[] NOT NULL, + last_used_at timestamp with time zone DEFAULT now() NOT NULL, + expires_at timestamp with time zone NOT NULL, + revoked_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT control_user_sessions_kind_check CHECK ((kind = ANY (ARRAY['setup'::text, 'control'::text]))) +); + +CREATE TABLE public.control_users ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + email text NOT NULL, + normalized_email text NOT NULL, + display_name text DEFAULT ''::text NOT NULL, + status text DEFAULT 'active'::text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + password_hash text, + CONSTRAINT control_users_status_check CHECK ((status = ANY (ARRAY['active'::text, 'suspended'::text, 'deleted'::text]))) +); + +CREATE TABLE public.control_user_identities ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + control_user_id uuid NOT NULL, + auth_provider_config_id uuid NOT NULL, + provider text NOT NULL, + provider_subject text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + last_used_at timestamp with time zone, + CONSTRAINT control_user_identities_provider_check CHECK ((provider = ANY (ARRAY['google'::text, 'apple'::text]))) ); -CREATE TABLE outbox ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - event_id uuid NOT NULL REFERENCES domain_events(id), - available_at timestamptz NOT NULL DEFAULT now(), - attempts integer NOT NULL DEFAULT 0, - locked_at timestamptz, +CREATE TABLE public.control_user_external_auth_challenges ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + auth_provider_config_id uuid NOT NULL, + provider text NOT NULL, + flow text NOT NULL, + requested_by_control_user_id uuid, + invitation_id uuid, + state_digest bytea NOT NULL, + nonce_digest bytea NOT NULL, + verifier_ciphertext text NOT NULL, + expires_at timestamp with time zone NOT NULL, + locked_until timestamp with time zone, + consumed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT control_user_external_auth_challenges_provider_check CHECK ((provider = ANY (ARRAY['google'::text, 'apple'::text]))), + CONSTRAINT control_user_external_auth_challenges_flow_check CHECK ((flow = ANY (ARRAY['login'::text, 'link'::text, 'invitation'::text]))), + CONSTRAINT control_user_external_auth_challenges_context_check CHECK (((flow = 'login'::text) AND (requested_by_control_user_id IS NULL) AND (invitation_id IS NULL)) OR ((flow = 'link'::text) AND (requested_by_control_user_id IS NOT NULL) AND (invitation_id IS NULL)) OR ((flow = 'invitation'::text) AND (requested_by_control_user_id IS NULL) AND (invitation_id IS NOT NULL))) +); + +CREATE TABLE public.control_user_invitations ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + organization_id uuid, + normalized_email text NOT NULL, + role text NOT NULL, + onboarding_method text DEFAULT 'email'::text NOT NULL, + credential_digest bytea NOT NULL, + invited_by uuid NOT NULL, + accepted_by uuid, + expires_at timestamp with time zone NOT NULL, + accepted_at timestamp with time zone, + revoked_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT control_user_invitations_method_check CHECK ((onboarding_method = ANY (ARRAY['email'::text, 'google'::text, 'apple'::text]))), + CONSTRAINT control_user_invitations_role_check CHECK (((organization_id IS NULL) AND (role = ANY (ARRAY['owner'::text, 'admin'::text, 'auditor'::text]))) OR ((organization_id IS NOT NULL) AND (role = ANY (ARRAY['owner'::text, 'admin'::text, 'member'::text, 'auditor'::text])))) +); + +CREATE TABLE public.organization_memberships ( + organization_id uuid NOT NULL, + control_user_id uuid NOT NULL, + role text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT organization_memberships_role_check CHECK ((role = ANY (ARRAY['owner'::text, 'admin'::text, 'member'::text, 'auditor'::text]))) +); + +CREATE TABLE public.organization_policies ( + organization_id uuid NOT NULL, + max_applications integer, + max_users integer, + enabled_settings jsonb DEFAULT '{"webhooks": true, "delegation": true, "custom_events": true, "personal_api_keys": true, "public_registration": true, "password_authentication": true, "passwordless_authentication": true, "application_provider_overrides": true, "organization_provider_overrides": true}'::jsonb NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT organization_policies_enabled_settings_check CHECK ((jsonb_typeof(enabled_settings) = 'object'::text)), + CONSTRAINT organization_policies_max_applications_check CHECK (((max_applications IS NULL) OR (max_applications >= 0))), + CONSTRAINT organization_policies_max_users_check CHECK (((max_users IS NULL) OR (max_users >= 0))) +); + +CREATE TABLE public.organizations ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + name text NOT NULL, + slug text NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + deleted_at timestamp with time zone +); + +CREATE TABLE public.outbox ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + event_id uuid NOT NULL, + available_at timestamp with time zone DEFAULT now() NOT NULL, + attempts integer DEFAULT 0 NOT NULL, + locked_at timestamp with time zone, locked_by text, - dispatched_at timestamptz, + dispatched_at timestamp with time zone, last_error text ); -CREATE TABLE webhook_endpoints ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - uri text NOT NULL, - event_filters text[] NOT NULL DEFAULT '{}', - secret_ciphertext text NOT NULL, - previous_secret_ciphertext text, - previous_valid_until timestamptz, - disabled_at timestamptz, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE webhook_deliveries ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - application_id uuid NOT NULL REFERENCES applications(id), - webhook_endpoint_id uuid NOT NULL REFERENCES webhook_endpoints(id), - event_id uuid NOT NULL REFERENCES domain_events(id), - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','delivering','delivered','failed','dead')), - attempt_count integer NOT NULL DEFAULT 0, - next_attempt_at timestamptz NOT NULL DEFAULT now(), - response_status integer, - response_excerpt text, - delivered_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (webhook_endpoint_id, event_id) +CREATE TABLE public.payments ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, + provider_payment_id text NOT NULL, + provider_customer_id text, + provider_invoice_id text, + billing_customer_id uuid, + checkout_session_id uuid, + invoice_id uuid, + status text NOT NULL, + amount_minor bigint DEFAULT 0 NOT NULL, + amount_received_minor bigint DEFAULT 0 NOT NULL, + currency character(3) NOT NULL, + payment_method_type text, + failure_code text, + failure_message text, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + external_reference text ); -CREATE TABLE audit_records ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - organization_id uuid REFERENCES organizations(id), - application_id uuid REFERENCES applications(id), - actor_type text NOT NULL, - actor_id uuid, - action text NOT NULL, - target_type text, - target_id uuid, - reason text, - request_id text, - changes jsonb NOT NULL DEFAULT '{}', - created_at timestamptz NOT NULL DEFAULT now() +CREATE TABLE public.personal_api_keys ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + label text, + token_prefix text NOT NULL, + token_digest bytea NOT NULL, + scopes text[] DEFAULT '{}'::text[] NOT NULL, + expires_at timestamp with time zone NOT NULL, + last_used_at timestamp with time zone, + revoked_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT personal_api_keys_scopes_format_check CHECK (public.valid_canonical_scopes(application_id,scopes,true)) +); + +CREATE TABLE public.price_features ( + price_id uuid NOT NULL, + feature_id uuid NOT NULL, + boolean_value boolean, + quantity_value bigint, + free_form_value jsonb ); -CREATE TABLE audit_exports ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - organization_id uuid REFERENCES organizations(id), - application_id uuid REFERENCES applications(id), - requested_by uuid NOT NULL REFERENCES operators(id), - filter_snapshot jsonb NOT NULL DEFAULT '{}', - payload_ciphertext text NOT NULL, - record_count integer NOT NULL, - expires_at timestamptz NOT NULL, - created_at timestamptz NOT NULL DEFAULT now() +CREATE TABLE public.prices ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + product_id uuid NOT NULL, + key text NOT NULL, + mode text NOT NULL, + amount_minor bigint NOT NULL, + currency character(3) NOT NULL, + currency_exponent smallint DEFAULT 2 NOT NULL, + interval_unit text, + interval_count integer, + validity_seconds bigint, + grace_seconds bigint DEFAULT 0 NOT NULL, + tax_behavior text DEFAULT 'inclusive'::text NOT NULL, + checkout_config jsonb DEFAULT '{}'::jsonb NOT NULL, + entitlement_config jsonb DEFAULT '{}'::jsonb NOT NULL, + active boolean DEFAULT true NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT prices_amount_minor_check CHECK ((amount_minor >= 0)), + CONSTRAINT prices_interval_unit_check CHECK ((interval_unit = ANY (ARRAY['day'::text, 'week'::text, 'month'::text, 'year'::text]))), + CONSTRAINT prices_mode_check CHECK ((mode = ANY (ARRAY['recurring'::text, 'one_time'::text, 'local'::text]))), + CONSTRAINT prices_tax_behavior_check CHECK ((tax_behavior = ANY (ARRAY['inclusive'::text, 'exclusive'::text, 'unspecified'::text]))) +); + +CREATE TABLE public.product_features ( + product_id uuid NOT NULL, + feature_id uuid NOT NULL, + boolean_value boolean, + quantity_value bigint, + free_form_value jsonb ); -CREATE INDEX audit_exports_expiry ON audit_exports(expires_at); -CREATE TABLE idempotency_records ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), +CREATE TABLE public.products ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + key text NOT NULL, + name text NOT NULL, + description text DEFAULT ''::text NOT NULL, + listable boolean DEFAULT true NOT NULL, + status text DEFAULT 'active'::text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + entitlement_config jsonb DEFAULT '{}'::jsonb NOT NULL, + CONSTRAINT products_status_check CHECK ((status = ANY (ARRAY['draft'::text, 'active'::text, 'archived'::text]))) +); + +CREATE TABLE public.provider_connections ( + id uuid DEFAULT gen_random_uuid() NOT NULL, application_id uuid, - actor_key text NOT NULL, - idempotency_key text NOT NULL, - request_hash bytea NOT NULL, - response_status integer, - response_headers jsonb, - response_body bytea, - locked_until timestamptz, - expires_at timestamptz NOT NULL, - created_at timestamptz NOT NULL DEFAULT now(), - UNIQUE NULLS NOT DISTINCT (application_id, actor_key, idempotency_key) -); - --- Composite keys make application ownership part of every critical reference. -CREATE UNIQUE INDEX clients_application_identity ON clients(application_id,id); -CREATE UNIQUE INDEX billing_profiles_application_identity ON billing_profiles(application_id,id); -CREATE UNIQUE INDEX roles_application_identity ON roles(application_id,id); -CREATE UNIQUE INDEX products_application_identity ON products(application_id,id); -CREATE UNIQUE INDEX prices_application_identity ON prices(application_id,id); -CREATE UNIQUE INDEX provider_connections_application_identity ON provider_connections(application_id,id); -CREATE UNIQUE INDEX billing_customers_application_identity ON billing_customers(application_id,id); -CREATE UNIQUE INDEX checkout_sessions_application_identity ON checkout_sessions(application_id,id); -CREATE UNIQUE INDEX subscriptions_application_identity ON subscriptions(application_id,id); -CREATE UNIQUE INDEX invoices_application_identity ON invoices(application_id,id); -CREATE UNIQUE INDEX payments_application_identity ON payments(application_id,id); - -ALTER TABLE role_assignments - ADD CONSTRAINT role_assignments_user_application_fk FOREIGN KEY(application_id,user_id) REFERENCES users(application_id,id), - ADD CONSTRAINT role_assignments_client_application_fk FOREIGN KEY(application_id,client_id) REFERENCES clients(application_id,id), - ADD CONSTRAINT role_assignments_role_application_fk FOREIGN KEY(application_id,role_id) REFERENCES roles(application_id,id), - ADD CONSTRAINT role_assignments_workspace_application_fk FOREIGN KEY(application_id,workspace_id) REFERENCES workspaces(application_id,id); -ALTER TABLE addresses ADD CONSTRAINT addresses_profile_application_fk - FOREIGN KEY(application_id,billing_profile_id) REFERENCES billing_profiles(application_id,id); -ALTER TABLE prices ADD CONSTRAINT prices_product_application_fk - FOREIGN KEY(application_id,product_id) REFERENCES products(application_id,id); -ALTER TABLE entitlement_grants - ADD CONSTRAINT entitlement_product_application_fk FOREIGN KEY(application_id,product_id) REFERENCES products(application_id,id), - ADD CONSTRAINT entitlement_price_application_fk FOREIGN KEY(application_id,price_id) REFERENCES prices(application_id,id); -ALTER TABLE local_entitlement_requests - ADD CONSTRAINT local_request_user_application_fk FOREIGN KEY(application_id,requester_user_id) REFERENCES users(application_id,id), - ADD CONSTRAINT local_request_product_application_fk FOREIGN KEY(application_id,product_id) REFERENCES products(application_id,id), - ADD CONSTRAINT local_request_price_application_fk FOREIGN KEY(application_id,price_id) REFERENCES prices(application_id,id); -ALTER TABLE billing_customers ADD CONSTRAINT billing_customer_provider_application_fk - FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE checkout_sessions - ADD CONSTRAINT checkout_price_application_fk FOREIGN KEY(application_id,price_id) REFERENCES prices(application_id,id), - ADD CONSTRAINT checkout_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE subscriptions - ADD CONSTRAINT subscription_price_application_fk FOREIGN KEY(application_id,price_id) REFERENCES prices(application_id,id), - ADD CONSTRAINT subscription_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE invoices - ADD CONSTRAINT invoice_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id), - ADD CONSTRAINT invoice_customer_application_fk FOREIGN KEY(application_id,billing_customer_id) REFERENCES billing_customers(application_id,id), - ADD CONSTRAINT invoice_subscription_application_fk FOREIGN KEY(application_id,subscription_id) REFERENCES subscriptions(application_id,id); -ALTER TABLE payments - ADD CONSTRAINT payment_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id), - ADD CONSTRAINT payment_customer_application_fk FOREIGN KEY(application_id,billing_customer_id) REFERENCES billing_customers(application_id,id), - ADD CONSTRAINT payment_checkout_application_fk FOREIGN KEY(application_id,checkout_session_id) REFERENCES checkout_sessions(application_id,id), - ADD CONSTRAINT payment_invoice_application_fk FOREIGN KEY(application_id,invoice_id) REFERENCES invoices(application_id,id); -ALTER TABLE refunds - ADD CONSTRAINT refund_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id), - ADD CONSTRAINT refund_payment_application_fk FOREIGN KEY(application_id,payment_id) REFERENCES payments(application_id,id); -ALTER TABLE disputes - ADD CONSTRAINT dispute_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id), - ADD CONSTRAINT dispute_payment_application_fk FOREIGN KEY(application_id,payment_id) REFERENCES payments(application_id,id); -ALTER TABLE reconciliation_runs ADD CONSTRAINT reconciliation_provider_application_fk - FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE provider_events ADD CONSTRAINT provider_event_connection_application_fk - FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); + provider text NOT NULL, + public_id text NOT NULL, + api_version text NOT NULL, + secret_ciphertext text NOT NULL, + webhook_secret_ciphertext text, + status text DEFAULT 'active'::text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + organization_id uuid, + inheritable boolean DEFAULT false NOT NULL, + CONSTRAINT billing_provider_scope_check CHECK ((((application_id IS NOT NULL) AND (organization_id IS NULL)) OR ((application_id IS NULL) AND (organization_id IS NOT NULL)) OR ((application_id IS NULL) AND (organization_id IS NULL)))), + CONSTRAINT provider_connections_status_check CHECK ((status = ANY (ARRAY['active'::text, 'disabled'::text, 'error'::text]))) +); + +CREATE TABLE public.provider_events ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, + provider_event_id text NOT NULL, + api_version text, + event_type text NOT NULL, + raw_body_ciphertext text NOT NULL, + status text DEFAULT 'pending'::text NOT NULL, + attempts integer DEFAULT 0 NOT NULL, + last_error text, + received_at timestamp with time zone DEFAULT now() NOT NULL, + processed_at timestamp with time zone, + CONSTRAINT provider_events_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'processed'::text, 'failed'::text, 'ignored'::text]))) +); --- +goose StatementBegin -CREATE FUNCTION enforce_application_subject() RETURNS trigger LANGUAGE plpgsql AS $$ -BEGIN - IF NEW.subject_type='user' AND NOT EXISTS ( - SELECT 1 FROM users u WHERE u.application_id=NEW.application_id AND u.id=NEW.subject_id - ) THEN - RAISE EXCEPTION 'user subject must belong to the row application'; - ELSIF NEW.subject_type='workspace' AND NOT EXISTS ( - SELECT 1 FROM workspaces w WHERE w.application_id=NEW.application_id AND w.id=NEW.subject_id - ) THEN - RAISE EXCEPTION 'workspace subject must belong to the row application'; - END IF; - RETURN NEW; -END; -$$; +CREATE TABLE public.provider_mappings ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, + object_type text NOT NULL, + internal_id uuid NOT NULL, + provider_id text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT provider_mappings_object_type_check CHECK ((object_type = ANY (ARRAY['product'::text, 'price'::text]))) +); + +CREATE TABLE public.reconciliation_runs ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, + status text NOT NULL, + findings jsonb DEFAULT '[]'::jsonb NOT NULL, + repairs jsonb DEFAULT '[]'::jsonb NOT NULL, + last_error text, + started_at timestamp with time zone, + completed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT reconciliation_runs_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'running'::text, 'completed'::text, 'failed'::text]))) +); + +CREATE TABLE public.refunds ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, + provider_payment_id text, + payment_id uuid, + provider_refund_id text NOT NULL, + status text NOT NULL, + amount_minor bigint NOT NULL, + currency character(3) NOT NULL, + reason text, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.role_assignments ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid, + client_id uuid, + role_id uuid NOT NULL, + workspace_id uuid, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT role_assignments_check CHECK (((user_id IS NOT NULL) <> (client_id IS NOT NULL))) +); + +CREATE TABLE public.permission_grants ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid, + client_id uuid, + workspace_id uuid, + permission text NOT NULL, + canonical_scope text NOT NULL, + reason text DEFAULT ''::text NOT NULL, + created_by_type text NOT NULL, + created_by_id uuid NOT NULL, + revoked_by_type text, + revoked_by_id uuid, + revoked_reason text, + revoked_at timestamp with time zone, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT permission_grants_subject_check CHECK (((user_id IS NOT NULL) <> (client_id IS NOT NULL))), + CONSTRAINT permission_grants_actor_type_check CHECK ((created_by_type = ANY (ARRAY['control_user'::text, 'user'::text, 'client'::text]))), + CONSTRAINT permission_grants_revocation_check CHECK (((revoked_at IS NULL) = (revoked_by_type IS NULL)) AND ((revoked_at IS NULL) = (revoked_by_id IS NULL)) AND (revoked_by_type IS NULL OR revoked_by_type = ANY (ARRAY['control_user'::text, 'user'::text, 'client'::text]))) +); + +CREATE TABLE public.roles ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + key text NOT NULL, + name text NOT NULL, + scope text NOT NULL, + permissions text[] DEFAULT '{}'::text[] NOT NULL, + built_in boolean DEFAULT false NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT roles_scope_check CHECK ((scope = ANY (ARRAY['application'::text, 'workspace'::text]))), + CONSTRAINT roles_key_format_check CHECK ((key ~ '^[a-z][a-z0-9_-]{0,62}$'::text)), + CONSTRAINT roles_permissions_format_check CHECK (public.valid_permission_keys(permissions)) +); + +CREATE TABLE public.sender_identities ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid, + notification_provider_id uuid NOT NULL, + email text NOT NULL, + name text DEFAULT ''::text NOT NULL, + is_default boolean DEFAULT false NOT NULL, + verified_at timestamp with time zone, + disabled_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + organization_id uuid +); + +CREATE TABLE public.signing_keys ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + kid text NOT NULL, + public_jwk jsonb NOT NULL, + private_key_ciphertext text NOT NULL, + status text NOT NULL, + activates_at timestamp with time zone, + retires_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT signing_keys_status_check CHECK ((status = ANY (ARRAY['prepared'::text, 'active'::text, 'retiring'::text, 'retired'::text]))) +); + +CREATE TABLE public.storage_objects ( + id uuid NOT NULL, + application_id uuid, + storage_provider_id uuid NOT NULL, + owner_type text NOT NULL, + owner_id uuid, + visibility text NOT NULL, + bucket_role text NOT NULL, + bucket_name text NOT NULL, + object_key text NOT NULL, + filename text NOT NULL, + content_type text NOT NULL, + size_bytes bigint NOT NULL, + etag text, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + status text DEFAULT 'pending'::text NOT NULL, + upload_expires_at timestamp with time zone, + ready_at timestamp with time zone, + deleted_at timestamp with time zone, + last_error text, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT storage_objects_bucket_role_check CHECK ((bucket_role = ANY (ARRAY['public'::text, 'private'::text]))), + CONSTRAINT storage_objects_check CHECK ((((owner_type = 'installation'::text) AND (application_id IS NULL) AND (owner_id IS NULL)) OR ((owner_type = 'application'::text) AND (application_id IS NOT NULL) AND (owner_id IS NULL)) OR ((owner_type = ANY (ARRAY['user'::text, 'workspace'::text])) AND (application_id IS NOT NULL) AND (owner_id IS NOT NULL)))), + CONSTRAINT storage_objects_check1 CHECK ((visibility = bucket_role)), + CONSTRAINT storage_objects_check2 CHECK ((((status = 'pending'::text) AND (upload_expires_at IS NOT NULL)) OR (status <> 'pending'::text))), + CONSTRAINT storage_objects_content_type_check CHECK (((content_type <> ''::text) AND (length(content_type) <= 255))), + CONSTRAINT storage_objects_filename_check CHECK (((filename <> ''::text) AND (length(filename) <= 500))), + CONSTRAINT storage_objects_object_key_check CHECK (((object_key <> ''::text) AND (length(object_key) <= 1024))), + CONSTRAINT storage_objects_owner_type_check CHECK ((owner_type = ANY (ARRAY['installation'::text, 'application'::text, 'user'::text, 'workspace'::text]))), + CONSTRAINT storage_objects_size_bytes_check CHECK ((size_bytes > 0)), + CONSTRAINT storage_objects_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'ready'::text, 'deleting'::text, 'deleted'::text, 'failed'::text]))), + CONSTRAINT storage_objects_visibility_check CHECK ((visibility = ANY (ARRAY['public'::text, 'private'::text]))) +); + +CREATE TABLE public.storage_providers ( + id uuid NOT NULL, + organization_id uuid, + application_id uuid, + provider text DEFAULT 's3'::text NOT NULL, + name text NOT NULL, + endpoint text NOT NULL, + region text NOT NULL, + force_path_style boolean DEFAULT false NOT NULL, + public_bucket text, + private_bucket text, + public_base_url text, + credentials_ciphertext text NOT NULL, + inheritable boolean DEFAULT false NOT NULL, + allow_private_endpoint boolean DEFAULT false NOT NULL, + max_object_bytes bigint DEFAULT 26214400 NOT NULL, + max_email_image_bytes bigint DEFAULT 2097152 NOT NULL, + max_application_bytes bigint DEFAULT '10737418240'::bigint NOT NULL, + max_application_objects bigint DEFAULT 100000 NOT NULL, + status text DEFAULT 'unverified'::text NOT NULL, + verified_at timestamp with time zone, + disabled_at timestamp with time zone, + last_error text, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT storage_providers_check CHECK ((max_application_bytes >= max_object_bytes)), + CONSTRAINT storage_providers_check1 CHECK ((((application_id IS NOT NULL) AND (organization_id IS NULL)) OR ((application_id IS NULL) AND (organization_id IS NOT NULL)) OR ((application_id IS NULL) AND (organization_id IS NULL)))), + CONSTRAINT storage_providers_check2 CHECK (((public_bucket IS NOT NULL) OR (private_bucket IS NOT NULL))), + CONSTRAINT storage_providers_check3 CHECK (((public_bucket IS NULL) OR (private_bucket IS NULL) OR (public_bucket <> private_bucket))), + CONSTRAINT storage_providers_check4 CHECK (((application_id IS NULL) OR (inheritable = false))), + CONSTRAINT storage_providers_check5 CHECK (((allow_private_endpoint = false) OR ((application_id IS NULL) AND (organization_id IS NULL)))), + CONSTRAINT storage_providers_endpoint_check CHECK (((endpoint <> ''::text) AND (length(endpoint) <= 2000))), + CONSTRAINT storage_providers_max_application_objects_check CHECK (((max_application_objects >= 1) AND (max_application_objects <= 100000000))), + CONSTRAINT storage_providers_max_email_image_bytes_check CHECK (((max_email_image_bytes >= 1) AND (max_email_image_bytes <= 26214400))), + CONSTRAINT storage_providers_max_object_bytes_check CHECK (((max_object_bytes >= 1) AND (max_object_bytes <= '5368709120'::bigint))), + CONSTRAINT storage_providers_name_check CHECK (((name <> ''::text) AND (length(name) <= 200))), + CONSTRAINT storage_providers_provider_check CHECK ((provider = 's3'::text)), + CONSTRAINT storage_providers_region_check CHECK (((region <> ''::text) AND (length(region) <= 100))), + CONSTRAINT storage_providers_status_check CHECK ((status = ANY (ARRAY['unverified'::text, 'active'::text, 'error'::text, 'disabled'::text]))) +); + +CREATE TABLE public.subscriptions ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + subject_type text NOT NULL, + subject_id uuid NOT NULL, + price_id uuid NOT NULL, + provider_connection_id uuid NOT NULL, + provider_subscription_id text NOT NULL, + provider_item_id text, + status text NOT NULL, + current_period_start timestamp with time zone, + current_period_end timestamp with time zone, + cancel_at timestamp with time zone, + canceled_at timestamp with time zone, + trial_end timestamp with time zone, + cancel_at_period_end boolean DEFAULT false NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + external_reference text +); + +CREATE TABLE public.user_authentication_methods ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + method_type text NOT NULL, + label text DEFAULT ''::text NOT NULL, + secret_ciphertext text, + credential_id bytea, + credential_ciphertext text, + webauthn_rp_id text, + status text DEFAULT 'pending'::text NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + activated_at timestamp with time zone, + last_used_at timestamp with time zone, + disabled_at timestamp with time zone, + CONSTRAINT user_authentication_methods_method_type_check CHECK ((method_type = ANY (ARRAY['totp'::text, 'webauthn'::text]))), + CONSTRAINT user_authentication_methods_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'active'::text, 'disabled'::text]))) +); + +CREATE TABLE public.user_identities ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + provider text NOT NULL, + provider_subject text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.user_recovery_codes ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + code_digest bytea NOT NULL, + used_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.user_sessions ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + delegation_id uuid, + refresh_digest bytea NOT NULL, + previous_refresh_digest bytea, + previous_valid_until timestamp with time zone, + user_agent text, + ip_hash bytea, + authenticated_at timestamp with time zone DEFAULT now() NOT NULL, + mfa_authenticated_at timestamp with time zone, + amr text[] DEFAULT '{}'::text[] NOT NULL, + expires_at timestamp with time zone NOT NULL, + revoked_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + last_used_at timestamp with time zone +); + +CREATE TABLE public.users ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + email text NOT NULL, + normalized_email text NOT NULL, + first_name text DEFAULT ''::text NOT NULL, + last_name text DEFAULT ''::text NOT NULL, + username text, + password_hash text, + email_verified_at timestamp with time zone, + is_org_verified boolean DEFAULT false NOT NULL, + status text DEFAULT 'active'::text NOT NULL, + custom_attributes jsonb DEFAULT '{}'::jsonb NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + deleted_at timestamp with time zone, + locale text DEFAULT ''::text NOT NULL, + CONSTRAINT users_locale_length CHECK ((length(locale) <= 35)), + CONSTRAINT users_status_check CHECK ((status = ANY (ARRAY['active'::text, 'suspended'::text, 'pending_deletion'::text, 'anonymized'::text, 'deleted'::text]))) +); + +CREATE TABLE public.webauthn_ceremonies ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + user_id uuid NOT NULL, + user_session_id uuid, + mfa_challenge_id uuid, + intent text NOT NULL, + origin text NOT NULL, + label text DEFAULT ''::text NOT NULL, + session_ciphertext text NOT NULL, + expires_at timestamp with time zone NOT NULL, + consumed_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT webauthn_ceremonies_intent_check CHECK ((intent = ANY (ARRAY['register'::text, 'authenticate'::text]))) +); + +CREATE TABLE public.webhook_deliveries ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + webhook_endpoint_id uuid NOT NULL, + event_id uuid NOT NULL, + status text DEFAULT 'pending'::text NOT NULL, + attempt_count integer DEFAULT 0 NOT NULL, + next_attempt_at timestamp with time zone DEFAULT now() NOT NULL, + response_status integer, + response_excerpt text, + delivered_at timestamp with time zone, + created_at timestamp with time zone DEFAULT now() NOT NULL, + CONSTRAINT webhook_deliveries_status_check CHECK ((status = ANY (ARRAY['pending'::text, 'delivering'::text, 'delivered'::text, 'failed'::text, 'dead'::text]))) +); + +CREATE TABLE public.webhook_endpoints ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + uri text NOT NULL, + event_filters text[] DEFAULT '{}'::text[] NOT NULL, + secret_ciphertext text NOT NULL, + previous_secret_ciphertext text, + previous_valid_until timestamp with time zone, + disabled_at timestamp with time zone, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.workspace_memberships ( + application_id uuid NOT NULL, + workspace_id uuid NOT NULL, + user_id uuid NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL +); + +CREATE TABLE public.workspaces ( + id uuid DEFAULT gen_random_uuid() NOT NULL, + application_id uuid NOT NULL, + owner_user_id uuid NOT NULL, + key text NOT NULL, + name text NOT NULL, + metadata jsonb DEFAULT '{}'::jsonb NOT NULL, + version bigint DEFAULT 1 NOT NULL, + created_at timestamp with time zone DEFAULT now() NOT NULL, + updated_at timestamp with time zone DEFAULT now() NOT NULL, + deleted_at timestamp with time zone +); + +ALTER TABLE ONLY public.addresses + ADD CONSTRAINT addresses_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.application_domains + ADD CONSTRAINT application_domains_application_id_hostname_key UNIQUE (application_id, hostname); + +ALTER TABLE ONLY public.application_domains + ADD CONSTRAINT application_domains_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.application_secrets + ADD CONSTRAINT application_secrets_application_id_kind_name_key UNIQUE (application_id, kind, name); + +ALTER TABLE ONLY public.application_secrets + ADD CONSTRAINT application_secrets_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.applications + ADD CONSTRAINT applications_organization_id_slug_key UNIQUE (organization_id, slug); + +ALTER TABLE ONLY public.applications + ADD CONSTRAINT applications_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.audit_exports + ADD CONSTRAINT audit_exports_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.audit_records + ADD CONSTRAINT audit_records_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.auth_provider_configs + ADD CONSTRAINT auth_provider_configs_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.auth_rate_limits + ADD CONSTRAINT auth_rate_limits_pkey PRIMARY KEY (bucket_digest); + +ALTER TABLE ONLY public.billing_customers + ADD CONSTRAINT billing_customers_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.billing_customers + ADD CONSTRAINT billing_customers_provider_connection_id_subject_type_subje_key UNIQUE (provider_connection_id, subject_type, subject_id); + +ALTER TABLE ONLY public.billing_profiles + ADD CONSTRAINT billing_profiles_application_id_subject_type_subject_id_key UNIQUE (application_id, subject_type, subject_id); + +ALTER TABLE ONLY public.billing_profiles + ADD CONSTRAINT billing_profiles_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.checkout_sessions + ADD CONSTRAINT checkout_sessions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.clients + ADD CONSTRAINT clients_client_id_key UNIQUE (client_id); + +ALTER TABLE ONLY public.clients + ADD CONSTRAINT clients_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.delegations + ADD CONSTRAINT delegations_exchange_digest_key UNIQUE (exchange_digest); + +ALTER TABLE ONLY public.delegations + ADD CONSTRAINT delegations_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.disputes + ADD CONSTRAINT disputes_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.disputes + ADD CONSTRAINT disputes_provider_connection_id_provider_dispute_id_key UNIQUE (provider_connection_id, provider_dispute_id); + +ALTER TABLE ONLY public.domain_events + ADD CONSTRAINT domain_events_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.entitlement_grant_actions + ADD CONSTRAINT entitlement_grant_actions_grant_id_action_key_key UNIQUE (grant_id, action_key); + +ALTER TABLE ONLY public.entitlement_grant_actions + ADD CONSTRAINT entitlement_grant_actions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.entitlement_grants + ADD CONSTRAINT entitlement_grants_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.event_type_definitions + ADD CONSTRAINT event_type_definitions_application_id_name_key UNIQUE NULLS NOT DISTINCT (application_id, name); + +ALTER TABLE ONLY public.event_type_definitions + ADD CONSTRAINT event_type_definitions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.external_auth_challenges + ADD CONSTRAINT external_auth_challenges_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.external_auth_challenges + ADD CONSTRAINT external_auth_challenges_state_digest_key UNIQUE (state_digest); + +ALTER TABLE ONLY public.external_auth_exchanges + ADD CONSTRAINT external_auth_exchanges_credential_digest_key UNIQUE (credential_digest); + +ALTER TABLE ONLY public.external_auth_exchanges + ADD CONSTRAINT external_auth_exchanges_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.features + ADD CONSTRAINT features_application_id_key_key UNIQUE (application_id, key); + +ALTER TABLE ONLY public.features + ADD CONSTRAINT features_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.idempotency_records + ADD CONSTRAINT idempotency_records_application_id_actor_key_idempotency_ke_key UNIQUE NULLS NOT DISTINCT (application_id, actor_key, idempotency_key); + +ALTER TABLE ONLY public.idempotency_records + ADD CONSTRAINT idempotency_records_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.installation_control_user_roles + ADD CONSTRAINT installation_control_user_roles_pkey PRIMARY KEY (control_user_id); + +ALTER TABLE ONLY public.installations + ADD CONSTRAINT installations_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.invitation_authorization_codes + ADD CONSTRAINT invitation_authorization_codes_code_digest_key UNIQUE (code_digest); + +ALTER TABLE ONLY public.invitation_authorization_codes + ADD CONSTRAINT invitation_authorization_codes_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoices_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoices_provider_connection_id_provider_invoice_id_key UNIQUE (provider_connection_id, provider_invoice_id); + +ALTER TABLE ONLY public.local_entitlement_request_actions + ADD CONSTRAINT local_entitlement_request_actions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_entitlement_requests_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.login_challenges + ADD CONSTRAINT login_challenges_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.management_clients + ADD CONSTRAINT management_clients_client_id_key UNIQUE (client_id); + +ALTER TABLE ONLY public.management_clients + ADD CONSTRAINT management_clients_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.mfa_login_challenges + ADD CONSTRAINT mfa_login_challenges_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.notification_attachments + ADD CONSTRAINT notification_attachments_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.notification_attempts + ADD CONSTRAINT notification_attempts_notification_id_attempt_number_key UNIQUE (notification_id, attempt_number); + +ALTER TABLE ONLY public.notification_attempts + ADD CONSTRAINT notification_attempts_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.notification_preferences + ADD CONSTRAINT notification_preferences_pkey PRIMARY KEY (application_id, user_id, category); + +ALTER TABLE ONLY public.notification_providers + ADD CONSTRAINT notification_providers_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.notification_template_assets + ADD CONSTRAINT notification_template_assets_pkey PRIMARY KEY (notification_template_id, storage_object_id); + +ALTER TABLE ONLY public.notification_templates + ADD CONSTRAINT notification_templates_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.notifications + ADD CONSTRAINT notifications_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.oauth_client_assertion_jtis + ADD CONSTRAINT oauth_client_assertion_jtis_pkey PRIMARY KEY (application_id, jti_digest); + +ALTER TABLE ONLY public.oauth_consents + ADD CONSTRAINT oauth_consents_pkey PRIMARY KEY (application_id, user_id, client_id); + +ALTER TABLE ONLY public.oauth_sessions + ADD CONSTRAINT oauth_sessions_application_id_kind_signature_digest_key UNIQUE (application_id, kind, signature_digest); + +ALTER TABLE ONLY public.oauth_sessions + ADD CONSTRAINT oauth_sessions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.control_user_login_challenges + ADD CONSTRAINT control_user_login_challenges_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.control_user_external_auth_challenges + ADD CONSTRAINT control_user_external_auth_challenges_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.control_user_external_auth_challenges + ADD CONSTRAINT control_user_external_auth_challenges_state_digest_key UNIQUE (state_digest); + +ALTER TABLE ONLY public.control_user_identities + ADD CONSTRAINT control_user_identities_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.control_user_invitations + ADD CONSTRAINT control_user_invitations_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.control_user_sessions + ADD CONSTRAINT control_user_sessions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.control_user_sessions + ADD CONSTRAINT control_user_sessions_refresh_digest_key UNIQUE (refresh_digest); + +ALTER TABLE ONLY public.control_users + ADD CONSTRAINT control_users_normalized_email_key UNIQUE (normalized_email); + +ALTER TABLE ONLY public.control_users + ADD CONSTRAINT control_users_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.organization_memberships + ADD CONSTRAINT organization_memberships_pkey PRIMARY KEY (organization_id, control_user_id); + +ALTER TABLE ONLY public.organization_policies + ADD CONSTRAINT organization_policies_pkey PRIMARY KEY (organization_id); + +ALTER TABLE ONLY public.organizations + ADD CONSTRAINT organizations_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.organizations + ADD CONSTRAINT organizations_slug_key UNIQUE (slug); + +ALTER TABLE ONLY public.outbox + ADD CONSTRAINT outbox_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payments_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payments_provider_connection_id_provider_payment_id_key UNIQUE (provider_connection_id, provider_payment_id); + +ALTER TABLE ONLY public.personal_api_keys + ADD CONSTRAINT personal_api_keys_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.personal_api_keys + ADD CONSTRAINT personal_api_keys_token_digest_key UNIQUE (token_digest); + +ALTER TABLE ONLY public.permission_grants + ADD CONSTRAINT permission_grants_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.price_features + ADD CONSTRAINT price_features_pkey PRIMARY KEY (price_id, feature_id); + +ALTER TABLE ONLY public.prices + ADD CONSTRAINT prices_application_id_key_key UNIQUE (application_id, key); + +ALTER TABLE ONLY public.prices + ADD CONSTRAINT prices_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.product_features + ADD CONSTRAINT product_features_pkey PRIMARY KEY (product_id, feature_id); + +ALTER TABLE ONLY public.products + ADD CONSTRAINT products_application_id_key_key UNIQUE (application_id, key); + +ALTER TABLE ONLY public.products + ADD CONSTRAINT products_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.provider_connections + ADD CONSTRAINT provider_connections_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.provider_connections + ADD CONSTRAINT provider_connections_public_id_key UNIQUE (public_id); + +ALTER TABLE ONLY public.provider_events + ADD CONSTRAINT provider_events_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.provider_events + ADD CONSTRAINT provider_events_provider_connection_id_provider_event_id_key UNIQUE (provider_connection_id, provider_event_id); + +ALTER TABLE ONLY public.provider_mappings + ADD CONSTRAINT provider_mappings_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.provider_mappings + ADD CONSTRAINT provider_mappings_provider_connection_id_object_type_intern_key UNIQUE (provider_connection_id, object_type, internal_id); + +ALTER TABLE ONLY public.provider_mappings + ADD CONSTRAINT provider_mappings_provider_connection_id_object_type_provid_key UNIQUE (provider_connection_id, object_type, provider_id); + +ALTER TABLE ONLY public.reconciliation_runs + ADD CONSTRAINT reconciliation_runs_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.refunds + ADD CONSTRAINT refunds_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.refunds + ADD CONSTRAINT refunds_provider_connection_id_provider_refund_id_key UNIQUE (provider_connection_id, provider_refund_id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.roles + ADD CONSTRAINT roles_application_id_key_key UNIQUE (application_id, key); + +ALTER TABLE ONLY public.roles + ADD CONSTRAINT roles_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.sender_identities + ADD CONSTRAINT sender_identities_notification_provider_id_email_key UNIQUE (notification_provider_id, email); + +ALTER TABLE ONLY public.sender_identities + ADD CONSTRAINT sender_identities_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.signing_keys + ADD CONSTRAINT signing_keys_kid_key UNIQUE (kid); + +ALTER TABLE ONLY public.signing_keys + ADD CONSTRAINT signing_keys_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.storage_objects + ADD CONSTRAINT storage_objects_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.storage_objects + ADD CONSTRAINT storage_objects_storage_provider_id_bucket_name_object_key_key UNIQUE (storage_provider_id, bucket_name, object_key); + +ALTER TABLE ONLY public.storage_providers + ADD CONSTRAINT storage_providers_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.subscriptions + ADD CONSTRAINT subscriptions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.subscriptions + ADD CONSTRAINT subscriptions_provider_connection_id_provider_subscription__key UNIQUE (provider_connection_id, provider_subscription_id); + +ALTER TABLE ONLY public.user_authentication_methods + ADD CONSTRAINT user_authentication_methods_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.user_identities + ADD CONSTRAINT user_identities_application_id_provider_provider_subject_key UNIQUE (application_id, provider, provider_subject); + +ALTER TABLE ONLY public.user_identities + ADD CONSTRAINT user_identities_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.user_recovery_codes + ADD CONSTRAINT user_recovery_codes_application_id_code_digest_key UNIQUE (application_id, code_digest); + +ALTER TABLE ONLY public.user_recovery_codes + ADD CONSTRAINT user_recovery_codes_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.user_sessions + ADD CONSTRAINT user_sessions_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.user_sessions + ADD CONSTRAINT user_sessions_refresh_digest_key UNIQUE (refresh_digest); + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_application_id_normalized_email_key UNIQUE (application_id, normalized_email); + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.webauthn_ceremonies + ADD CONSTRAINT webauthn_ceremonies_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.webhook_deliveries + ADD CONSTRAINT webhook_deliveries_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.webhook_deliveries + ADD CONSTRAINT webhook_deliveries_webhook_endpoint_id_event_id_key UNIQUE (webhook_endpoint_id, event_id); + +ALTER TABLE ONLY public.webhook_endpoints + ADD CONSTRAINT webhook_endpoints_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.application_invitations + ADD CONSTRAINT application_invitations_pkey PRIMARY KEY (id); + +ALTER TABLE ONLY public.workspace_memberships + ADD CONSTRAINT workspace_memberships_pkey PRIMARY KEY (workspace_id, user_id); + +ALTER TABLE ONLY public.workspaces + ADD CONSTRAINT workspaces_application_id_id_key UNIQUE (application_id, id); + +ALTER TABLE ONLY public.workspaces + ADD CONSTRAINT workspaces_application_id_key_key UNIQUE (application_id, key); + +ALTER TABLE ONLY public.workspaces + ADD CONSTRAINT workspaces_pkey PRIMARY KEY (id); + +CREATE UNIQUE INDEX addresses_one_active ON public.addresses USING btree (billing_profile_id) WHERE is_active; + +CREATE UNIQUE INDEX application_invitations_pending_email ON public.application_invitations USING btree (application_id, COALESCE(workspace_id, '00000000-0000-0000-0000-000000000000'::uuid), normalized_email) WHERE ((accepted_at IS NULL) AND (revoked_at IS NULL) AND (expiration_recorded_at IS NULL)); + +CREATE INDEX audit_exports_expiry ON public.audit_exports USING btree (expires_at); + +CREATE UNIQUE INDEX auth_provider_configs_application_unique ON public.auth_provider_configs USING btree (application_id, provider) WHERE ((application_id IS NOT NULL) AND (disabled_at IS NULL)); + +CREATE INDEX auth_provider_configs_effective_scope ON public.auth_provider_configs USING btree (provider, application_id, organization_id, inheritable) WHERE (disabled_at IS NULL); + +CREATE UNIQUE INDEX auth_provider_configs_installation_unique ON public.auth_provider_configs USING btree (provider) WHERE ((application_id IS NULL) AND (organization_id IS NULL) AND (disabled_at IS NULL)); + +CREATE UNIQUE INDEX auth_provider_configs_organization_unique ON public.auth_provider_configs USING btree (organization_id, provider) WHERE ((organization_id IS NOT NULL) AND (disabled_at IS NULL)); + +CREATE INDEX auth_rate_limits_expiry ON public.auth_rate_limits USING btree (expires_at); + +CREATE UNIQUE INDEX billing_customers_application_identity ON public.billing_customers USING btree (application_id, id); + +CREATE UNIQUE INDEX billing_profiles_application_identity ON public.billing_profiles USING btree (application_id, id); + +CREATE UNIQUE INDEX checkout_sessions_application_identity ON public.checkout_sessions USING btree (application_id, id); + +CREATE UNIQUE INDEX clients_application_identity ON public.clients USING btree (application_id, id); + +CREATE INDEX entitlement_grant_actions_history ON public.entitlement_grant_actions USING btree (grant_id, created_at, id); + +CREATE INDEX entitlement_grants_effective ON public.entitlement_grants USING btree (application_id, subject_type, subject_id, starts_at, expires_at); + +CREATE UNIQUE INDEX entitlement_grants_unique_source ON public.entitlement_grants USING btree (application_id, source_type, source_id, product_id) WHERE (source_id IS NOT NULL); + +CREATE UNIQUE INDEX installations_singleton ON public.installations USING btree ((true)); + +CREATE INDEX invitation_authorization_codes_expiry ON public.invitation_authorization_codes USING btree (expires_at) WHERE (used_at IS NULL); + +CREATE UNIQUE INDEX invoices_application_identity ON public.invoices USING btree (application_id, id); + +CREATE INDEX local_entitlement_request_actions_history ON public.local_entitlement_request_actions USING btree (request_id, created_at, id); + +CREATE INDEX notification_providers_effective_scope ON public.notification_providers USING btree (provider, application_id, organization_id, inheritable) WHERE (disabled_at IS NULL); + +CREATE UNIQUE INDEX notification_templates_application_published ON public.notification_templates USING btree (application_id, key, locale) WHERE ((application_id IS NOT NULL) AND (status = 'published'::text)); + +CREATE UNIQUE INDEX notification_templates_application_version ON public.notification_templates USING btree (application_id, key, locale, version) WHERE (application_id IS NOT NULL); + +CREATE UNIQUE INDEX notification_templates_installation_published ON public.notification_templates USING btree (key, locale) WHERE ((application_id IS NULL) AND (status = 'published'::text)); + +CREATE UNIQUE INDEX notification_templates_installation_version ON public.notification_templates USING btree (key, locale, version) WHERE (application_id IS NULL); + +CREATE INDEX notifications_organization_queue ON public.notifications USING btree (organization_id, status, next_attempt_at) WHERE ((organization_id IS NOT NULL) AND (status = ANY (ARRAY['queued'::text, 'failed'::text]))); + +CREATE INDEX oauth_client_assertion_jtis_expiry ON public.oauth_client_assertion_jtis USING btree (expires_at); + +CREATE INDEX oauth_sessions_expiry ON public.oauth_sessions USING btree (expires_at); + +CREATE INDEX oauth_sessions_request ON public.oauth_sessions USING btree (application_id, request_id, kind) WHERE active; + +CREATE UNIQUE INDEX control_user_identities_provider_subject_unique ON public.control_user_identities USING btree (auth_provider_config_id, provider_subject); + +CREATE UNIQUE INDEX control_user_identities_user_provider_unique ON public.control_user_identities USING btree (control_user_id, auth_provider_config_id); + +CREATE UNIQUE INDEX control_user_invitations_installation_pending ON public.control_user_invitations USING btree (normalized_email) WHERE ((organization_id IS NULL) AND (accepted_at IS NULL) AND (revoked_at IS NULL)); + +CREATE UNIQUE INDEX control_user_invitations_organization_pending ON public.control_user_invitations USING btree (organization_id, normalized_email) WHERE ((organization_id IS NOT NULL) AND (accepted_at IS NULL) AND (revoked_at IS NULL)); + +CREATE UNIQUE INDEX payments_application_identity ON public.payments USING btree (application_id, id); + +CREATE UNIQUE INDEX permission_grants_active_client ON public.permission_grants USING btree (application_id, client_id, workspace_id, permission) NULLS NOT DISTINCT WHERE ((client_id IS NOT NULL) AND (revoked_at IS NULL)); + +CREATE UNIQUE INDEX permission_grants_active_user ON public.permission_grants USING btree (application_id, user_id, workspace_id, permission) NULLS NOT DISTINCT WHERE ((user_id IS NOT NULL) AND (revoked_at IS NULL)); + +CREATE INDEX permission_grants_subject_history ON public.permission_grants USING btree (application_id, user_id, client_id, workspace_id, created_at DESC); + +CREATE UNIQUE INDEX prices_application_identity ON public.prices USING btree (application_id, id); + +CREATE UNIQUE INDEX products_application_identity ON public.products USING btree (application_id, id); + +CREATE INDEX provider_connections_effective_scope ON public.provider_connections USING btree (provider, application_id, organization_id, inheritable) WHERE (status <> 'disabled'::text); + +CREATE UNIQUE INDEX role_assignments_unique_client ON public.role_assignments USING btree (application_id, client_id, role_id, workspace_id) NULLS NOT DISTINCT WHERE (client_id IS NOT NULL); + +CREATE UNIQUE INDEX role_assignments_unique_user ON public.role_assignments USING btree (application_id, user_id, role_id, workspace_id) NULLS NOT DISTINCT WHERE (user_id IS NOT NULL); + +CREATE UNIQUE INDEX roles_application_identity ON public.roles USING btree (application_id, id); + +CREATE INDEX storage_objects_application ON public.storage_objects USING btree (application_id, owner_type, owner_id, status, created_at DESC); + +CREATE INDEX storage_objects_pending ON public.storage_objects USING btree (upload_expires_at) WHERE (status = 'pending'::text); + +CREATE INDEX storage_objects_provider ON public.storage_objects USING btree (storage_provider_id, status, created_at DESC); + +CREATE INDEX storage_providers_scope ON public.storage_providers USING btree (application_id, organization_id, status, created_at DESC); + +CREATE UNIQUE INDEX subscriptions_application_identity ON public.subscriptions USING btree (application_id, id); + +CREATE INDEX user_authentication_methods_user ON public.user_authentication_methods USING btree (application_id, user_id, status); + +CREATE UNIQUE INDEX user_authentication_methods_webauthn_credential ON public.user_authentication_methods USING btree (application_id, credential_id) WHERE ((method_type = 'webauthn'::text) AND (status <> 'disabled'::text)); + +CREATE UNIQUE INDEX users_application_identity ON public.users USING btree (application_id, id); + +CREATE TRIGGER billing_customers_subject_guard BEFORE INSERT OR UPDATE OF application_id, subject_type, subject_id ON public.billing_customers FOR EACH ROW EXECUTE FUNCTION public.enforce_application_subject(); + +CREATE TRIGGER billing_profiles_subject_guard BEFORE INSERT OR UPDATE OF application_id, subject_type, subject_id ON public.billing_profiles FOR EACH ROW EXECUTE FUNCTION public.enforce_application_subject(); + +CREATE TRIGGER checkout_sessions_subject_guard BEFORE INSERT OR UPDATE OF application_id, subject_type, subject_id ON public.checkout_sessions FOR EACH ROW EXECUTE FUNCTION public.enforce_application_subject(); + +CREATE TRIGGER entitlement_grants_subject_guard BEFORE INSERT OR UPDATE OF application_id, subject_type, subject_id ON public.entitlement_grants FOR EACH ROW EXECUTE FUNCTION public.enforce_application_subject(); + +CREATE TRIGGER local_requests_subject_guard BEFORE INSERT OR UPDATE OF application_id, subject_type, subject_id ON public.local_entitlement_requests FOR EACH ROW EXECUTE FUNCTION public.enforce_application_subject(); + +CREATE TRIGGER notification_template_asset_scope_guard BEFORE INSERT OR UPDATE ON public.notification_template_assets FOR EACH ROW EXECUTE FUNCTION public.enforce_notification_template_asset_scope(); + +CREATE TRIGGER organizations_default_policy AFTER INSERT ON public.organizations FOR EACH ROW EXECUTE FUNCTION public.create_default_organization_policy(); + +CREATE TRIGGER permission_grants_guard BEFORE INSERT OR UPDATE ON public.permission_grants FOR EACH ROW EXECUTE FUNCTION public.enforce_permission_grant(); + +CREATE TRIGGER storage_object_scope_guard BEFORE INSERT OR UPDATE OF application_id, storage_provider_id, owner_type, owner_id, bucket_role, bucket_name ON public.storage_objects FOR EACH ROW EXECUTE FUNCTION public.enforce_storage_object_scope(); + +CREATE TRIGGER subscriptions_subject_guard BEFORE INSERT OR UPDATE OF application_id, subject_type, subject_id ON public.subscriptions FOR EACH ROW EXECUTE FUNCTION public.enforce_application_subject(); + +CREATE TRIGGER users_active_workspace_owner_guard BEFORE UPDATE OF status ON public.users FOR EACH ROW EXECUTE FUNCTION public.prevent_inactive_workspace_owner(); + +CREATE TRIGGER workspace_memberships_owner_guard BEFORE INSERT OR UPDATE ON public.workspace_memberships FOR EACH ROW EXECUTE FUNCTION public.enforce_workspace_owner_membership_separation(); + +CREATE TRIGGER workspaces_owner_guard BEFORE INSERT OR UPDATE OF owner_user_id ON public.workspaces FOR EACH ROW EXECUTE FUNCTION public.enforce_workspace_owner_is_active_non_member(); + +ALTER TABLE ONLY public.addresses + ADD CONSTRAINT addresses_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.addresses + ADD CONSTRAINT addresses_billing_profile_id_fkey FOREIGN KEY (billing_profile_id) REFERENCES public.billing_profiles(id); + +ALTER TABLE ONLY public.addresses + ADD CONSTRAINT addresses_profile_application_fk FOREIGN KEY (application_id, billing_profile_id) REFERENCES public.billing_profiles(application_id, id); + +ALTER TABLE ONLY public.application_domains + ADD CONSTRAINT application_domains_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.application_secrets + ADD CONSTRAINT application_secrets_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.applications + ADD CONSTRAINT applications_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.audit_exports + ADD CONSTRAINT audit_exports_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.audit_exports + ADD CONSTRAINT audit_exports_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.audit_exports + ADD CONSTRAINT audit_exports_requested_by_fkey FOREIGN KEY (requested_by) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.audit_records + ADD CONSTRAINT audit_records_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.audit_records + ADD CONSTRAINT audit_records_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.auth_provider_configs + ADD CONSTRAINT auth_provider_configs_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.auth_provider_configs + ADD CONSTRAINT auth_provider_configs_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.billing_customers + ADD CONSTRAINT billing_customers_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.billing_customers + ADD CONSTRAINT billing_customers_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.billing_profiles + ADD CONSTRAINT billing_profiles_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.checkout_sessions + ADD CONSTRAINT checkout_price_application_fk FOREIGN KEY (application_id, price_id) REFERENCES public.prices(application_id, id); + +ALTER TABLE ONLY public.checkout_sessions + ADD CONSTRAINT checkout_sessions_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.checkout_sessions + ADD CONSTRAINT checkout_sessions_price_id_fkey FOREIGN KEY (price_id) REFERENCES public.prices(id); + +ALTER TABLE ONLY public.checkout_sessions + ADD CONSTRAINT checkout_sessions_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.clients + ADD CONSTRAINT clients_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.delegations + ADD CONSTRAINT delegations_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.delegations + ADD CONSTRAINT delegations_control_user_id_fkey FOREIGN KEY (control_user_id) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.delegations + ADD CONSTRAINT delegations_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.delegations + ADD CONSTRAINT delegations_workspace_fk FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id); + +ALTER TABLE ONLY public.disputes + ADD CONSTRAINT dispute_payment_application_fk FOREIGN KEY (application_id, payment_id) REFERENCES public.payments(application_id, id); + +ALTER TABLE ONLY public.disputes + ADD CONSTRAINT disputes_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.disputes + ADD CONSTRAINT disputes_payment_id_fkey FOREIGN KEY (payment_id) REFERENCES public.payments(id); + +ALTER TABLE ONLY public.disputes + ADD CONSTRAINT disputes_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.domain_events + ADD CONSTRAINT domain_events_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.entitlement_grant_actions + ADD CONSTRAINT entitlement_grant_actions_grant_id_fkey FOREIGN KEY (grant_id) REFERENCES public.entitlement_grants(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.entitlement_grants + ADD CONSTRAINT entitlement_grants_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.entitlement_grants + ADD CONSTRAINT entitlement_grants_price_id_fkey FOREIGN KEY (price_id) REFERENCES public.prices(id); + +ALTER TABLE ONLY public.entitlement_grants + ADD CONSTRAINT entitlement_grants_product_id_fkey FOREIGN KEY (product_id) REFERENCES public.products(id); + +ALTER TABLE ONLY public.entitlement_grants + ADD CONSTRAINT entitlement_price_application_fk FOREIGN KEY (application_id, price_id) REFERENCES public.prices(application_id, id); + +ALTER TABLE ONLY public.entitlement_grants + ADD CONSTRAINT entitlement_product_application_fk FOREIGN KEY (application_id, product_id) REFERENCES public.products(application_id, id); + +ALTER TABLE ONLY public.event_type_definitions + ADD CONSTRAINT event_type_definitions_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.external_auth_challenges + ADD CONSTRAINT external_auth_challenges_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.external_auth_challenges + ADD CONSTRAINT external_auth_challenges_requested_by_user_id_fkey FOREIGN KEY (requested_by_user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.external_auth_exchanges + ADD CONSTRAINT external_auth_exchanges_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.external_auth_exchanges + ADD CONSTRAINT external_auth_exchanges_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.features + ADD CONSTRAINT features_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.installation_control_user_roles + ADD CONSTRAINT installation_control_user_roles_control_user_id_fkey FOREIGN KEY (control_user_id) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.invitation_authorization_codes + ADD CONSTRAINT invitation_authorization_codes_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.invitation_authorization_codes + ADD CONSTRAINT invitation_authorization_codes_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoice_customer_application_fk FOREIGN KEY (application_id, billing_customer_id) REFERENCES public.billing_customers(application_id, id); + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoice_subscription_application_fk FOREIGN KEY (application_id, subscription_id) REFERENCES public.subscriptions(application_id, id); + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoices_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoices_billing_customer_id_fkey FOREIGN KEY (billing_customer_id) REFERENCES public.billing_customers(id); + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoices_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.invoices + ADD CONSTRAINT invoices_subscription_id_fkey FOREIGN KEY (subscription_id) REFERENCES public.subscriptions(id); + +ALTER TABLE ONLY public.local_entitlement_request_actions + ADD CONSTRAINT local_entitlement_request_actions_request_id_fkey FOREIGN KEY (request_id) REFERENCES public.local_entitlement_requests(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_entitlement_requests_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_entitlement_requests_entitlement_grant_id_fkey FOREIGN KEY (entitlement_grant_id) REFERENCES public.entitlement_grants(id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_entitlement_requests_price_id_fkey FOREIGN KEY (price_id) REFERENCES public.prices(id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_entitlement_requests_product_id_fkey FOREIGN KEY (product_id) REFERENCES public.products(id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_entitlement_requests_requester_user_id_fkey FOREIGN KEY (requester_user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_entitlement_requests_reviewed_by_fkey FOREIGN KEY (reviewed_by) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_request_price_application_fk FOREIGN KEY (application_id, price_id) REFERENCES public.prices(application_id, id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_request_product_application_fk FOREIGN KEY (application_id, product_id) REFERENCES public.products(application_id, id); + +ALTER TABLE ONLY public.local_entitlement_requests + ADD CONSTRAINT local_request_user_application_fk FOREIGN KEY (application_id, requester_user_id) REFERENCES public.users(application_id, id); + +ALTER TABLE ONLY public.login_challenges + ADD CONSTRAINT login_challenges_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.login_challenges + ADD CONSTRAINT login_challenges_requested_by_user_id_fkey FOREIGN KEY (requested_by_user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.mfa_login_challenges + ADD CONSTRAINT mfa_login_challenges_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.mfa_login_challenges + ADD CONSTRAINT mfa_login_challenges_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.notification_attachments + ADD CONSTRAINT notification_attachments_notification_id_fkey FOREIGN KEY (notification_id) REFERENCES public.notifications(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.notification_attempts + ADD CONSTRAINT notification_attempts_notification_id_fkey FOREIGN KEY (notification_id) REFERENCES public.notifications(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.notification_attempts + ADD CONSTRAINT notification_attempts_notification_provider_id_fkey FOREIGN KEY (notification_provider_id) REFERENCES public.notification_providers(id); + +ALTER TABLE ONLY public.notification_preferences + ADD CONSTRAINT notification_preferences_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.notification_preferences + ADD CONSTRAINT notification_preferences_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.notification_providers + ADD CONSTRAINT notification_providers_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.notification_providers + ADD CONSTRAINT notification_providers_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.notification_template_assets + ADD CONSTRAINT notification_template_assets_notification_template_id_fkey FOREIGN KEY (notification_template_id) REFERENCES public.notification_templates(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.notification_template_assets + ADD CONSTRAINT notification_template_assets_storage_object_id_fkey FOREIGN KEY (storage_object_id) REFERENCES public.storage_objects(id); + +ALTER TABLE ONLY public.notification_templates + ADD CONSTRAINT notification_templates_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.notifications + ADD CONSTRAINT notifications_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.notifications + ADD CONSTRAINT notifications_notification_provider_id_fkey FOREIGN KEY (notification_provider_id) REFERENCES public.notification_providers(id); + +ALTER TABLE ONLY public.notifications + ADD CONSTRAINT notifications_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.notifications + ADD CONSTRAINT notifications_template_id_fkey FOREIGN KEY (template_id) REFERENCES public.notification_templates(id); + +ALTER TABLE ONLY public.notifications + ADD CONSTRAINT notifications_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.oauth_client_assertion_jtis + ADD CONSTRAINT oauth_client_assertion_jtis_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.oauth_consents + ADD CONSTRAINT oauth_consents_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.oauth_consents + ADD CONSTRAINT oauth_consents_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id); + +ALTER TABLE ONLY public.oauth_consents + ADD CONSTRAINT oauth_consents_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.oauth_sessions + ADD CONSTRAINT oauth_sessions_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.control_user_sessions + ADD CONSTRAINT control_user_sessions_control_user_id_fkey FOREIGN KEY (control_user_id) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.control_user_identities + ADD CONSTRAINT control_user_identities_control_user_id_fkey FOREIGN KEY (control_user_id) REFERENCES public.control_users(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.control_user_identities + ADD CONSTRAINT control_user_identities_auth_provider_config_id_fkey FOREIGN KEY (auth_provider_config_id) REFERENCES public.auth_provider_configs(id); + +ALTER TABLE ONLY public.control_user_external_auth_challenges + ADD CONSTRAINT control_user_external_auth_challenges_provider_id_fkey FOREIGN KEY (auth_provider_config_id) REFERENCES public.auth_provider_configs(id); + +ALTER TABLE ONLY public.control_user_external_auth_challenges + ADD CONSTRAINT control_user_external_auth_challenges_control_user_id_fkey FOREIGN KEY (requested_by_control_user_id) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.control_user_external_auth_challenges + ADD CONSTRAINT control_user_external_auth_challenges_invitation_id_fkey FOREIGN KEY (invitation_id) REFERENCES public.control_user_invitations(id); + +ALTER TABLE ONLY public.control_user_invitations + ADD CONSTRAINT control_user_invitations_accepted_by_fkey FOREIGN KEY (accepted_by) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.control_user_invitations + ADD CONSTRAINT control_user_invitations_invited_by_fkey FOREIGN KEY (invited_by) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.control_user_invitations + ADD CONSTRAINT control_user_invitations_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.organization_memberships + ADD CONSTRAINT organization_memberships_control_user_id_fkey FOREIGN KEY (control_user_id) REFERENCES public.control_users(id); + +ALTER TABLE ONLY public.organization_memberships + ADD CONSTRAINT organization_memberships_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.organization_policies + ADD CONSTRAINT organization_policies_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.outbox + ADD CONSTRAINT outbox_event_id_fkey FOREIGN KEY (event_id) REFERENCES public.domain_events(id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payment_checkout_application_fk FOREIGN KEY (application_id, checkout_session_id) REFERENCES public.checkout_sessions(application_id, id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payment_customer_application_fk FOREIGN KEY (application_id, billing_customer_id) REFERENCES public.billing_customers(application_id, id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payment_invoice_application_fk FOREIGN KEY (application_id, invoice_id) REFERENCES public.invoices(application_id, id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payments_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payments_billing_customer_id_fkey FOREIGN KEY (billing_customer_id) REFERENCES public.billing_customers(id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payments_checkout_session_id_fkey FOREIGN KEY (checkout_session_id) REFERENCES public.checkout_sessions(id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payments_invoice_id_fkey FOREIGN KEY (invoice_id) REFERENCES public.invoices(id); + +ALTER TABLE ONLY public.payments + ADD CONSTRAINT payments_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.personal_api_keys + ADD CONSTRAINT personal_api_keys_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.personal_api_keys + ADD CONSTRAINT personal_api_keys_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.permission_grants + ADD CONSTRAINT permission_grants_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.permission_grants + ADD CONSTRAINT permission_grants_client_application_fk FOREIGN KEY (application_id, client_id) REFERENCES public.clients(application_id, id); + +ALTER TABLE ONLY public.permission_grants + ADD CONSTRAINT permission_grants_user_application_fk FOREIGN KEY (application_id, user_id) REFERENCES public.users(application_id, id); + +ALTER TABLE ONLY public.permission_grants + ADD CONSTRAINT permission_grants_workspace_application_fk FOREIGN KEY (application_id, workspace_id) REFERENCES public.workspaces(application_id, id); + +ALTER TABLE ONLY public.price_features + ADD CONSTRAINT price_features_feature_id_fkey FOREIGN KEY (feature_id) REFERENCES public.features(id); + +ALTER TABLE ONLY public.price_features + ADD CONSTRAINT price_features_price_id_fkey FOREIGN KEY (price_id) REFERENCES public.prices(id); + +ALTER TABLE ONLY public.prices + ADD CONSTRAINT prices_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.prices + ADD CONSTRAINT prices_product_application_fk FOREIGN KEY (application_id, product_id) REFERENCES public.products(application_id, id); + +ALTER TABLE ONLY public.prices + ADD CONSTRAINT prices_product_id_fkey FOREIGN KEY (product_id) REFERENCES public.products(id); + +ALTER TABLE ONLY public.product_features + ADD CONSTRAINT product_features_feature_id_fkey FOREIGN KEY (feature_id) REFERENCES public.features(id); + +ALTER TABLE ONLY public.product_features + ADD CONSTRAINT product_features_product_id_fkey FOREIGN KEY (product_id) REFERENCES public.products(id) ON DELETE CASCADE; + +ALTER TABLE ONLY public.products + ADD CONSTRAINT products_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.provider_connections + ADD CONSTRAINT provider_connections_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.provider_connections + ADD CONSTRAINT provider_connections_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.provider_events + ADD CONSTRAINT provider_events_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.provider_events + ADD CONSTRAINT provider_events_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.provider_mappings + ADD CONSTRAINT provider_mappings_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.provider_mappings + ADD CONSTRAINT provider_mappings_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.reconciliation_runs + ADD CONSTRAINT reconciliation_runs_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.reconciliation_runs + ADD CONSTRAINT reconciliation_runs_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.refunds + ADD CONSTRAINT refund_payment_application_fk FOREIGN KEY (application_id, payment_id) REFERENCES public.payments(application_id, id); + +ALTER TABLE ONLY public.refunds + ADD CONSTRAINT refunds_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.refunds + ADD CONSTRAINT refunds_payment_id_fkey FOREIGN KEY (payment_id) REFERENCES public.payments(id); + +ALTER TABLE ONLY public.refunds + ADD CONSTRAINT refunds_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_client_application_fk FOREIGN KEY (application_id, client_id) REFERENCES public.clients(application_id, id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_client_id_fkey FOREIGN KEY (client_id) REFERENCES public.clients(id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_role_application_fk FOREIGN KEY (application_id, role_id) REFERENCES public.roles(application_id, id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_role_id_fkey FOREIGN KEY (role_id) REFERENCES public.roles(id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_user_application_fk FOREIGN KEY (application_id, user_id) REFERENCES public.users(application_id, id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_workspace_application_fk FOREIGN KEY (application_id, workspace_id) REFERENCES public.workspaces(application_id, id); + +ALTER TABLE ONLY public.role_assignments + ADD CONSTRAINT role_assignments_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id); + +ALTER TABLE ONLY public.roles + ADD CONSTRAINT roles_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.sender_identities + ADD CONSTRAINT sender_identities_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.sender_identities + ADD CONSTRAINT sender_identities_notification_provider_id_fkey FOREIGN KEY (notification_provider_id) REFERENCES public.notification_providers(id); + +ALTER TABLE ONLY public.sender_identities + ADD CONSTRAINT sender_identities_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.storage_objects + ADD CONSTRAINT storage_objects_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.storage_objects + ADD CONSTRAINT storage_objects_storage_provider_id_fkey FOREIGN KEY (storage_provider_id) REFERENCES public.storage_providers(id); + +ALTER TABLE ONLY public.storage_providers + ADD CONSTRAINT storage_providers_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.storage_providers + ADD CONSTRAINT storage_providers_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES public.organizations(id); + +ALTER TABLE ONLY public.subscriptions + ADD CONSTRAINT subscription_price_application_fk FOREIGN KEY (application_id, price_id) REFERENCES public.prices(application_id, id); + +ALTER TABLE ONLY public.subscriptions + ADD CONSTRAINT subscriptions_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.subscriptions + ADD CONSTRAINT subscriptions_price_id_fkey FOREIGN KEY (price_id) REFERENCES public.prices(id); + +ALTER TABLE ONLY public.subscriptions + ADD CONSTRAINT subscriptions_provider_connection_id_fkey FOREIGN KEY (provider_connection_id) REFERENCES public.provider_connections(id); + +ALTER TABLE ONLY public.user_authentication_methods + ADD CONSTRAINT user_authentication_methods_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.user_authentication_methods + ADD CONSTRAINT user_authentication_methods_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.user_identities + ADD CONSTRAINT user_identities_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.user_identities + ADD CONSTRAINT user_identities_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.user_recovery_codes + ADD CONSTRAINT user_recovery_codes_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.user_recovery_codes + ADD CONSTRAINT user_recovery_codes_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.user_sessions + ADD CONSTRAINT user_sessions_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.user_sessions + ADD CONSTRAINT user_sessions_delegation_id_fkey FOREIGN KEY (delegation_id) REFERENCES public.delegations(id); + +ALTER TABLE ONLY public.user_sessions + ADD CONSTRAINT user_sessions_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.webauthn_ceremonies + ADD CONSTRAINT webauthn_ceremonies_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.webauthn_ceremonies + ADD CONSTRAINT webauthn_ceremonies_mfa_challenge_id_fkey FOREIGN KEY (mfa_challenge_id) REFERENCES public.mfa_login_challenges(id); + +ALTER TABLE ONLY public.webauthn_ceremonies + ADD CONSTRAINT webauthn_ceremonies_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id); + +ALTER TABLE ONLY public.webauthn_ceremonies + ADD CONSTRAINT webauthn_ceremonies_user_session_id_fkey FOREIGN KEY (user_session_id) REFERENCES public.user_sessions(id); + +ALTER TABLE ONLY public.webhook_deliveries + ADD CONSTRAINT webhook_deliveries_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.webhook_deliveries + ADD CONSTRAINT webhook_deliveries_event_id_fkey FOREIGN KEY (event_id) REFERENCES public.domain_events(id); + +ALTER TABLE ONLY public.webhook_deliveries + ADD CONSTRAINT webhook_deliveries_webhook_endpoint_id_fkey FOREIGN KEY (webhook_endpoint_id) REFERENCES public.webhook_endpoints(id); + +ALTER TABLE ONLY public.webhook_endpoints + ADD CONSTRAINT webhook_endpoints_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.application_invitations + ADD CONSTRAINT application_invitations_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.application_invitations + ADD CONSTRAINT application_invitations_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES public.workspaces(id); + +ALTER TABLE ONLY public.workspace_memberships + ADD CONSTRAINT workspace_memberships_application_id_user_id_fkey FOREIGN KEY (application_id, user_id) REFERENCES public.users(application_id, id); + +ALTER TABLE ONLY public.workspace_memberships + ADD CONSTRAINT workspace_memberships_application_id_workspace_id_fkey FOREIGN KEY (application_id, workspace_id) REFERENCES public.workspaces(application_id, id); + +ALTER TABLE ONLY public.workspaces + ADD CONSTRAINT workspaces_application_id_fkey FOREIGN KEY (application_id) REFERENCES public.applications(id); + +ALTER TABLE ONLY public.workspaces + ADD CONSTRAINT workspaces_application_id_owner_user_id_fkey FOREIGN KEY (application_id, owner_user_id) REFERENCES public.users(application_id, id); + +INSERT INTO public.event_type_definitions +(id,application_id,name,description,schema_version,source,status,example_subject,data_schema,example_data,version) VALUES + (gen_random_uuid(),NULL,'application.created','An application was created.','1.0','platform93','active','application/01900000-0000-7000-8000-000000000002','{"type": "object", "required": ["name", "slug"], "properties": {"name": {"type": "string"}, "slug": {"type": "string"}}, "additionalProperties": false}'::jsonb,'{"name": "Production", "slug": "production"}'::jsonb,1), + (gen_random_uuid(),NULL,'application.restored','An application was restored.','1.0','platform93','active','application/01900000-0000-7000-8000-000000000002','{"type": "object", "required": ["organization_id", "reason"], "properties": {"reason": {"type": "string"}, "organization_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"reason": "application_restored", "organization_id": "01900000-0000-7000-8000-000000000001"}'::jsonb,1), + (gen_random_uuid(),NULL,'application.retired','An application was retired.','1.0','platform93','active','application/01900000-0000-7000-8000-000000000002','{"type": "object", "required": ["organization_id", "reason"], "properties": {"reason": {"type": "string"}, "organization_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"reason": "application_retired", "organization_id": "01900000-0000-7000-8000-000000000001"}'::jsonb,1), + (gen_random_uuid(),NULL,'application_invitation.accepted','An application invitation was accepted.','1.0','platform93','active','application_invitation/example','{"type": "object", "required": ["invitation_id", "status"], "properties": {"status": {"enum": ["pending", "accepted", "revoked", "expired"]}, "user_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": "string", "format": "date-time"}, "workspace_id": {"type": ["string", "null"], "format": "uuid"}, "invitation_id": {"type": "string", "format": "uuid"}, "workspace_role_keys": {"type": "array", "items": {"type": "string"}}, "application_role_keys": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "accepted", "invitation_id": "01900000-0000-7000-8000-000000000030"}'::jsonb,1), + (gen_random_uuid(),NULL,'application_invitation.created','An application invitation was created.','1.0','platform93','active','application_invitation/example','{"type": "object", "required": ["invitation_id", "status"], "properties": {"status": {"enum": ["pending", "accepted", "revoked", "expired"]}, "user_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": "string", "format": "date-time"}, "workspace_id": {"type": ["string", "null"], "format": "uuid"}, "invitation_id": {"type": "string", "format": "uuid"}, "workspace_role_keys": {"type": "array", "items": {"type": "string"}}, "application_role_keys": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "pending", "invitation_id": "01900000-0000-7000-8000-000000000030"}'::jsonb,1), + (gen_random_uuid(),NULL,'application_invitation.expired','An application invitation expired.','1.0','platform93','active','application_invitation/example','{"type": "object", "required": ["invitation_id", "status"], "properties": {"status": {"enum": ["pending", "accepted", "revoked", "expired"]}, "user_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": "string", "format": "date-time"}, "workspace_id": {"type": ["string", "null"], "format": "uuid"}, "invitation_id": {"type": "string", "format": "uuid"}, "workspace_role_keys": {"type": "array", "items": {"type": "string"}}, "application_role_keys": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "expired", "invitation_id": "01900000-0000-7000-8000-000000000030"}'::jsonb,1), + (gen_random_uuid(),NULL,'application_invitation.resent','An application invitation was resent.','1.0','platform93','active','application_invitation/example','{"type": "object", "required": ["invitation_id", "status"], "properties": {"status": {"enum": ["pending", "accepted", "revoked", "expired"]}, "user_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": "string", "format": "date-time"}, "workspace_id": {"type": ["string", "null"], "format": "uuid"}, "invitation_id": {"type": "string", "format": "uuid"}, "workspace_role_keys": {"type": "array", "items": {"type": "string"}}, "application_role_keys": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "pending", "invitation_id": "01900000-0000-7000-8000-000000000030"}'::jsonb,1), + (gen_random_uuid(),NULL,'application_invitation.revoked','An application invitation was revoked.','1.0','platform93','active','application_invitation/example','{"type": "object", "required": ["invitation_id", "status"], "properties": {"status": {"enum": ["pending", "accepted", "revoked", "expired"]}, "user_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": "string", "format": "date-time"}, "workspace_id": {"type": ["string", "null"], "format": "uuid"}, "invitation_id": {"type": "string", "format": "uuid"}, "workspace_role_keys": {"type": "array", "items": {"type": "string"}}, "application_role_keys": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "revoked", "invitation_id": "01900000-0000-7000-8000-000000000030"}'::jsonb,1), + (gen_random_uuid(),NULL,'billing.dispute.updated','A dispute changed.','1.0','platform93','active','dispute/example','{"type": "object", "required": ["status", "external_reference"], "properties": {"status": {"type": "string", "minLength": 1}, "refund_id": {"type": "string", "format": "uuid"}, "dispute_id": {"type": "string", "format": "uuid"}, "invoice_id": {"type": "string", "format": "uuid"}, "payment_id": {"type": "string", "format": "uuid"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "subscription_id": {"type": "string", "format": "uuid"}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "dispute_id": "01900000-0000-7000-8000-000000000035", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'billing.invoice.updated','An invoice changed.','1.0','platform93','active','invoice/example','{"type": "object", "required": ["status", "external_reference"], "properties": {"status": {"type": "string", "minLength": 1}, "refund_id": {"type": "string", "format": "uuid"}, "dispute_id": {"type": "string", "format": "uuid"}, "invoice_id": {"type": "string", "format": "uuid"}, "payment_id": {"type": "string", "format": "uuid"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "subscription_id": {"type": "string", "format": "uuid"}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "invoice_id": "01900000-0000-7000-8000-000000000032", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'billing.payment.updated','A payment changed.','1.0','platform93','active','payment/example','{"type": "object", "required": ["status", "external_reference"], "properties": {"status": {"type": "string", "minLength": 1}, "refund_id": {"type": "string", "format": "uuid"}, "dispute_id": {"type": "string", "format": "uuid"}, "invoice_id": {"type": "string", "format": "uuid"}, "payment_id": {"type": "string", "format": "uuid"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "subscription_id": {"type": "string", "format": "uuid"}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "payment_id": "01900000-0000-7000-8000-000000000033", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'billing.refund.updated','A refund changed.','1.0','platform93','active','refund/example','{"type": "object", "required": ["status", "external_reference"], "properties": {"status": {"type": "string", "minLength": 1}, "refund_id": {"type": "string", "format": "uuid"}, "dispute_id": {"type": "string", "format": "uuid"}, "invoice_id": {"type": "string", "format": "uuid"}, "payment_id": {"type": "string", "format": "uuid"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "subscription_id": {"type": "string", "format": "uuid"}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "refund_id": "01900000-0000-7000-8000-000000000034", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'billing.subscription.updated','A subscription changed.','1.0','platform93','active','subscription/example','{"type": "object", "required": ["status", "external_reference"], "properties": {"status": {"type": "string", "minLength": 1}, "refund_id": {"type": "string", "format": "uuid"}, "dispute_id": {"type": "string", "format": "uuid"}, "invoice_id": {"type": "string", "format": "uuid"}, "payment_id": {"type": "string", "format": "uuid"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "subscription_id": {"type": "string", "format": "uuid"}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "subscription_id": "01900000-0000-7000-8000-000000000031", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'authorization.permission_grant.created','A direct permission grant was created.','1.0','platform93','active','permission_grant/01900000-0000-7000-8000-000000000040','{"type":"object","required":["grant_id","subject_type","subject_id","workspace_id","permission","canonical_scope"],"properties":{"grant_id":{"type":"string","format":"uuid"},"subject_type":{"enum":["user","client"]},"subject_id":{"type":"string","format":"uuid"},"workspace_id":{"type":["string","null"],"format":"uuid"},"permission":{"type":"string","minLength":1,"maxLength":160},"canonical_scope":{"type":"string","minLength":1}},"additionalProperties":false}'::jsonb,'{"grant_id":"01900000-0000-7000-8000-000000000040","subject_type":"user","subject_id":"01900000-0000-7000-8000-000000000004","workspace_id":null,"permission":"invoices:read","canonical_scope":"/applications/01900000-0000-7000-8000-000000000002/invoices/read"}'::jsonb,1), + (gen_random_uuid(),NULL,'authorization.permission_grant.revoked','A direct permission grant was revoked.','1.0','platform93','active','permission_grant/01900000-0000-7000-8000-000000000040','{"type":"object","required":["grant_id","subject_type","subject_id","workspace_id","permission","canonical_scope"],"properties":{"grant_id":{"type":"string","format":"uuid"},"subject_type":{"enum":["user","client"]},"subject_id":{"type":"string","format":"uuid"},"workspace_id":{"type":["string","null"],"format":"uuid"},"permission":{"type":"string","minLength":1,"maxLength":160},"canonical_scope":{"type":"string","minLength":1}},"additionalProperties":false}'::jsonb,'{"grant_id":"01900000-0000-7000-8000-000000000040","subject_type":"user","subject_id":"01900000-0000-7000-8000-000000000004","workspace_id":null,"permission":"invoices:read","canonical_scope":"/applications/01900000-0000-7000-8000-000000000002/invoices/read"}'::jsonb,1), + (gen_random_uuid(),NULL,'delegation.created','Platform user delegation was created.','1.0','platform93','active','delegation/01900000-0000-7000-8000-000000000003','{"type": "object", "required": ["delegation_id", "user_id", "workspace_id", "permissions", "reason", "expires_at"], "properties": {"reason": {"type": "string"}, "user_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": "string", "format": "date-time"}, "permissions": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": ["string", "null"], "format": "uuid"}, "delegation_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"reason": "Investigate support request", "user_id": "01900000-0000-7000-8000-000000000004", "expires_at": "2026-01-01T00:15:00Z", "permissions": ["/applications/01900000-0000-7000-8000-000000000002/users/read"], "workspace_id": null, "delegation_id": "01900000-0000-7000-8000-000000000003"}'::jsonb,1), + (gen_random_uuid(),NULL,'delegation.exchanged','Platform user delegation was exchanged.','1.0','platform93','active','delegation/01900000-0000-7000-8000-000000000003','{"type": "object", "required": ["delegation_id", "user_id"], "properties": {"user_id": {"type": "string", "format": "uuid"}, "delegation_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004", "delegation_id": "01900000-0000-7000-8000-000000000003"}'::jsonb,1), + (gen_random_uuid(),NULL,'delegation.revoked','Platform user delegation was revoked.','1.0','platform93','active','delegation/01900000-0000-7000-8000-000000000003','{"type": "object", "required": ["delegation_id"], "properties": {"delegation_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"delegation_id": "01900000-0000-7000-8000-000000000003"}'::jsonb,1), + (gen_random_uuid(),NULL,'entitlement.adjusted','An entitlement was adjusted.','1.0','platform93','active','entitlement/example','{"type": "object", "required": ["grant_id"], "properties": {"reason": {"type": "string"}, "status": {"enum": ["active", "revoked", "expired"]}, "grant_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": ["string", "null"], "format": "date-time"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "grant_id": "01900000-0000-7000-8000-000000000005", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'entitlement.effective_changed','Effective entitlement values changed.','1.0','platform93','active','entitlement/example','{"type": "object", "required": ["grant_id"], "properties": {"reason": {"type": "string"}, "status": {"enum": ["active", "revoked", "expired"]}, "grant_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": ["string", "null"], "format": "date-time"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "grant_id": "01900000-0000-7000-8000-000000000005", "subject_id": "01900000-0000-7000-8000-000000000004", "subject_type": "user", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'entitlement.expired','An entitlement expired.','1.0','platform93','active','entitlement/example','{"type": "object", "required": ["grant_id"], "properties": {"reason": {"type": "string"}, "status": {"enum": ["active", "revoked", "expired"]}, "grant_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": ["string", "null"], "format": "date-time"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "expired", "grant_id": "01900000-0000-7000-8000-000000000005", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'entitlement.granted','An entitlement grant was created.','1.0','platform93','active','entitlement/01900000-0000-7000-8000-000000000005','{"type": "object", "required": ["grant_id", "subject_type", "subject_id", "reason", "status", "external_reference"], "properties": {"reason": {"type": "string"}, "status": {"enum": ["active", "revoked", "expired"]}, "grant_id": {"type": "string", "format": "uuid"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"reason": "subscription", "status": "active", "grant_id": "01900000-0000-7000-8000-000000000005", "subject_id": "01900000-0000-7000-8000-000000000006", "subject_type": "workspace", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'entitlement.restored','An entitlement was restored.','1.0','platform93','active','entitlement/example','{"type": "object", "required": ["grant_id"], "properties": {"reason": {"type": "string"}, "status": {"enum": ["active", "revoked", "expired"]}, "grant_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": ["string", "null"], "format": "date-time"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "active", "grant_id": "01900000-0000-7000-8000-000000000005", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'entitlement.revoked','An entitlement was revoked.','1.0','platform93','active','entitlement/example','{"type": "object", "required": ["grant_id"], "properties": {"reason": {"type": "string"}, "status": {"enum": ["active", "revoked", "expired"]}, "grant_id": {"type": "string", "format": "uuid"}, "expires_at": {"type": ["string", "null"], "format": "date-time"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"status": "revoked", "grant_id": "01900000-0000-7000-8000-000000000005", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'local_entitlement_request.approved','A local entitlement request was approved.','1.0','platform93','active','local_entitlement_request/01900000-0000-7000-8000-000000000007','{"type": "object", "required": ["request_id", "grant_id", "external_reference"], "properties": {"grant_id": {"type": "string", "format": "uuid"}, "request_id": {"type": "string", "format": "uuid"}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"grant_id": "01900000-0000-7000-8000-000000000005", "request_id": "01900000-0000-7000-8000-000000000007", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'local_entitlement_request.created','A local entitlement request was created.','1.0','platform93','active','local_entitlement_request/01900000-0000-7000-8000-000000000007','{"type": "object", "required": ["request_id", "subject_type", "subject_id", "price_id", "external_reference"], "properties": {"price_id": {"type": "string", "format": "uuid"}, "request_id": {"type": "string", "format": "uuid"}, "subject_id": {"type": "string", "format": "uuid"}, "subject_type": {"enum": ["user", "workspace"]}, "external_reference": {"type": ["string", "null"], "maxLength": 255, "minLength": 1}}, "additionalProperties": false}'::jsonb,'{"price_id": "01900000-0000-7000-8000-000000000008", "request_id": "01900000-0000-7000-8000-000000000007", "subject_id": "01900000-0000-7000-8000-000000000004", "subject_type": "user", "external_reference": null}'::jsonb,1), + (gen_random_uuid(),NULL,'oauth.consent_revoked','OAuth consent was revoked.','1.0','platform93','active','oauth_consent/01900000-0000-7000-8000-000000000004/01900000-0000-7000-8000-000000000009','{"type": "object", "required": ["user_id", "client_id", "client_key"], "properties": {"user_id": {"type": "string", "format": "uuid"}, "client_id": {"type": "string", "format": "uuid"}, "client_key": {"type": "string"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004", "client_id": "01900000-0000-7000-8000-000000000009", "client_key": "web"}'::jsonb,1), + (gen_random_uuid(),NULL,'organization.created','An organization was created.','1.0','platform93','active','organization/01900000-0000-7000-8000-000000000001','{"type": "object", "required": ["name", "slug"], "properties": {"name": {"type": "string"}, "slug": {"type": "string"}}, "additionalProperties": false}'::jsonb,'{"name": "Example Organization", "slug": "example-organization"}'::jsonb,1), + (gen_random_uuid(),NULL,'organization.restored','An organization was restored without restoring descendants.','1.0','platform93','active','organization/01900000-0000-7000-8000-000000000001','{"type": "object", "required": ["descendants_restored"], "properties": {"descendants_restored": {"type": "boolean"}}, "additionalProperties": false}'::jsonb,'{"descendants_restored": false}'::jsonb,1), + (gen_random_uuid(),NULL,'organization.retired','An organization and its active applications were retired.','1.0','platform93','active','organization/01900000-0000-7000-8000-000000000001','{"type": "object", "required": ["application_count"], "properties": {"application_count": {"type": "integer", "minimum": 0}}, "additionalProperties": false}'::jsonb,'{"application_count": 2}'::jsonb,1), + (gen_random_uuid(),NULL,'platform93.webhook.test','A targeted Platform93 webhook test was requested.','1.0','platform93','active','webhook/01900000-0000-7000-8000-000000000010','{"type": "object", "required": ["webhook_endpoint_id", "test"], "properties": {"test": {"const": true}, "webhook_endpoint_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"test": true, "webhook_endpoint_id": "01900000-0000-7000-8000-000000000010"}'::jsonb,1), + (gen_random_uuid(),NULL,'storage.object.deleted','An object was deleted.','1.0','platform93','active','storage_object/01900000-0000-7000-8000-000000000020','{"type": "object", "required": ["object_id", "owner_type", "visibility", "size_bytes"], "properties": {"object_id": {"type": "string", "format": "uuid"}, "owner_type": {"enum": ["installation", "application", "user", "workspace"]}, "size_bytes": {"type": "integer", "minimum": 1}, "visibility": {"enum": ["public", "private"]}}, "additionalProperties": false}'::jsonb,'{"object_id": "01900000-0000-7000-8000-000000000020", "owner_type": "workspace", "size_bytes": 1024, "visibility": "private"}'::jsonb,1), + (gen_random_uuid(),NULL,'storage.object.ready','An object upload completed and was verified.','1.0','platform93','active','storage_object/01900000-0000-7000-8000-000000000020','{"type": "object", "required": ["object_id", "owner_type", "visibility", "size_bytes"], "properties": {"object_id": {"type": "string", "format": "uuid"}, "owner_type": {"enum": ["installation", "application", "user", "workspace"]}, "size_bytes": {"type": "integer", "minimum": 1}, "visibility": {"enum": ["public", "private"]}}, "additionalProperties": false}'::jsonb,'{"object_id": "01900000-0000-7000-8000-000000000020", "owner_type": "workspace", "size_bytes": 1024, "visibility": "private"}'::jsonb,1), + (gen_random_uuid(),NULL,'storage.object.upload_requested','An object upload was authorized.','1.0','platform93','active','storage_object/01900000-0000-7000-8000-000000000020','{"type": "object", "required": ["object_id", "owner_type", "visibility", "size_bytes"], "properties": {"object_id": {"type": "string", "format": "uuid"}, "owner_type": {"enum": ["installation", "application", "user", "workspace"]}, "size_bytes": {"type": "integer", "minimum": 1}, "visibility": {"enum": ["public", "private"]}}, "additionalProperties": false}'::jsonb,'{"object_id": "01900000-0000-7000-8000-000000000020", "owner_type": "workspace", "size_bytes": 1024, "visibility": "private"}'::jsonb,1), + (gen_random_uuid(),NULL,'storage.provider.disabled','An S3-compatible storage provider was disabled in Platform93.','1.0','platform93','active','storage_provider/01900000-0000-7000-8000-000000000021','{"type": "object", "required": ["provider_id", "scope", "public_enabled", "private_enabled"], "properties": {"scope": {"enum": ["installation", "organization", "application"]}, "provider_id": {"type": "string", "format": "uuid"}, "public_enabled": {"type": "boolean"}, "private_enabled": {"type": "boolean"}}, "additionalProperties": false}'::jsonb,'{"scope": "application", "provider_id": "01900000-0000-7000-8000-000000000021", "public_enabled": true, "private_enabled": true}'::jsonb,1), + (gen_random_uuid(),NULL,'storage.provider.verified','An S3-compatible storage provider was verified.','1.0','platform93','active','storage_provider/01900000-0000-7000-8000-000000000021','{"type": "object", "required": ["provider_id", "scope", "public_enabled", "private_enabled"], "properties": {"scope": {"enum": ["installation", "organization", "application"]}, "provider_id": {"type": "string", "format": "uuid"}, "public_enabled": {"type": "boolean"}, "private_enabled": {"type": "boolean"}}, "additionalProperties": false}'::jsonb,'{"scope": "application", "provider_id": "01900000-0000-7000-8000-000000000021", "public_enabled": true, "private_enabled": true}'::jsonb,1), + (gen_random_uuid(),NULL,'user.anonymized','A user account was anonymized.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id"], "properties": {"user_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004"}'::jsonb,1), + (gen_random_uuid(),NULL,'user.created','A user account was created.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id", "email_verified", "is_org_verified"], "properties": {"user_id": {"type": "string", "format": "uuid"}, "email_verified": {"type": "boolean"}, "is_org_verified": {"type": "boolean"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004", "email_verified": false, "is_org_verified": false}'::jsonb,1), + (gen_random_uuid(),NULL,'user.deleted','A user account was deleted.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id"], "properties": {"user_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004"}'::jsonb,1), + (gen_random_uuid(),NULL,'user.email_changed','A user email address was changed.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id"], "properties": {"user_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004"}'::jsonb,1), + (gen_random_uuid(),NULL,'user.email_unverified','A user email address was administratively unverified.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id", "verified", "reason"], "properties": {"reason": {"type": "string"}, "user_id": {"type": "string", "format": "uuid"}, "verified": {"const": false}}, "additionalProperties": false}'::jsonb,'{"reason": "control_user_request", "user_id": "01900000-0000-7000-8000-000000000004", "verified": false}'::jsonb,1), + (gen_random_uuid(),NULL,'user.email_verified','A user email address was verified.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id", "verified", "reason"], "properties": {"reason": {"type": "string"}, "user_id": {"type": "string", "format": "uuid"}, "verified": {"const": true}}, "additionalProperties": false}'::jsonb,'{"reason": "self_service", "user_id": "01900000-0000-7000-8000-000000000004", "verified": true}'::jsonb,1), + (gen_random_uuid(),NULL,'user.organization_unverified','Organization verification was removed from a user.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id", "verified", "reason"], "properties": {"reason": {"type": "string"}, "user_id": {"type": "string", "format": "uuid"}, "verified": {"const": false}}, "additionalProperties": false}'::jsonb,'{"reason": "organization_review", "user_id": "01900000-0000-7000-8000-000000000004", "verified": false}'::jsonb,1), + (gen_random_uuid(),NULL,'user.organization_verified','A user was verified for an organization.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id", "verified", "reason"], "properties": {"reason": {"type": "string"}, "user_id": {"type": "string", "format": "uuid"}, "verified": {"const": true}}, "additionalProperties": false}'::jsonb,'{"reason": "organization_approved", "user_id": "01900000-0000-7000-8000-000000000004", "verified": true}'::jsonb,1), + (gen_random_uuid(),NULL,'user.password_reset','A user password was reset.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id"], "properties": {"user_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004"}'::jsonb,1), + (gen_random_uuid(),NULL,'user.pending_deletion','A user account entered pending deletion.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id"], "properties": {"user_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004"}'::jsonb,1), + (gen_random_uuid(),NULL,'user.restored','A suspended user was restored.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id", "reason"], "properties": {"reason": {"type": "string"}, "user_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"reason": "control_user_request", "user_id": "01900000-0000-7000-8000-000000000004"}'::jsonb,1), + (gen_random_uuid(),NULL,'user.suspended','A user was suspended.','1.0','platform93','active','user/01900000-0000-7000-8000-000000000004','{"type": "object", "required": ["user_id", "reason"], "properties": {"reason": {"type": "string"}, "user_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"reason": "control_user_request", "user_id": "01900000-0000-7000-8000-000000000004"}'::jsonb,1), + (gen_random_uuid(),NULL,'user.updated','A user profile was updated.','1.0','platform93','active','user/example','{"type": "object", "required": ["user_id", "changed_fields"], "properties": {"user_id": {"type": "string", "format": "uuid"}, "changed_fields": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004", "changed_fields": []}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.archived','A workspace was archived.','1.0','platform93','active','workspace/example','{"type": "object", "required": ["workspace_id", "status"], "properties": {"key": {"type": "string"}, "name": {"type": "string"}, "status": {"enum": ["active", "archived", "removed"]}, "user_id": {"type": "string", "format": "uuid"}, "role_keys": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": "string", "format": "uuid"}, "owner_user_id": {"type": "string", "format": "uuid"}, "changed_fields": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "archived", "workspace_id": "01900000-0000-7000-8000-000000000006"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.created','A workspace was created.','1.0','platform93','active','workspace/example','{"type": "object", "required": ["workspace_id", "status"], "properties": {"key": {"type": "string"}, "name": {"type": "string"}, "status": {"enum": ["active", "archived", "removed"]}, "user_id": {"type": "string", "format": "uuid"}, "role_keys": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": "string", "format": "uuid"}, "owner_user_id": {"type": "string", "format": "uuid"}, "changed_fields": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "active", "workspace_id": "01900000-0000-7000-8000-000000000006"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.invitation_accepted','A workspace invitation was accepted.','1.0','platform93','active','workspace_invitation/01900000-0000-7000-8000-000000000011','{"type": "object", "required": ["invitation_id", "workspace_id", "user_id"], "properties": {"user_id": {"type": "string", "format": "uuid"}, "workspace_id": {"type": "string", "format": "uuid"}, "invitation_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"user_id": "01900000-0000-7000-8000-000000000004", "workspace_id": "01900000-0000-7000-8000-000000000006", "invitation_id": "01900000-0000-7000-8000-000000000011"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.invitation_created','A workspace invitation was created.','1.0','platform93','active','workspace_invitation/01900000-0000-7000-8000-000000000011','{"type": "object", "required": ["invitation_id", "workspace_id", "role_keys"], "properties": {"role_keys": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": "string", "format": "uuid"}, "invitation_id": {"type": "string", "format": "uuid"}}, "additionalProperties": false}'::jsonb,'{"role_keys": ["workspace_member"], "workspace_id": "01900000-0000-7000-8000-000000000006", "invitation_id": "01900000-0000-7000-8000-000000000011"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.member_added','A workspace member was added.','1.0','platform93','active','workspace/example','{"type": "object", "required": ["workspace_id", "status"], "properties": {"key": {"type": "string"}, "name": {"type": "string"}, "status": {"enum": ["active", "archived", "removed"]}, "user_id": {"type": "string", "format": "uuid"}, "role_keys": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": "string", "format": "uuid"}, "owner_user_id": {"type": "string", "format": "uuid"}, "changed_fields": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "active", "workspace_id": "01900000-0000-7000-8000-000000000006"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.member_removed','A workspace member was removed.','1.0','platform93','active','workspace/example','{"type": "object", "required": ["workspace_id", "status"], "properties": {"key": {"type": "string"}, "name": {"type": "string"}, "status": {"enum": ["active", "archived", "removed"]}, "user_id": {"type": "string", "format": "uuid"}, "role_keys": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": "string", "format": "uuid"}, "owner_user_id": {"type": "string", "format": "uuid"}, "changed_fields": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "removed", "workspace_id": "01900000-0000-7000-8000-000000000006"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.member_updated','Workspace member roles changed.','1.0','platform93','active','workspace/example','{"type": "object", "required": ["workspace_id", "status"], "properties": {"key": {"type": "string"}, "name": {"type": "string"}, "status": {"enum": ["active", "archived", "removed"]}, "user_id": {"type": "string", "format": "uuid"}, "role_keys": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": "string", "format": "uuid"}, "owner_user_id": {"type": "string", "format": "uuid"}, "changed_fields": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "active", "workspace_id": "01900000-0000-7000-8000-000000000006"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.owner_transferred','Workspace ownership was transferred.','1.0','platform93','active','workspace/01900000-0000-7000-8000-000000000006','{"type": "object", "required": ["workspace_id", "previous_owner_user_id", "new_owner_user_id", "previous_owner_disposition"], "properties": {"workspace_id": {"type": "string", "format": "uuid"}, "new_owner_user_id": {"type": "string", "format": "uuid"}, "previous_owner_user_id": {"type": "string", "format": "uuid"}, "previous_owner_disposition": {"enum": ["member", "remove"]}}, "additionalProperties": false}'::jsonb,'{"workspace_id": "01900000-0000-7000-8000-000000000006", "new_owner_user_id": "01900000-0000-7000-8000-000000000012", "previous_owner_user_id": "01900000-0000-7000-8000-000000000004", "previous_owner_disposition": "member"}'::jsonb,1), + (gen_random_uuid(),NULL,'workspace.updated','A workspace was updated.','1.0','platform93','active','workspace/example','{"type": "object", "required": ["workspace_id", "status"], "properties": {"key": {"type": "string"}, "name": {"type": "string"}, "status": {"enum": ["active", "archived", "removed"]}, "user_id": {"type": "string", "format": "uuid"}, "role_keys": {"type": "array", "items": {"type": "string"}}, "workspace_id": {"type": "string", "format": "uuid"}, "owner_user_id": {"type": "string", "format": "uuid"}, "changed_fields": {"type": "array", "items": {"type": "string"}}}, "additionalProperties": false}'::jsonb,'{"status": "active", "workspace_id": "01900000-0000-7000-8000-000000000006"}'::jsonb,1); +INSERT INTO public.event_type_definitions +(id,application_id,name,description,schema_version,source,status,example_subject,data_schema,example_data,version) VALUES + (gen_random_uuid(),NULL,'control_user.identity_linked','A Platform user linked an external identity.','1.0','platform93','active','control_user/01900000-0000-7000-8000-000000000050','{"type":"object","required":["control_user_id","provider"],"properties":{"control_user_id":{"type":"string","format":"uuid"},"provider":{"enum":["google","apple"]}},"additionalProperties":false}'::jsonb,'{"control_user_id":"01900000-0000-7000-8000-000000000050","provider":"google"}'::jsonb,1), + (gen_random_uuid(),NULL,'control_user.identity_unlinked','A Platform user unlinked an external identity.','1.0','platform93','active','control_user/01900000-0000-7000-8000-000000000050','{"type":"object","required":["control_user_id","provider"],"properties":{"control_user_id":{"type":"string","format":"uuid"},"provider":{"enum":["google","apple"]}},"additionalProperties":false}'::jsonb,'{"control_user_id":"01900000-0000-7000-8000-000000000050","provider":"google"}'::jsonb,1), + (gen_random_uuid(),NULL,'control_auth.policy_updated','The Platform user authentication policy changed.','1.0','platform93','active','installation/identity','{"type":"object","required":["email_code_enabled","magic_link_enabled","password_enabled"],"properties":{"email_code_enabled":{"type":"boolean"},"magic_link_enabled":{"type":"boolean"},"password_enabled":{"type":"boolean"}},"additionalProperties":false}'::jsonb,'{"email_code_enabled":true,"magic_link_enabled":true,"password_enabled":true}'::jsonb,1), + (gen_random_uuid(),NULL,'control_auth.provider_login_enabled','An installation provider was enabled for Platform user sign-in.','1.0','platform93','active','auth_provider/google','{"type":"object","required":["provider","enabled"],"properties":{"provider":{"enum":["google","apple"]},"enabled":{"type":"boolean"}},"additionalProperties":false}'::jsonb,'{"provider":"google","enabled":true}'::jsonb,1), + (gen_random_uuid(),NULL,'control_auth.provider_login_disabled','An installation provider was disabled for Platform user sign-in.','1.0','platform93','active','auth_provider/google','{"type":"object","required":["provider","enabled"],"properties":{"provider":{"enum":["google","apple"]},"enabled":{"type":"boolean"}},"additionalProperties":false}'::jsonb,'{"provider":"google","enabled":false}'::jsonb,1), + (gen_random_uuid(),NULL,'control_user.invitation_created','A Platform user invitation was created.','1.0','platform93','active','control_user_invitation/01900000-0000-7000-8000-000000000051','{"type":"object","required":["invitation_id","role","onboarding_method","status"],"properties":{"invitation_id":{"type":"string","format":"uuid"},"organization_id":{"type":["string","null"],"format":"uuid"},"control_user_id":{"type":"string","format":"uuid"},"role":{"enum":["owner","admin","member","auditor"]},"onboarding_method":{"enum":["email","google","apple"]},"status":{"enum":["pending","accepted","revoked"]}},"additionalProperties":false}'::jsonb,'{"invitation_id":"01900000-0000-7000-8000-000000000051","organization_id":null,"role":"admin","onboarding_method":"google","status":"pending"}'::jsonb,1), + (gen_random_uuid(),NULL,'control_user.invitation_resent','A Platform user invitation credential was rotated.','1.0','platform93','active','control_user_invitation/01900000-0000-7000-8000-000000000051','{"type":"object","required":["invitation_id","role","onboarding_method","status"],"properties":{"invitation_id":{"type":"string","format":"uuid"},"organization_id":{"type":["string","null"],"format":"uuid"},"control_user_id":{"type":"string","format":"uuid"},"role":{"enum":["owner","admin","member","auditor"]},"onboarding_method":{"enum":["email","google","apple"]},"status":{"enum":["pending","accepted","revoked"]}},"additionalProperties":false}'::jsonb,'{"invitation_id":"01900000-0000-7000-8000-000000000051","organization_id":null,"role":"admin","onboarding_method":"google","status":"pending"}'::jsonb,1), + (gen_random_uuid(),NULL,'control_user.invitation_revoked','A Platform user invitation was revoked.','1.0','platform93','active','control_user_invitation/01900000-0000-7000-8000-000000000051','{"type":"object","required":["invitation_id","role","onboarding_method","status"],"properties":{"invitation_id":{"type":"string","format":"uuid"},"organization_id":{"type":["string","null"],"format":"uuid"},"control_user_id":{"type":"string","format":"uuid"},"role":{"enum":["owner","admin","member","auditor"]},"onboarding_method":{"enum":["email","google","apple"]},"status":{"enum":["pending","accepted","revoked"]}},"additionalProperties":false}'::jsonb,'{"invitation_id":"01900000-0000-7000-8000-000000000051","organization_id":null,"role":"admin","onboarding_method":"google","status":"revoked"}'::jsonb,1), + (gen_random_uuid(),NULL,'control_user.invitation_accepted','A Platform user invitation was accepted.','1.0','platform93','active','control_user_invitation/01900000-0000-7000-8000-000000000051','{"type":"object","required":["invitation_id","control_user_id","role","onboarding_method","status"],"properties":{"invitation_id":{"type":"string","format":"uuid"},"organization_id":{"type":["string","null"],"format":"uuid"},"control_user_id":{"type":"string","format":"uuid"},"role":{"enum":["owner","admin","member","auditor"]},"onboarding_method":{"enum":["email","google","apple"]},"status":{"enum":["pending","accepted","revoked"]}},"additionalProperties":false}'::jsonb,'{"invitation_id":"01900000-0000-7000-8000-000000000051","organization_id":null,"control_user_id":"01900000-0000-7000-8000-000000000050","role":"admin","onboarding_method":"google","status":"accepted"}'::jsonb,1); +INSERT INTO public.notification_templates +(application_id,key,locale,category,version,subject_template,text_template,html_template,variable_schema,status,system_managed) VALUES + (NULL,'platform93.control_user_invitation','en','security',1,'Your Platform93 invitation','You were invited as a Platform93 {{role}}. + +Onboarding method: {{onboarding_method}} + +Accept invitation: {{invitation_link}} + +Expires at: {{expires_at}}.','

Your Platform93 invitation

You were invited as {{role}}.

Onboarding method: {{onboarding_method}}

Accept invitation

Expires at {{expires_at}}.

','{"required": ["role", "onboarding_method", "invitation_link", "expires_at"], "properties": {"role": {"type": "string"}, "onboarding_method": {"type": "string"}, "invitation_link": {"type": "string"}, "invitation_token": {"type": "string"}, "expires_at": {"type": "string"}}}'::jsonb,'published',true), + (NULL,'platform93.application_invitation','en','security',1,'Invitation to {{application_name}}','You were invited to {{application_name}}. + +Code: {{invitation_code}} + +Accept invitation: {{invitation_link}} + +Roles: {{role_keys}} + +Expires at: {{expires_at}}.','

Invitation to {{application_name}}

Code: {{invitation_code}}

Accept invitation

Roles: {{role_keys}}
Expires at {{expires_at}}.

','{"required": ["invitation_code", "invitation_link", "role_keys", "expires_at"], "properties": {"role_keys": {"type": "string"}, "expires_at": {"type": "string"}, "inviter_name": {"type": "string"}, "invitation_code": {"type": "string"}, "invitation_link": {"type": "string"}}}'::jsonb,'published',true), + (NULL,'platform93.application_sign_in','en','security',1,'Sign in to {{application_name}}','A sign-in was requested for {{application_name}}. + +Code: {{code}} + +Magic link: {{magic_link}} + +This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.','

Sign in to {{application_name}}

Use the code or secure link below.

Code: {{code}}

Continue signing in

This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.

','{"required": ["code", "magic_link", "expires_minutes", "intent"], "properties": {"code": {"type": "string", "title": "Sign-in code", "example": "AB12CD34"}, "intent": {"type": "string", "title": "Authentication intent", "example": "sign_in"}, "magic_link": {"type": "string", "title": "Magic link", "example": "https://app.example/auth/callback"}, "expires_minutes": {"type": "integer", "title": "Expiry in minutes", "example": 10}}}'::jsonb,'published',true), + (NULL,'platform93.change_email','en','security',1,'Confirm your new email for {{application_name}}','Confirm this email address for {{application_name}}. + +Code: {{code}} + +Confirmation link: {{magic_link}} + +This credential expires in {{expires_minutes}} minutes.','

Confirm your new email

Confirm this email address for {{application_name}}.

Code: {{code}}

Confirm email

This credential expires in {{expires_minutes}} minutes.

','{"required": ["code", "magic_link", "expires_minutes"], "properties": {"code": {"type": "string", "title": "Confirmation code", "example": "AB12CD34"}, "magic_link": {"type": "string", "title": "Confirmation link", "example": "https://app.example/auth/callback"}, "expires_minutes": {"type": "integer", "title": "Expiry in minutes", "example": 10}}}'::jsonb,'published',true), + (NULL,'platform93.control_user_sign_in','en','security',1,'Your Platform93 sign-in code','A sign-in was requested for your Platform93 user account. + +Code: {{code}} + +Magic link: {{magic_link}} + +This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.','

Sign in to Platform93

A sign-in was requested for your Platform user account.

Code: {{code}}

Sign in securely

This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.

','{"required": ["code", "magic_link", "expires_minutes"], "properties": {"code": {"type": "string", "title": "Sign-in code", "example": "AB12CD34"}, "magic_link": {"type": "string", "title": "Magic link", "example": "https://platform93.example/?control_user_challenge=true"}, "expires_minutes": {"type": "integer", "title": "Expiry in minutes", "example": 10}}}'::jsonb,'published',true), + (NULL,'platform93.organization_invitation','en','security',1,'Invitation to administer {{organization_name}}','You were invited to administer {{organization_name}} as {{role}}. + +Accept invitation: {{invitation_link}} + +One-time invitation code: {{invitation_token}} + +Expires at: {{expires_at}} + +If you did not expect this invitation, ignore this message.','

Organization invitation

You were invited to administer {{organization_name}} as {{role}}.

Accept invitation

One-time invitation code: {{invitation_token}}

Expires at {{expires_at}}.

','{"required": ["organization_name", "role", "invitation_link", "invitation_token", "expires_at"], "properties": {"role": {"type": "string", "title": "Organization role", "example": "admin"}, "expires_at": {"type": "string", "title": "Expiry time", "example": "2026-08-15T12:00:00Z"}, "invitation_link": {"type": "string", "title": "Invitation link", "example": "https://platform93.example/?organization_invitation=true"}, "invitation_token": {"type": "string", "title": "One-time invitation code", "example": "p93_org_invite_example"}, "organization_name": {"type": "string", "title": "Organization name", "example": "Acme GmbH"}}}'::jsonb,'published',true), + (NULL,'platform93.password_reset','en','security',1,'Reset your {{application_name}} password','A password reset was requested for {{application_name}}. + +Code: {{code}} + +Reset link: {{magic_link}} + +This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.','

Reset your password

A password reset was requested for {{application_name}}.

Code: {{code}}

Reset password

This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.

','{"required": ["code", "magic_link", "expires_minutes"], "properties": {"code": {"type": "string", "title": "Reset code", "example": "AB12CD34"}, "magic_link": {"type": "string", "title": "Reset link", "example": "https://app.example/auth/callback"}, "expires_minutes": {"type": "integer", "title": "Expiry in minutes", "example": 10}}}'::jsonb,'published',true), + (NULL,'platform93.verify_email','en','security',1,'Verify your email for {{application_name}}','Confirm your email address for {{application_name}}. + +Code: {{code}} + +Verification link: {{magic_link}} + +This credential expires in {{expires_minutes}} minutes.','

Verify your email

Confirm your email address for {{application_name}}.

Code: {{code}}

Verify email

This credential expires in {{expires_minutes}} minutes.

','{"required": ["code", "magic_link", "expires_minutes"], "properties": {"code": {"type": "string", "title": "Verification code", "example": "AB12CD34"}, "magic_link": {"type": "string", "title": "Verification link", "example": "https://app.example/auth/callback"}, "expires_minutes": {"type": "integer", "title": "Expiry in minutes", "example": 10}}}'::jsonb,'published',true), + (NULL,'platform93.workspace_invitation','en','security',1,'Invitation to {{workspace_name}} in {{application_name}}','You were invited to join {{workspace_name}} in {{application_name}}. + +Code: {{invitation_code}} + +Accept invitation: {{invitation_link}} + +Roles: {{role_keys}} + +Expires at: {{expires_at}}.','

Workspace invitation

You were invited to join {{workspace_name}} in {{application_name}}.

Code: {{invitation_code}}

Accept invitation

Roles: {{role_keys}}
Expires at {{expires_at}}.

','{"required": ["workspace_id", "workspace_name", "role_keys", "invitation_code", "invitation_link", "expires_at"], "properties": {"role_keys": {"type": "string"}, "expires_at": {"type": "string"}, "inviter_name": {"type": "string"}, "workspace_id": {"type": "string"}, "workspace_name": {"type": "string"}, "invitation_code": {"type": "string"}, "invitation_link": {"type": "string"}}}'::jsonb,'published',true); -- +goose StatementEnd -CREATE TRIGGER billing_profiles_subject_guard BEFORE INSERT OR UPDATE OF application_id,subject_type,subject_id ON billing_profiles FOR EACH ROW EXECUTE FUNCTION enforce_application_subject(); -CREATE TRIGGER entitlement_grants_subject_guard BEFORE INSERT OR UPDATE OF application_id,subject_type,subject_id ON entitlement_grants FOR EACH ROW EXECUTE FUNCTION enforce_application_subject(); -CREATE TRIGGER local_requests_subject_guard BEFORE INSERT OR UPDATE OF application_id,subject_type,subject_id ON local_entitlement_requests FOR EACH ROW EXECUTE FUNCTION enforce_application_subject(); -CREATE TRIGGER billing_customers_subject_guard BEFORE INSERT OR UPDATE OF application_id,subject_type,subject_id ON billing_customers FOR EACH ROW EXECUTE FUNCTION enforce_application_subject(); -CREATE TRIGGER checkout_sessions_subject_guard BEFORE INSERT OR UPDATE OF application_id,subject_type,subject_id ON checkout_sessions FOR EACH ROW EXECUTE FUNCTION enforce_application_subject(); -CREATE TRIGGER subscriptions_subject_guard BEFORE INSERT OR UPDATE OF application_id,subject_type,subject_id ON subscriptions FOR EACH ROW EXECUTE FUNCTION enforce_application_subject(); -- +goose Down -DROP TABLE IF EXISTS idempotency_records, audit_exports, audit_records, webhook_deliveries, -webhook_endpoints, outbox, domain_events, notifications, notification_templates, -notification_attempts, notification_attachments, notification_preferences, sender_identities, -notification_providers, provider_events, reconciliation_runs, disputes, refunds, payments, invoices, subscriptions, -checkout_sessions, billing_customers, provider_mappings, provider_connections, -local_entitlement_request_actions, local_entitlement_requests, entitlement_grant_actions, entitlement_grants, price_features, prices, -products, features, workspace_invitations, role_assignments, workspace_memberships, workspaces, roles, -addresses, billing_profiles, personal_api_keys, webauthn_ceremonies, mfa_login_challenges, -user_recovery_codes, user_authentication_methods, user_sessions, external_auth_exchanges, -external_auth_challenges, login_challenges, user_identities, -delegations, users, clients, application_secrets, application_domains, applications, -organization_invitations, organization_memberships, organizations, auth_rate_limits, operator_login_challenges, installation_operator_roles, operator_sessions, operators, signing_keys, -installations CASCADE; -DROP FUNCTION IF EXISTS enforce_application_subject(); -DROP FUNCTION IF EXISTS prevent_inactive_workspace_owner(); -DROP FUNCTION IF EXISTS enforce_workspace_owner_is_active_non_member(); -DROP FUNCTION IF EXISTS enforce_workspace_owner_membership_separation(); -DROP FUNCTION IF EXISTS workspace_accessible_to_user(uuid,uuid,uuid); +DROP TABLE IF EXISTS public.addresses, public.application_domains, public.application_invitations, public.application_secrets, public.applications, public.audit_exports, public.audit_records, public.auth_provider_configs, public.auth_rate_limits, public.billing_customers, public.billing_profiles, public.checkout_sessions, public.clients, public.control_user_external_auth_challenges, public.control_user_identities, public.control_user_invitations, public.delegations, public.disputes, public.domain_events, public.entitlement_grant_actions, public.entitlement_grants, public.event_type_definitions, public.external_auth_challenges, public.external_auth_exchanges, public.features, public.idempotency_records, public.installation_control_user_roles, public.installations, public.invitation_authorization_codes, public.invoices, public.local_entitlement_request_actions, public.local_entitlement_requests, public.login_challenges, public.management_clients, public.mfa_login_challenges, public.notification_attachments, public.notification_attempts, public.notification_preferences, public.notification_providers, public.notification_template_assets, public.notification_templates, public.notifications, public.oauth_client_assertion_jtis, public.oauth_consents, public.oauth_sessions, public.control_user_login_challenges, public.control_user_sessions, public.control_users, public.organization_memberships, public.organization_policies, public.organizations, public.outbox, public.payments, public.permission_grants, public.personal_api_keys, public.price_features, public.prices, public.product_features, public.products, public.provider_connections, public.provider_events, public.provider_mappings, public.reconciliation_runs, public.refunds, public.role_assignments, public.roles, public.sender_identities, public.signing_keys, public.storage_objects, public.storage_providers, public.subscriptions, public.user_authentication_methods, public.user_identities, public.user_recovery_codes, public.user_sessions, public.users, public.webauthn_ceremonies, public.webhook_deliveries, public.webhook_endpoints, public.workspace_memberships, public.workspaces CASCADE; +DROP FUNCTION IF EXISTS public.create_default_organization_policy() CASCADE; +DROP FUNCTION IF EXISTS public.enforce_application_subject() CASCADE; +DROP FUNCTION IF EXISTS public.enforce_notification_template_asset_scope() CASCADE; +DROP FUNCTION IF EXISTS public.enforce_permission_grant() CASCADE; +DROP FUNCTION IF EXISTS public.enforce_storage_object_scope() CASCADE; +DROP FUNCTION IF EXISTS public.enforce_workspace_owner_is_active_non_member() CASCADE; +DROP FUNCTION IF EXISTS public.enforce_workspace_owner_membership_separation() CASCADE; +DROP FUNCTION IF EXISTS public.prevent_inactive_workspace_owner() CASCADE; +DROP FUNCTION IF EXISTS public.workspace_accessible_to_user(uuid,uuid,uuid) CASCADE; +DROP FUNCTION IF EXISTS public.valid_permission_key(text) CASCADE; +DROP FUNCTION IF EXISTS public.valid_permission_keys(text[]) CASCADE; +DROP FUNCTION IF EXISTS public.valid_canonical_scope(uuid,text) CASCADE; +DROP FUNCTION IF EXISTS public.valid_canonical_scopes(uuid,text[],boolean) CASCADE; diff --git a/migrations/00002_product_entitlement_defaults.sql b/migrations/00002_product_entitlement_defaults.sql deleted file mode 100644 index 78710db..0000000 --- a/migrations/00002_product_entitlement_defaults.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up -ALTER TABLE products ADD COLUMN entitlement_config jsonb NOT NULL DEFAULT '{}'; - -CREATE TABLE product_features ( - product_id uuid NOT NULL REFERENCES products(id) ON DELETE CASCADE, - feature_id uuid NOT NULL REFERENCES features(id), - boolean_value boolean, - quantity_value bigint, - configuration_value jsonb, - PRIMARY KEY (product_id, feature_id) -); - --- +goose Down -DROP TABLE IF EXISTS product_features; -ALTER TABLE products DROP COLUMN IF EXISTS entitlement_config; diff --git a/migrations/00003_event_type_registry.sql b/migrations/00003_event_type_registry.sql deleted file mode 100644 index eff895b..0000000 --- a/migrations/00003_event_type_registry.sql +++ /dev/null @@ -1,52 +0,0 @@ --- +goose Up -CREATE TABLE event_type_definitions ( - id uuid PRIMARY KEY, - application_id uuid REFERENCES applications(id), - name text NOT NULL CHECK (name ~ '^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$'), - description text NOT NULL DEFAULT '', - schema_version text NOT NULL DEFAULT '1.0' CHECK (schema_version ~ '^[1-9][0-9]*\.[0-9]+$'), - data_schema jsonb NOT NULL DEFAULT '{}', - source text NOT NULL CHECK (source IN ('platform93','application')), - status text NOT NULL DEFAULT 'active' CHECK (status IN ('active','archived')), - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE NULLS NOT DISTINCT (application_id,name), - CHECK ((source='platform93' AND application_id IS NULL) OR (source='application' AND application_id IS NOT NULL)) -); - -INSERT INTO event_type_definitions(id,application_id,name,description,source) VALUES -(gen_random_uuid(),NULL,'application.created','An application was created.','platform93'), -(gen_random_uuid(),NULL,'application.retired','An application was retired.','platform93'), -(gen_random_uuid(),NULL,'application.restored','An application was restored.','platform93'), -(gen_random_uuid(),NULL,'delegation.created','Operator delegation was created.','platform93'), -(gen_random_uuid(),NULL,'delegation.exchanged','Operator delegation was exchanged.','platform93'), -(gen_random_uuid(),NULL,'delegation.revoked','Operator delegation was revoked.','platform93'), -(gen_random_uuid(),NULL,'entitlement.granted','An entitlement grant was created.','platform93'), -(gen_random_uuid(),NULL,'local_entitlement_request.approved','A local entitlement request was approved.','platform93'), -(gen_random_uuid(),NULL,'local_entitlement_request.created','A local entitlement request was created.','platform93'), -(gen_random_uuid(),NULL,'oauth.consent_revoked','OAuth consent was revoked.','platform93'), -(gen_random_uuid(),NULL,'platform93.webhook.test.v1','A targeted Platform93 webhook test was requested.','platform93'), -(gen_random_uuid(),NULL,'user.anonymized','A user account was anonymized.','platform93'), -(gen_random_uuid(),NULL,'user.created','A user account was created.','platform93'), -(gen_random_uuid(),NULL,'user.deleted','A user account was deleted.','platform93'), -(gen_random_uuid(),NULL,'user.email_changed','A user email address was changed.','platform93'), -(gen_random_uuid(),NULL,'user.email_unverified','A user email address was administratively unverified.','platform93'), -(gen_random_uuid(),NULL,'user.email_verified','A user email address was verified.','platform93'), -(gen_random_uuid(),NULL,'user.organization_unverified','Organization verification was removed from a user.','platform93'), -(gen_random_uuid(),NULL,'user.organization_verified','A user was verified for an organization.','platform93'), -(gen_random_uuid(),NULL,'user.password_reset','A user password was reset.','platform93'), -(gen_random_uuid(),NULL,'user.pending_deletion','A user account entered pending deletion.','platform93'), -(gen_random_uuid(),NULL,'user.restored','A suspended user was restored.','platform93'), -(gen_random_uuid(),NULL,'user.suspended','A user was suspended.','platform93'), -(gen_random_uuid(),NULL,'workspace.invitation_accepted','A workspace invitation was accepted.','platform93'), -(gen_random_uuid(),NULL,'workspace.invitation_created','A workspace invitation was created.','platform93'), -(gen_random_uuid(),NULL,'workspace.owner_transferred','Workspace ownership was transferred.','platform93'); - -INSERT INTO roles(id,application_id,key,name,scope,permissions,built_in) -SELECT gen_random_uuid(),id,'event_publisher','Event publisher','application',ARRAY['events:publish'],true -FROM applications ON CONFLICT(application_id,key) DO NOTHING; - --- +goose Down -DELETE FROM roles WHERE key='event_publisher' AND built_in=true; -DROP TABLE IF EXISTS event_type_definitions; diff --git a/migrations/00004_provider_inheritance.sql b/migrations/00004_provider_inheritance.sql deleted file mode 100644 index 7a71bfa..0000000 --- a/migrations/00004_provider_inheritance.sql +++ /dev/null @@ -1,85 +0,0 @@ --- +goose Up -ALTER TABLE notification_providers - ADD COLUMN organization_id uuid REFERENCES organizations(id), - ADD COLUMN inheritable boolean NOT NULL DEFAULT false; -UPDATE notification_providers SET inheritable=true WHERE application_id IS NULL; -ALTER TABLE notification_providers ADD CONSTRAINT notification_provider_scope_check CHECK ( - (application_id IS NOT NULL AND organization_id IS NULL) OR - (application_id IS NULL AND organization_id IS NOT NULL) OR - (application_id IS NULL AND organization_id IS NULL) -); -CREATE INDEX notification_providers_effective_scope - ON notification_providers(provider,application_id,organization_id,inheritable) WHERE disabled_at IS NULL; - -ALTER TABLE sender_identities ADD COLUMN organization_id uuid REFERENCES organizations(id); - -ALTER TABLE billing_customers DROP CONSTRAINT billing_customer_provider_application_fk; -ALTER TABLE checkout_sessions DROP CONSTRAINT checkout_provider_application_fk; -ALTER TABLE subscriptions DROP CONSTRAINT subscription_provider_application_fk; -ALTER TABLE invoices DROP CONSTRAINT invoice_provider_application_fk; -ALTER TABLE payments DROP CONSTRAINT payment_provider_application_fk; -ALTER TABLE refunds DROP CONSTRAINT refund_provider_application_fk; -ALTER TABLE disputes DROP CONSTRAINT dispute_provider_application_fk; -ALTER TABLE reconciliation_runs DROP CONSTRAINT reconciliation_provider_application_fk; -ALTER TABLE provider_events DROP CONSTRAINT provider_event_connection_application_fk; -DROP INDEX provider_connections_application_identity; - -ALTER TABLE provider_connections - ALTER COLUMN application_id DROP NOT NULL, - ADD COLUMN organization_id uuid REFERENCES organizations(id), - ADD COLUMN inheritable boolean NOT NULL DEFAULT false; -ALTER TABLE provider_connections ADD CONSTRAINT billing_provider_scope_check CHECK ( - (application_id IS NOT NULL AND organization_id IS NULL) OR - (application_id IS NULL AND organization_id IS NOT NULL) OR - (application_id IS NULL AND organization_id IS NULL) -); -CREATE INDEX provider_connections_effective_scope - ON provider_connections(provider,application_id,organization_id,inheritable) WHERE status<>'disabled'; - -CREATE TABLE auth_provider_configs ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - organization_id uuid REFERENCES organizations(id), - application_id uuid REFERENCES applications(id), - provider text NOT NULL CHECK (provider IN ('google','apple')), - client_id text NOT NULL, - config_ciphertext text NOT NULL, - metadata jsonb NOT NULL DEFAULT '{}', - inheritable boolean NOT NULL DEFAULT false, - disabled_at timestamptz, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - CHECK ( - (application_id IS NOT NULL AND organization_id IS NULL) OR - (application_id IS NULL AND organization_id IS NOT NULL) OR - (application_id IS NULL AND organization_id IS NULL) - ) -); -CREATE UNIQUE INDEX auth_provider_configs_installation_unique - ON auth_provider_configs(provider) WHERE application_id IS NULL AND organization_id IS NULL AND disabled_at IS NULL; -CREATE UNIQUE INDEX auth_provider_configs_organization_unique - ON auth_provider_configs(organization_id,provider) WHERE organization_id IS NOT NULL AND disabled_at IS NULL; -CREATE UNIQUE INDEX auth_provider_configs_application_unique - ON auth_provider_configs(application_id,provider) WHERE application_id IS NOT NULL AND disabled_at IS NULL; -CREATE INDEX auth_provider_configs_effective_scope - ON auth_provider_configs(provider,application_id,organization_id,inheritable) WHERE disabled_at IS NULL; - --- +goose Down -DROP TABLE auth_provider_configs; -DROP INDEX provider_connections_effective_scope; -ALTER TABLE provider_connections DROP CONSTRAINT billing_provider_scope_check; -ALTER TABLE provider_connections DROP COLUMN inheritable, DROP COLUMN organization_id; -ALTER TABLE provider_connections ALTER COLUMN application_id SET NOT NULL; -CREATE UNIQUE INDEX provider_connections_application_identity ON provider_connections(application_id,id); -ALTER TABLE billing_customers ADD CONSTRAINT billing_customer_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE checkout_sessions ADD CONSTRAINT checkout_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE subscriptions ADD CONSTRAINT subscription_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE invoices ADD CONSTRAINT invoice_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE payments ADD CONSTRAINT payment_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE refunds ADD CONSTRAINT refund_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE disputes ADD CONSTRAINT dispute_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE reconciliation_runs ADD CONSTRAINT reconciliation_provider_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE provider_events ADD CONSTRAINT provider_event_connection_application_fk FOREIGN KEY(application_id,provider_connection_id) REFERENCES provider_connections(application_id,id); -ALTER TABLE sender_identities DROP COLUMN organization_id; -DROP INDEX notification_providers_effective_scope; -ALTER TABLE notification_providers DROP CONSTRAINT notification_provider_scope_check; -ALTER TABLE notification_providers DROP COLUMN inheritable, DROP COLUMN organization_id; diff --git a/migrations/00005_organization_notifications.sql b/migrations/00005_organization_notifications.sql deleted file mode 100644 index 1da2ac6..0000000 --- a/migrations/00005_organization_notifications.sql +++ /dev/null @@ -1,10 +0,0 @@ --- +goose Up -ALTER TABLE notifications - ADD COLUMN organization_id uuid REFERENCES organizations(id), - ADD CONSTRAINT notification_scope_check CHECK (application_id IS NULL OR organization_id IS NULL); -CREATE INDEX notifications_organization_queue - ON notifications(organization_id,status,next_attempt_at) WHERE organization_id IS NOT NULL AND status IN ('queued','failed'); - --- +goose Down -DROP INDEX notifications_organization_queue; -ALTER TABLE notifications DROP CONSTRAINT notification_scope_check, DROP COLUMN organization_id; diff --git a/migrations/00006_system_notification_templates.sql b/migrations/00006_system_notification_templates.sql deleted file mode 100644 index d329b13..0000000 --- a/migrations/00006_system_notification_templates.sql +++ /dev/null @@ -1,77 +0,0 @@ --- +goose Up -ALTER TABLE notification_templates - ALTER COLUMN application_id DROP NOT NULL, - ADD COLUMN system_managed boolean NOT NULL DEFAULT false; -ALTER TABLE notification_templates - DROP CONSTRAINT notification_templates_application_id_key_locale_version_key; -WITH ranked_published AS ( - SELECT id,row_number() OVER (PARTITION BY application_id,key,locale ORDER BY version DESC,updated_at DESC,id DESC) AS position - FROM notification_templates WHERE status='published' -) -UPDATE notification_templates SET status='archived',updated_at=now() -WHERE id IN (SELECT id FROM ranked_published WHERE position>1); -CREATE UNIQUE INDEX notification_templates_installation_version - ON notification_templates(key,locale,version) WHERE application_id IS NULL; -CREATE UNIQUE INDEX notification_templates_application_version - ON notification_templates(application_id,key,locale,version) WHERE application_id IS NOT NULL; -CREATE UNIQUE INDEX notification_templates_installation_published - ON notification_templates(key,locale) WHERE application_id IS NULL AND status='published'; -CREATE UNIQUE INDEX notification_templates_application_published - ON notification_templates(application_id,key,locale) WHERE application_id IS NOT NULL AND status='published'; - -INSERT INTO notification_templates -(application_id,key,locale,category,version,subject_template,text_template,html_template,variable_schema,status,system_managed) -VALUES -(NULL,'platform93.operator_sign_in','en','security',1, - 'Your Platform93 sign-in code', - E'A sign-in was requested for your Platform93 operator account.\n\nCode: {{code}}\n\nMagic link: {{magic_link}}\n\nThis credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.', - '

Sign in to Platform93

A sign-in was requested for your operator account.

Code: {{code}}

Sign in securely

This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.

', - '{"properties":{"code":{"type":"string","title":"Sign-in code","example":"AB12CD34"},"magic_link":{"type":"string","title":"Magic link","example":"https://platform93.example/?operator_challenge=true"},"expires_minutes":{"type":"integer","title":"Expiry in minutes","example":10}},"required":["code","magic_link","expires_minutes"]}', - 'published',true), -(NULL,'platform93.application_sign_in','en','security',1, - 'Sign in to {{application_name}}', - E'A sign-in was requested for {{application_name}}.\n\nCode: {{code}}\n\nMagic link: {{magic_link}}\n\nThis credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.', - '

Sign in to {{application_name}}

Use the code or secure link below.

Code: {{code}}

Continue signing in

This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.

', - '{"properties":{"code":{"type":"string","title":"Sign-in code","example":"AB12CD34"},"magic_link":{"type":"string","title":"Magic link","example":"https://app.example/auth/callback"},"expires_minutes":{"type":"integer","title":"Expiry in minutes","example":10},"intent":{"type":"string","title":"Authentication intent","example":"sign_in"}},"required":["code","magic_link","expires_minutes","intent"]}', - 'published',true), -(NULL,'platform93.verify_email','en','security',1, - 'Verify your email for {{application_name}}', - E'Confirm your email address for {{application_name}}.\n\nCode: {{code}}\n\nVerification link: {{magic_link}}\n\nThis credential expires in {{expires_minutes}} minutes.', - '

Verify your email

Confirm your email address for {{application_name}}.

Code: {{code}}

Verify email

This credential expires in {{expires_minutes}} minutes.

', - '{"properties":{"code":{"type":"string","title":"Verification code","example":"AB12CD34"},"magic_link":{"type":"string","title":"Verification link","example":"https://app.example/auth/callback"},"expires_minutes":{"type":"integer","title":"Expiry in minutes","example":10}},"required":["code","magic_link","expires_minutes"]}', - 'published',true), -(NULL,'platform93.change_email','en','security',1, - 'Confirm your new email for {{application_name}}', - E'Confirm this email address for {{application_name}}.\n\nCode: {{code}}\n\nConfirmation link: {{magic_link}}\n\nThis credential expires in {{expires_minutes}} minutes.', - '

Confirm your new email

Confirm this email address for {{application_name}}.

Code: {{code}}

Confirm email

This credential expires in {{expires_minutes}} minutes.

', - '{"properties":{"code":{"type":"string","title":"Confirmation code","example":"AB12CD34"},"magic_link":{"type":"string","title":"Confirmation link","example":"https://app.example/auth/callback"},"expires_minutes":{"type":"integer","title":"Expiry in minutes","example":10}},"required":["code","magic_link","expires_minutes"]}', - 'published',true), -(NULL,'platform93.password_reset','en','security',1, - 'Reset your {{application_name}} password', - E'A password reset was requested for {{application_name}}.\n\nCode: {{code}}\n\nReset link: {{magic_link}}\n\nThis credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.', - '

Reset your password

A password reset was requested for {{application_name}}.

Code: {{code}}

Reset password

This credential expires in {{expires_minutes}} minutes. If you did not request it, ignore this message.

', - '{"properties":{"code":{"type":"string","title":"Reset code","example":"AB12CD34"},"magic_link":{"type":"string","title":"Reset link","example":"https://app.example/auth/callback"},"expires_minutes":{"type":"integer","title":"Expiry in minutes","example":10}},"required":["code","magic_link","expires_minutes"]}', - 'published',true), -(NULL,'platform93.organization_invitation','en','security',1, - 'Invitation to administer {{organization_name}}', - E'You were invited to administer {{organization_name}} as {{role}}.\n\nAccept invitation: {{invitation_link}}\n\nOne-time invitation code: {{invitation_token}}\n\nExpires at: {{expires_at}}\n\nIf you did not expect this invitation, ignore this message.', - '

Organization invitation

You were invited to administer {{organization_name}} as {{role}}.

Accept invitation

One-time invitation code: {{invitation_token}}

Expires at {{expires_at}}.

', - '{"properties":{"organization_name":{"type":"string","title":"Organization name","example":"Acme GmbH"},"role":{"type":"string","title":"Organization role","example":"admin"},"invitation_link":{"type":"string","title":"Invitation link","example":"https://platform93.example/?organization_invitation=true"},"invitation_token":{"type":"string","title":"One-time invitation code","example":"p93_org_invite_example"},"expires_at":{"type":"string","title":"Expiry time","example":"2026-08-15T12:00:00Z"}},"required":["organization_name","role","invitation_link","invitation_token","expires_at"]}', - 'published',true), -(NULL,'platform93.workspace_invitation','en','security',1, - 'Invitation to {{workspace_name}} in {{application_name}}', - E'You were invited to join {{workspace_name}} in {{application_name}}.\n\nAccept invitation: {{invitation_link}}\n\nOne-time invitation code: {{invitation_token}}\n\nRoles: {{role_keys}}\n\nExpires at: {{expires_at}}\n\nIf you did not expect this invitation, ignore this message.', - '

Workspace invitation

You were invited to join {{workspace_name}} in {{application_name}}.

Accept invitation

One-time invitation code: {{invitation_token}}

Roles: {{role_keys}}
Expires at {{expires_at}}.

', - '{"properties":{"workspace_id":{"type":"string","title":"Workspace ID","example":"01993f4e-7ae1-7000-8000-000000000093"},"workspace_name":{"type":"string","title":"Workspace name","example":"Main workspace"},"role_keys":{"type":"string","title":"Workspace roles","example":"member"},"invitation_link":{"type":"string","title":"Invitation link","example":"https://app.example/invitations/accept"},"invitation_token":{"type":"string","title":"One-time invitation code","example":"p93_invite_example"},"expires_at":{"type":"string","title":"Expiry time","example":"2026-08-15T12:00:00Z"}},"required":["workspace_id","workspace_name","role_keys","invitation_link","invitation_token","expires_at"]}', - 'published',true); - --- +goose Down -DELETE FROM notification_templates WHERE application_id IS NULL; -DROP INDEX notification_templates_application_published; -DROP INDEX notification_templates_installation_published; -DROP INDEX notification_templates_application_version; -DROP INDEX notification_templates_installation_version; -ALTER TABLE notification_templates DROP COLUMN system_managed; -ALTER TABLE notification_templates ALTER COLUMN application_id SET NOT NULL; -ALTER TABLE notification_templates ADD CONSTRAINT notification_templates_application_id_key_locale_version_key - UNIQUE(application_id,key,locale,version); diff --git a/migrations/00007_free_form_features.sql b/migrations/00007_free_form_features.sql deleted file mode 100644 index 15cac0a..0000000 --- a/migrations/00007_free_form_features.sql +++ /dev/null @@ -1,22 +0,0 @@ --- +goose Up -ALTER TABLE features DROP CONSTRAINT features_value_type_check; -ALTER TABLE features ADD COLUMN free_form_format text; -UPDATE features SET value_type = 'free_form', free_form_format = 'json' WHERE value_type = 'configuration'; -ALTER TABLE features ADD CONSTRAINT features_value_type_check CHECK (value_type IN ('boolean','quantity','free_form')); -ALTER TABLE features ADD CONSTRAINT features_free_form_format_check CHECK ( - (value_type = 'free_form' AND free_form_format IN ('text','csv','json')) OR - (value_type <> 'free_form' AND free_form_format IS NULL) -); - -ALTER TABLE product_features RENAME COLUMN configuration_value TO free_form_value; -ALTER TABLE price_features RENAME COLUMN configuration_value TO free_form_value; - --- +goose Down -ALTER TABLE price_features RENAME COLUMN free_form_value TO configuration_value; -ALTER TABLE product_features RENAME COLUMN free_form_value TO configuration_value; - -ALTER TABLE features DROP CONSTRAINT features_free_form_format_check; -ALTER TABLE features DROP CONSTRAINT features_value_type_check; -UPDATE features SET value_type = 'configuration' WHERE value_type = 'free_form'; -ALTER TABLE features DROP COLUMN free_form_format; -ALTER TABLE features ADD CONSTRAINT features_value_type_check CHECK (value_type IN ('boolean','quantity','configuration')); diff --git a/migrations/00008_application_configuration.sql b/migrations/00008_application_configuration.sql deleted file mode 100644 index 79a3520..0000000 --- a/migrations/00008_application_configuration.sql +++ /dev/null @@ -1,35 +0,0 @@ --- +goose Up -ALTER TABLE applications - ADD COLUMN public_config jsonb NOT NULL DEFAULT '{}', - ADD COLUMN internal_config jsonb NOT NULL DEFAULT '{"registration_mode":"public","password_enabled":true,"passwordless_enabled":true,"personal_api_keys_enabled":false,"delegation_enabled":false}'; - -UPDATE applications SET internal_config = jsonb_build_object( - 'registration_mode', CASE WHEN COALESCE((auth_config->>'registration_enabled')::boolean, true) THEN 'public' ELSE 'invite_only' END, - 'password_enabled', COALESCE((auth_config->>'password_enabled')::boolean, true), - 'passwordless_enabled', COALESCE((auth_config->>'passwordless_enabled')::boolean, true), - 'personal_api_keys_enabled', COALESCE((auth_config->'personal_api_keys'->>'enabled')::boolean, false), - 'delegation_enabled', true -), auth_config = auth_config - 'registration_enabled' - 'password_enabled' - 'passwordless_enabled' - 'personal_api_keys'; - -ALTER TABLE applications ALTER COLUMN auth_config SET DEFAULT '{}'; -ALTER TABLE applications ADD CONSTRAINT applications_internal_config_check CHECK ( - jsonb_typeof(public_config) = 'object' AND - jsonb_typeof(internal_config) = 'object' AND - internal_config ?& ARRAY['registration_mode','password_enabled','passwordless_enabled','personal_api_keys_enabled','delegation_enabled'] AND - internal_config->>'registration_mode' IN ('public','invite_only') AND - jsonb_typeof(internal_config->'password_enabled') = 'boolean' AND - jsonb_typeof(internal_config->'passwordless_enabled') = 'boolean' AND - jsonb_typeof(internal_config->'personal_api_keys_enabled') = 'boolean' AND - jsonb_typeof(internal_config->'delegation_enabled') = 'boolean' -); - --- +goose Down -ALTER TABLE applications DROP CONSTRAINT applications_internal_config_check; -UPDATE applications SET auth_config = auth_config || jsonb_build_object( - 'registration_enabled', internal_config->>'registration_mode' = 'public', - 'password_enabled', internal_config->'password_enabled', - 'passwordless_enabled', internal_config->'passwordless_enabled', - 'personal_api_keys', jsonb_build_object('enabled', internal_config->'personal_api_keys_enabled') -); -ALTER TABLE applications ALTER COLUMN auth_config SET DEFAULT '{"registration_enabled":true,"password_enabled":true,"passwordless_enabled":true,"personal_api_keys":{"enabled":false}}'; -ALTER TABLE applications DROP COLUMN internal_config, DROP COLUMN public_config; diff --git a/migrations/00009_event_contracts.sql b/migrations/00009_event_contracts.sql deleted file mode 100644 index b4b0cfa..0000000 --- a/migrations/00009_event_contracts.sql +++ /dev/null @@ -1,80 +0,0 @@ --- +goose Up -ALTER TABLE event_type_definitions - ADD COLUMN example_subject text NOT NULL DEFAULT 'resource/example', - ADD COLUMN example_data jsonb NOT NULL DEFAULT '{}'; - -ALTER TABLE event_type_definitions ADD CONSTRAINT event_type_definition_contract_check CHECK ( - example_subject <> '' AND length(example_subject) <= 500 AND - jsonb_typeof(data_schema) = 'object' AND jsonb_typeof(example_data) = 'object' -); - -ALTER TABLE domain_events - ADD COLUMN contract_source text NOT NULL DEFAULT 'platform93' - CHECK (contract_source IN ('platform93','application')); - -UPDATE domain_events e SET contract_source='application' -WHERE EXISTS ( - SELECT 1 FROM event_type_definitions d - WHERE d.application_id=e.application_id AND d.name=e.event_type AND d.source='application' -); - -UPDATE event_type_definitions SET name='platform93.webhook.test' -WHERE application_id IS NULL AND name='platform93.webhook.test.v1'; -UPDATE domain_events SET event_type='platform93.webhook.test' -WHERE event_type='platform93.webhook.test.v1'; -UPDATE webhook_endpoints SET event_filters=array_replace(event_filters,'platform93.webhook.test.v1','platform93.webhook.test') -WHERE 'platform93.webhook.test.v1'=ANY(event_filters); - -INSERT INTO event_type_definitions(id,application_id,name,description,source) VALUES -(gen_random_uuid(),NULL,'organization.created','An organization was created.','platform93'), -(gen_random_uuid(),NULL,'organization.retired','An organization and its active applications were retired.','platform93'), -(gen_random_uuid(),NULL,'organization.restored','An organization was restored without restoring descendants.','platform93') -ON CONFLICT(application_id,name) DO NOTHING; - -WITH contracts(name,example_subject,data_schema,example_data) AS (VALUES -('organization.created','organization/01900000-0000-7000-8000-000000000001','{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"name":"Example Organization","slug":"example-organization"}'::jsonb), -('organization.retired','organization/01900000-0000-7000-8000-000000000001','{"type":"object","required":["application_count"],"properties":{"application_count":{"type":"integer","minimum":0}},"additionalProperties":false}'::jsonb,'{"application_count":2}'::jsonb), -('organization.restored','organization/01900000-0000-7000-8000-000000000001','{"type":"object","required":["descendants_restored"],"properties":{"descendants_restored":{"type":"boolean"}},"additionalProperties":false}'::jsonb,'{"descendants_restored":false}'::jsonb), -('application.created','application/01900000-0000-7000-8000-000000000002','{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string"},"slug":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"name":"Production","slug":"production"}'::jsonb), -('application.retired','application/01900000-0000-7000-8000-000000000002','{"type":"object","required":["organization_id","reason"],"properties":{"organization_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"organization_id":"01900000-0000-7000-8000-000000000001","reason":"application_retired"}'::jsonb), -('application.restored','application/01900000-0000-7000-8000-000000000002','{"type":"object","required":["organization_id","reason"],"properties":{"organization_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"organization_id":"01900000-0000-7000-8000-000000000001","reason":"application_restored"}'::jsonb), -('delegation.created','delegation/01900000-0000-7000-8000-000000000003','{"type":"object","required":["delegation_id","user_id","workspace_id","permissions","reason","expires_at"],"properties":{"delegation_id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"},"workspace_id":{"type":["string","null"],"format":"uuid"},"permissions":{"type":"array","items":{"type":"string"}},"reason":{"type":"string"},"expires_at":{"type":"string","format":"date-time"}},"additionalProperties":false}'::jsonb,'{"delegation_id":"01900000-0000-7000-8000-000000000003","user_id":"01900000-0000-7000-8000-000000000004","workspace_id":null,"permissions":["/applications/01900000-0000-7000-8000-000000000002/users/read"],"reason":"Investigate support request","expires_at":"2026-01-01T00:15:00Z"}'::jsonb), -('delegation.exchanged','delegation/01900000-0000-7000-8000-000000000003','{"type":"object","required":["delegation_id","user_id"],"properties":{"delegation_id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"delegation_id":"01900000-0000-7000-8000-000000000003","user_id":"01900000-0000-7000-8000-000000000004"}'::jsonb), -('delegation.revoked','delegation/01900000-0000-7000-8000-000000000003','{"type":"object","required":["delegation_id"],"properties":{"delegation_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"delegation_id":"01900000-0000-7000-8000-000000000003"}'::jsonb), -('entitlement.granted','entitlement/01900000-0000-7000-8000-000000000005','{"type":"object","required":["grant_id","subject_type","subject_id","reason"],"properties":{"grant_id":{"type":"string","format":"uuid"},"subject_type":{"enum":["user","workspace"]},"subject_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"grant_id":"01900000-0000-7000-8000-000000000005","subject_type":"workspace","subject_id":"01900000-0000-7000-8000-000000000006","reason":"subscription"}'::jsonb), -('local_entitlement_request.created','local_entitlement_request/01900000-0000-7000-8000-000000000007','{"type":"object","required":["request_id","subject_type","subject_id","price_id"],"properties":{"request_id":{"type":"string","format":"uuid"},"subject_type":{"enum":["user","workspace"]},"subject_id":{"type":"string","format":"uuid"},"price_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"request_id":"01900000-0000-7000-8000-000000000007","subject_type":"user","subject_id":"01900000-0000-7000-8000-000000000004","price_id":"01900000-0000-7000-8000-000000000008"}'::jsonb), -('local_entitlement_request.approved','local_entitlement_request/01900000-0000-7000-8000-000000000007','{"type":"object","required":["request_id","grant_id"],"properties":{"request_id":{"type":"string","format":"uuid"},"grant_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"request_id":"01900000-0000-7000-8000-000000000007","grant_id":"01900000-0000-7000-8000-000000000005"}'::jsonb), -('oauth.consent_revoked','oauth_consent/01900000-0000-7000-8000-000000000004/01900000-0000-7000-8000-000000000009','{"type":"object","required":["user_id","client_id","client_key"],"properties":{"user_id":{"type":"string","format":"uuid"},"client_id":{"type":"string","format":"uuid"},"client_key":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","client_id":"01900000-0000-7000-8000-000000000009","client_key":"web"}'::jsonb), -('platform93.webhook.test','webhook/01900000-0000-7000-8000-000000000010','{"type":"object","required":["webhook_endpoint_id","test"],"properties":{"webhook_endpoint_id":{"type":"string","format":"uuid"},"test":{"const":true}},"additionalProperties":false}'::jsonb,'{"webhook_endpoint_id":"01900000-0000-7000-8000-000000000010","test":true}'::jsonb), -('user.created','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id","email_verified","is_org_verified"],"properties":{"user_id":{"type":"string","format":"uuid"},"email_verified":{"type":"boolean"},"is_org_verified":{"type":"boolean"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","email_verified":false,"is_org_verified":false}'::jsonb), -('user.email_verified','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id","verified","reason"],"properties":{"user_id":{"type":"string","format":"uuid"},"verified":{"const":true},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","verified":true,"reason":"self_service"}'::jsonb), -('user.email_unverified','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id","verified","reason"],"properties":{"user_id":{"type":"string","format":"uuid"},"verified":{"const":false},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","verified":false,"reason":"operator_request"}'::jsonb), -('user.organization_verified','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id","verified","reason"],"properties":{"user_id":{"type":"string","format":"uuid"},"verified":{"const":true},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","verified":true,"reason":"organization_approved"}'::jsonb), -('user.organization_unverified','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id","verified","reason"],"properties":{"user_id":{"type":"string","format":"uuid"},"verified":{"const":false},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","verified":false,"reason":"organization_review"}'::jsonb), -('user.email_changed','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id"],"properties":{"user_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004"}'::jsonb), -('user.password_reset','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id"],"properties":{"user_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004"}'::jsonb), -('user.pending_deletion','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id"],"properties":{"user_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004"}'::jsonb), -('user.anonymized','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id"],"properties":{"user_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004"}'::jsonb), -('user.deleted','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id"],"properties":{"user_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004"}'::jsonb), -('user.suspended','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id","reason"],"properties":{"user_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","reason":"operator_request"}'::jsonb), -('user.restored','user/01900000-0000-7000-8000-000000000004','{"type":"object","required":["user_id","reason"],"properties":{"user_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}},"additionalProperties":false}'::jsonb,'{"user_id":"01900000-0000-7000-8000-000000000004","reason":"operator_request"}'::jsonb), -('workspace.invitation_created','workspace_invitation/01900000-0000-7000-8000-000000000011','{"type":"object","required":["invitation_id","workspace_id","role_keys"],"properties":{"invitation_id":{"type":"string","format":"uuid"},"workspace_id":{"type":"string","format":"uuid"},"role_keys":{"type":"array","items":{"type":"string"}}},"additionalProperties":false}'::jsonb,'{"invitation_id":"01900000-0000-7000-8000-000000000011","workspace_id":"01900000-0000-7000-8000-000000000006","role_keys":["workspace_member"]}'::jsonb), -('workspace.invitation_accepted','workspace_invitation/01900000-0000-7000-8000-000000000011','{"type":"object","required":["invitation_id","workspace_id","user_id"],"properties":{"invitation_id":{"type":"string","format":"uuid"},"workspace_id":{"type":"string","format":"uuid"},"user_id":{"type":"string","format":"uuid"}},"additionalProperties":false}'::jsonb,'{"invitation_id":"01900000-0000-7000-8000-000000000011","workspace_id":"01900000-0000-7000-8000-000000000006","user_id":"01900000-0000-7000-8000-000000000004"}'::jsonb), -('workspace.owner_transferred','workspace/01900000-0000-7000-8000-000000000006','{"type":"object","required":["workspace_id","previous_owner_user_id","new_owner_user_id","previous_owner_disposition"],"properties":{"workspace_id":{"type":"string","format":"uuid"},"previous_owner_user_id":{"type":"string","format":"uuid"},"new_owner_user_id":{"type":"string","format":"uuid"},"previous_owner_disposition":{"enum":["member","remove"]}},"additionalProperties":false}'::jsonb,'{"workspace_id":"01900000-0000-7000-8000-000000000006","previous_owner_user_id":"01900000-0000-7000-8000-000000000004","new_owner_user_id":"01900000-0000-7000-8000-000000000012","previous_owner_disposition":"member"}'::jsonb) -) -UPDATE event_type_definitions d SET - schema_version='1.0', example_subject=c.example_subject, - data_schema=c.data_schema, example_data=c.example_data, updated_at=now() -FROM contracts c WHERE d.application_id IS NULL AND d.source='platform93' AND d.name=c.name; - --- +goose Down -UPDATE webhook_endpoints SET event_filters=array_replace(event_filters,'platform93.webhook.test','platform93.webhook.test.v1') -WHERE 'platform93.webhook.test'=ANY(event_filters); -UPDATE domain_events SET event_type='platform93.webhook.test.v1' -WHERE event_type='platform93.webhook.test'; -UPDATE event_type_definitions SET name='platform93.webhook.test.v1' -WHERE application_id IS NULL AND name='platform93.webhook.test'; -DELETE FROM event_type_definitions WHERE application_id IS NULL AND name IN ('organization.created','organization.retired','organization.restored'); -ALTER TABLE domain_events DROP COLUMN contract_source; -ALTER TABLE event_type_definitions DROP CONSTRAINT event_type_definition_contract_check; -ALTER TABLE event_type_definitions DROP COLUMN example_data, DROP COLUMN example_subject; diff --git a/migrations/00010_operator_passwords.sql b/migrations/00010_operator_passwords.sql deleted file mode 100644 index 0a59226..0000000 --- a/migrations/00010_operator_passwords.sql +++ /dev/null @@ -1,5 +0,0 @@ --- +goose Up -ALTER TABLE operators ADD COLUMN password_hash text; - --- +goose Down -ALTER TABLE operators DROP COLUMN password_hash; diff --git a/migrations/00011_organization_management.sql b/migrations/00011_organization_management.sql deleted file mode 100644 index 669e827..0000000 --- a/migrations/00011_organization_management.sql +++ /dev/null @@ -1,59 +0,0 @@ --- +goose Up -ALTER TABLE installations ADD COLUMN management_api_enabled boolean NOT NULL DEFAULT false; - -COMMENT ON COLUMN installations.management_api_enabled IS 'Live kill switch for machine-only installation organization management.'; - -CREATE TABLE management_clients ( - id uuid PRIMARY KEY DEFAULT gen_random_uuid(), - client_id text NOT NULL UNIQUE, - name text NOT NULL, - secret_digest bytea NOT NULL, - allowed_scopes text[] NOT NULL DEFAULT ARRAY['/management/organizations/*']::text[], - disabled_at timestamptz, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now() -); - -CREATE TABLE organization_policies ( - organization_id uuid PRIMARY KEY REFERENCES organizations(id) ON DELETE CASCADE, - max_applications integer CHECK (max_applications IS NULL OR max_applications >= 0), - max_users integer CHECK (max_users IS NULL OR max_users >= 0), - enabled_settings jsonb NOT NULL DEFAULT '{ - "public_registration": true, - "password_authentication": true, - "passwordless_authentication": true, - "personal_api_keys": true, - "delegation": true, - "organization_provider_overrides": true, - "application_provider_overrides": true, - "custom_events": true, - "webhooks": true - }'::jsonb, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - CHECK (jsonb_typeof(enabled_settings) = 'object') -); - -INSERT INTO organization_policies(organization_id) -SELECT id FROM organizations ON CONFLICT DO NOTHING; - --- +goose StatementBegin -CREATE FUNCTION create_default_organization_policy() RETURNS trigger AS $$ -BEGIN - INSERT INTO organization_policies(organization_id) VALUES(NEW.id); - RETURN NEW; -END; -$$ LANGUAGE plpgsql; --- +goose StatementEnd - -CREATE TRIGGER organizations_default_policy -AFTER INSERT ON organizations FOR EACH ROW EXECUTE FUNCTION create_default_organization_policy(); - --- +goose Down -DROP TRIGGER IF EXISTS organizations_default_policy ON organizations; -DROP FUNCTION IF EXISTS create_default_organization_policy(); -DROP TABLE IF EXISTS organization_policies; -DROP TABLE IF EXISTS management_clients; -ALTER TABLE installations DROP COLUMN management_api_enabled; diff --git a/migrations/00012_notification_localization.sql b/migrations/00012_notification_localization.sql deleted file mode 100644 index 9497130..0000000 --- a/migrations/00012_notification_localization.sql +++ /dev/null @@ -1,9 +0,0 @@ --- +goose Up -ALTER TABLE users - ADD COLUMN locale text NOT NULL DEFAULT '', - ADD CONSTRAINT users_locale_length CHECK (length(locale) <= 35); - --- +goose Down -ALTER TABLE users - DROP CONSTRAINT users_locale_length, - DROP COLUMN locale; diff --git a/migrations/00013_object_storage.sql b/migrations/00013_object_storage.sql deleted file mode 100644 index ef07e7c..0000000 --- a/migrations/00013_object_storage.sql +++ /dev/null @@ -1,172 +0,0 @@ --- +goose Up -CREATE TABLE storage_providers ( - id uuid PRIMARY KEY, - organization_id uuid REFERENCES organizations(id), - application_id uuid REFERENCES applications(id), - provider text NOT NULL DEFAULT 's3' CHECK (provider='s3'), - name text NOT NULL CHECK (name<>'' AND length(name)<=200), - endpoint text NOT NULL CHECK (endpoint<>'' AND length(endpoint)<=2000), - region text NOT NULL CHECK (region<>'' AND length(region)<=100), - force_path_style boolean NOT NULL DEFAULT false, - public_bucket text, - private_bucket text, - public_base_url text, - credentials_ciphertext text NOT NULL, - inheritable boolean NOT NULL DEFAULT false, - allow_private_endpoint boolean NOT NULL DEFAULT false, - max_object_bytes bigint NOT NULL DEFAULT 26214400 CHECK (max_object_bytes BETWEEN 1 AND 5368709120), - max_email_image_bytes bigint NOT NULL DEFAULT 2097152 CHECK (max_email_image_bytes BETWEEN 1 AND 26214400), - max_application_bytes bigint NOT NULL DEFAULT 10737418240 CHECK (max_application_bytes>=max_object_bytes), - max_application_objects bigint NOT NULL DEFAULT 100000 CHECK (max_application_objects BETWEEN 1 AND 100000000), - status text NOT NULL DEFAULT 'unverified' CHECK (status IN ('unverified','active','error','disabled')), - verified_at timestamptz, - disabled_at timestamptz, - last_error text, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - CHECK ((application_id IS NOT NULL AND organization_id IS NULL) OR - (application_id IS NULL AND organization_id IS NOT NULL) OR - (application_id IS NULL AND organization_id IS NULL)), - CHECK (public_bucket IS NOT NULL OR private_bucket IS NOT NULL), - CHECK (public_bucket IS NULL OR private_bucket IS NULL OR public_bucket<>private_bucket), - CHECK (application_id IS NULL OR inheritable=false), - CHECK (allow_private_endpoint=false OR (application_id IS NULL AND organization_id IS NULL)) -); -CREATE INDEX storage_providers_scope ON storage_providers(application_id,organization_id,status,created_at DESC); - -CREATE TABLE storage_objects ( - id uuid PRIMARY KEY, - application_id uuid REFERENCES applications(id), - storage_provider_id uuid NOT NULL REFERENCES storage_providers(id), - owner_type text NOT NULL CHECK (owner_type IN ('installation','application','user','workspace')), - owner_id uuid, - visibility text NOT NULL CHECK (visibility IN ('public','private')), - bucket_role text NOT NULL CHECK (bucket_role IN ('public','private')), - bucket_name text NOT NULL, - object_key text NOT NULL CHECK (object_key<>'' AND length(object_key)<=1024), - filename text NOT NULL CHECK (filename<>'' AND length(filename)<=500), - content_type text NOT NULL CHECK (content_type<>'' AND length(content_type)<=255), - size_bytes bigint NOT NULL CHECK (size_bytes>0), - etag text, - metadata jsonb NOT NULL DEFAULT '{}', - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending','ready','deleting','deleted','failed')), - upload_expires_at timestamptz, - ready_at timestamptz, - deleted_at timestamptz, - last_error text, - version bigint NOT NULL DEFAULT 1, - created_at timestamptz NOT NULL DEFAULT now(), - updated_at timestamptz NOT NULL DEFAULT now(), - UNIQUE (storage_provider_id,bucket_name,object_key), - CHECK ((owner_type='installation' AND application_id IS NULL AND owner_id IS NULL) OR - (owner_type='application' AND application_id IS NOT NULL AND owner_id IS NULL) OR - (owner_type IN ('user','workspace') AND application_id IS NOT NULL AND owner_id IS NOT NULL)), - CHECK (visibility=bucket_role), - CHECK ((status='pending' AND upload_expires_at IS NOT NULL) OR status<>'pending') -); -CREATE INDEX storage_objects_application ON storage_objects(application_id,owner_type,owner_id,status,created_at DESC); -CREATE INDEX storage_objects_provider ON storage_objects(storage_provider_id,status,created_at DESC); -CREATE INDEX storage_objects_pending ON storage_objects(upload_expires_at) WHERE status='pending'; - --- +goose StatementBegin -CREATE FUNCTION enforce_storage_object_scope() RETURNS trigger LANGUAGE plpgsql AS $$ -DECLARE - provider_application uuid; - provider_organization uuid; - provider_public_bucket text; - provider_private_bucket text; -BEGIN - SELECT application_id,organization_id,public_bucket,private_bucket - INTO provider_application,provider_organization,provider_public_bucket,provider_private_bucket - FROM storage_providers WHERE id=NEW.storage_provider_id; - IF NEW.bucket_role='public' AND provider_public_bucket IS DISTINCT FROM NEW.bucket_name THEN - RAISE EXCEPTION 'public object bucket must match its storage provider'; - END IF; - IF NEW.bucket_role='private' AND provider_private_bucket IS DISTINCT FROM NEW.bucket_name THEN - RAISE EXCEPTION 'private object bucket must match its storage provider'; - END IF; - IF NEW.owner_type='installation' THEN - IF provider_application IS NOT NULL OR provider_organization IS NOT NULL THEN - RAISE EXCEPTION 'installation assets require an installation storage provider'; - END IF; - RETURN NEW; - END IF; - IF provider_application IS NOT NULL AND provider_application<>NEW.application_id THEN - RAISE EXCEPTION 'storage provider belongs to another application'; - END IF; - IF provider_organization IS NOT NULL AND NOT EXISTS ( - SELECT 1 FROM applications a WHERE a.id=NEW.application_id AND a.organization_id=provider_organization - ) THEN - RAISE EXCEPTION 'storage provider belongs to another organization'; - END IF; - IF NEW.owner_type='user' AND NOT EXISTS ( - SELECT 1 FROM users u WHERE u.id=NEW.owner_id AND u.application_id=NEW.application_id AND u.status='active' - ) THEN - RAISE EXCEPTION 'storage object user must be active in the application'; - END IF; - IF NEW.owner_type='workspace' AND NOT EXISTS ( - SELECT 1 FROM workspaces w WHERE w.id=NEW.owner_id AND w.application_id=NEW.application_id AND w.deleted_at IS NULL - ) THEN - RAISE EXCEPTION 'storage object workspace must be active in the application'; - END IF; - RETURN NEW; -END; -$$; --- +goose StatementEnd -CREATE TRIGGER storage_object_scope_guard BEFORE INSERT OR UPDATE OF application_id,storage_provider_id,owner_type,owner_id,bucket_role,bucket_name -ON storage_objects FOR EACH ROW EXECUTE FUNCTION enforce_storage_object_scope(); - -CREATE TABLE notification_template_assets ( - notification_template_id uuid NOT NULL REFERENCES notification_templates(id) ON DELETE CASCADE, - storage_object_id uuid NOT NULL REFERENCES storage_objects(id), - created_at timestamptz NOT NULL DEFAULT now(), - PRIMARY KEY (notification_template_id,storage_object_id) -); - --- +goose StatementBegin -CREATE FUNCTION enforce_notification_template_asset_scope() RETURNS trigger LANGUAGE plpgsql AS $$ -BEGIN - IF NOT EXISTS ( - SELECT 1 FROM notification_templates t JOIN storage_objects o ON o.id=NEW.storage_object_id - WHERE t.id=NEW.notification_template_id AND o.status='ready' AND o.visibility='public' - AND o.content_type IN ('image/png','image/jpeg','image/gif') - AND ((t.application_id IS NULL AND o.owner_type='installation') OR - (t.application_id IS NOT NULL AND ( - (o.application_id=t.application_id AND o.owner_type='application') OR - o.owner_type='installation' - ))) - ) THEN - RAISE EXCEPTION 'template assets must be ready public images from the template scope'; - END IF; - RETURN NEW; -END; -$$; --- +goose StatementEnd -CREATE TRIGGER notification_template_asset_scope_guard BEFORE INSERT OR UPDATE ON notification_template_assets -FOR EACH ROW EXECUTE FUNCTION enforce_notification_template_asset_scope(); - -UPDATE roles SET permissions=array_append(permissions,'storage:read') -WHERE built_in AND key='workspace_member' AND NOT ('storage:read'=ANY(permissions)); - -INSERT INTO event_type_definitions(id,application_id,name,description,source,example_subject,data_schema,example_data) VALUES -(gen_random_uuid(),NULL,'storage.object.upload_requested','An object upload was authorized.','platform93','storage_object/01900000-0000-7000-8000-000000000020','{"type":"object","required":["object_id","owner_type","visibility","size_bytes"],"properties":{"object_id":{"type":"string","format":"uuid"},"owner_type":{"enum":["installation","application","user","workspace"]},"visibility":{"enum":["public","private"]},"size_bytes":{"type":"integer","minimum":1}},"additionalProperties":false}'::jsonb,'{"object_id":"01900000-0000-7000-8000-000000000020","owner_type":"workspace","visibility":"private","size_bytes":1024}'::jsonb), -(gen_random_uuid(),NULL,'storage.object.ready','An object upload completed and was verified.','platform93','storage_object/01900000-0000-7000-8000-000000000020','{"type":"object","required":["object_id","owner_type","visibility","size_bytes"],"properties":{"object_id":{"type":"string","format":"uuid"},"owner_type":{"enum":["installation","application","user","workspace"]},"visibility":{"enum":["public","private"]},"size_bytes":{"type":"integer","minimum":1}},"additionalProperties":false}'::jsonb,'{"object_id":"01900000-0000-7000-8000-000000000020","owner_type":"workspace","visibility":"private","size_bytes":1024}'::jsonb), -(gen_random_uuid(),NULL,'storage.object.deleted','An object was deleted.','platform93','storage_object/01900000-0000-7000-8000-000000000020','{"type":"object","required":["object_id","owner_type","visibility","size_bytes"],"properties":{"object_id":{"type":"string","format":"uuid"},"owner_type":{"enum":["installation","application","user","workspace"]},"visibility":{"enum":["public","private"]},"size_bytes":{"type":"integer","minimum":1}},"additionalProperties":false}'::jsonb,'{"object_id":"01900000-0000-7000-8000-000000000020","owner_type":"workspace","visibility":"private","size_bytes":1024}'::jsonb), -(gen_random_uuid(),NULL,'storage.provider.verified','An S3-compatible storage provider was verified.','platform93','storage_provider/01900000-0000-7000-8000-000000000021','{"type":"object","required":["provider_id","scope","public_enabled","private_enabled"],"properties":{"provider_id":{"type":"string","format":"uuid"},"scope":{"enum":["installation","organization","application"]},"public_enabled":{"type":"boolean"},"private_enabled":{"type":"boolean"}},"additionalProperties":false}'::jsonb,'{"provider_id":"01900000-0000-7000-8000-000000000021","scope":"application","public_enabled":true,"private_enabled":true}'::jsonb), -(gen_random_uuid(),NULL,'storage.provider.disabled','An S3-compatible storage provider was disabled in Platform93.','platform93','storage_provider/01900000-0000-7000-8000-000000000021','{"type":"object","required":["provider_id","scope","public_enabled","private_enabled"],"properties":{"provider_id":{"type":"string","format":"uuid"},"scope":{"enum":["installation","organization","application"]},"public_enabled":{"type":"boolean"},"private_enabled":{"type":"boolean"}},"additionalProperties":false}'::jsonb,'{"provider_id":"01900000-0000-7000-8000-000000000021","scope":"application","public_enabled":true,"private_enabled":true}'::jsonb) -ON CONFLICT(application_id,name) DO NOTHING; - --- +goose Down -UPDATE roles SET permissions=array_remove(permissions,'storage:read') WHERE built_in AND key='workspace_member'; -DELETE FROM event_type_definitions WHERE application_id IS NULL AND name IN ( - 'storage.object.upload_requested','storage.object.ready','storage.object.deleted', - 'storage.provider.verified','storage.provider.disabled' -); -DROP TRIGGER notification_template_asset_scope_guard ON notification_template_assets; -DROP FUNCTION enforce_notification_template_asset_scope(); -DROP TABLE notification_template_assets; -DROP TRIGGER storage_object_scope_guard ON storage_objects; -DROP FUNCTION enforce_storage_object_scope(); -DROP TABLE storage_objects; -DROP TABLE storage_providers; diff --git a/package.json b/package.json index 79757f9..f0fd2b3 100644 --- a/package.json +++ b/package.json @@ -9,21 +9,26 @@ "pnpm": { "overrides": { "js-yaml": "4.3.1", + "nanoid": "3.3.18", "postcss": "8.5.23", "sharp": "0.35.0" } }, "scripts": { "build": "pnpm build:packages && pnpm --filter @platform93/admin build", - "build:packages": "pnpm --filter @supaapps/platform93-sdk build && pnpm --filter @supaapps/platform93-auth build && pnpm --filter @supaapps/platform93-react build && pnpm --filter @supaapps/platform93-server build && pnpm --filter @supaapps/platform93-events build", + "build:packages": "pnpm --filter @supaapps/platform93-sdk build && pnpm --filter @supaapps/platform93-auth build && pnpm --filter @supaapps/platform93-expo build && pnpm --filter @supaapps/platform93-react build && pnpm --filter @supaapps/platform93-server build && pnpm --filter @supaapps/platform93-events build", "generate": "node scripts/project-openapi-30.mjs && go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@v2.7.0 -config api/openapi/oapi-codegen.yaml api/openapi/platform93.openapi30.yaml && pnpm --filter @supaapps/platform93-sdk generate", "check:routes": "node scripts/check-route-contract.mjs", + "check:contracts": "node scripts/check-openapi-contract-quality.mjs", + "check:terminology": "node scripts/check-terminology.mjs", "lint": "pnpm build:packages && pnpm -r lint", "test": "pnpm build:packages && pnpm -r test", "typecheck": "pnpm build:packages && pnpm --filter @platform93/admin typecheck" }, "devDependencies": { + "@redocly/cli": "2.46.1", "ajv": "^8.17.1", - "ajv-formats": "^3.0.1" + "ajv-formats": "^3.0.1", + "js-yaml": "4.3.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8be1fb4..ac85f85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,7 @@ settings: overrides: js-yaml: 4.3.1 + nanoid: 3.3.18 postcss: 8.5.23 sharp: 0.35.0 @@ -13,12 +14,18 @@ importers: .: devDependencies: + '@redocly/cli': + specifier: 2.46.1 + version: 2.46.1 ajv: specifier: ^8.17.1 version: 8.20.0 ajv-formats: specifier: ^3.0.1 version: 3.0.1(ajv@8.20.0) + js-yaml: + specifier: 4.3.1 + version: 4.3.1 sdk/typescript/auth: dependencies: @@ -39,6 +46,19 @@ importers: specifier: ^5.9.2 version: 5.9.3 + sdk/typescript/expo: + dependencies: + '@supaapps/platform93-auth': + specifier: workspace:* + version: link:../auth + '@supaapps/platform93-sdk': + specifier: workspace:* + version: link:../sdk + devDependencies: + typescript: + specifier: ^5.9.2 + version: 5.9.3 + sdk/typescript/react: dependencies: '@supaapps/platform93-auth': @@ -66,6 +86,9 @@ importers: sdk/typescript/server: dependencies: + '@supaapps/platform93-sdk': + specifier: workspace:* + version: link:../sdk jose: specifier: ^6.0.12 version: 6.2.8 @@ -430,6 +453,11 @@ packages: engines: {node: '>=20'} hasBin: true + '@redocly/cli@2.46.1': + resolution: {integrity: sha512-FSUSq2FU8VN7DmTobTmq7zb3zPnDkRKSMd3n38D62JFJUUZKnLMQtn7BUhsD2dCFH2WgF05I3fbN7QHDQyCBeA==} + engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'} + hasBin: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -1451,8 +1479,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.17: - resolution: {integrity: sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==} + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -2200,6 +2228,8 @@ snapshots: dependencies: playwright: 1.62.1 + '@redocly/cli@2.46.1': {} + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.16.1': {} @@ -3386,7 +3416,7 @@ snapshots: ms@2.1.3: {} - nanoid@3.3.17: {} + nanoid@3.3.18: {} napi-postinstall@0.3.4: {} @@ -3546,7 +3576,7 @@ snapshots: postcss@8.5.23: dependencies: - nanoid: 3.3.17 + nanoid: 3.3.18 picocolors: 1.1.1 source-map-js: 1.2.1 diff --git a/schemas/events/migration-parity-1.0.schema.json b/schemas/events/migration-parity-1.0.schema.json new file mode 100644 index 0000000..7c5ecda --- /dev/null +++ b/schemas/events/migration-parity-1.0.schema.json @@ -0,0 +1,132 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://platform93.dev/schemas/events/migration-parity-1.0.schema.json", + "title": "Platform93 migration-parity lifecycle event data", + "$defs": { + "nullableExternalReference": { + "type": ["string", "null"], + "minLength": 1, + "maxLength": 255 + }, + "invitation": { + "type": "object", + "required": ["invitation_id", "status"], + "properties": { + "invitation_id": { "type": "string", "format": "uuid" }, + "workspace_id": { "type": ["string", "null"], "format": "uuid" }, + "user_id": { "type": "string", "format": "uuid" }, + "status": { "enum": ["pending", "accepted", "revoked", "expired"] }, + "expires_at": { "type": "string", "format": "date-time" }, + "application_role_keys": { "type": "array", "items": { "type": "string" } }, + "workspace_role_keys": { "type": "array", "items": { "type": "string" } } + }, + "additionalProperties": false + }, + "workspace": { + "type": "object", + "required": ["workspace_id", "status"], + "properties": { + "workspace_id": { "type": "string", "format": "uuid" }, + "status": { "enum": ["active", "archived", "removed"] }, + "owner_user_id": { "type": "string", "format": "uuid" }, + "user_id": { "type": "string", "format": "uuid" }, + "key": { "type": "string" }, + "name": { "type": "string" }, + "role_keys": { "type": "array", "items": { "type": "string" } }, + "changed_fields": { "type": "array", "items": { "type": "string" } } + }, + "additionalProperties": false + }, + "permissionGrant": { + "type": "object", + "required": ["grant_id", "subject_type", "subject_id", "workspace_id", "permission", "canonical_scope"], + "properties": { + "grant_id": { "type": "string", "format": "uuid" }, + "subject_type": { "enum": ["user", "client"] }, + "subject_id": { "type": "string", "format": "uuid" }, + "workspace_id": { "type": ["string", "null"], "format": "uuid" }, + "permission": { "type": "string", "minLength": 1, "maxLength": 160 }, + "canonical_scope": { "type": "string", "minLength": 1 } + }, + "additionalProperties": false + }, + "controlUserIdentity": { + "type": "object", + "required": ["control_user_id", "provider"], + "properties": { + "control_user_id": { "type": "string", "format": "uuid" }, + "provider": { "enum": ["google", "apple"] } + }, + "additionalProperties": false + }, + "controlUserInvitation": { + "type": "object", + "required": ["invitation_id", "role", "onboarding_method", "status"], + "properties": { + "invitation_id": { "type": "string", "format": "uuid" }, + "organization_id": { "type": ["string", "null"], "format": "uuid" }, + "control_user_id": { "type": "string", "format": "uuid" }, + "role": { "enum": ["owner", "admin", "member", "auditor"] }, + "onboarding_method": { "enum": ["email", "google", "apple"] }, + "status": { "enum": ["pending", "accepted", "revoked"] } + }, + "additionalProperties": false + }, + "controlAuthPolicy": { + "type": "object", + "required": ["email_code_enabled", "magic_link_enabled", "password_enabled"], + "properties": { + "email_code_enabled": { "type": "boolean" }, + "magic_link_enabled": { "type": "boolean" }, + "password_enabled": { "type": "boolean" } + }, + "additionalProperties": false + }, + "controlAuthProvider": { + "type": "object", + "required": ["provider", "enabled"], + "properties": { + "provider": { "enum": ["google", "apple"] }, + "enabled": { "type": "boolean" } + }, + "additionalProperties": false + }, + "entitlement": { + "type": "object", + "required": ["grant_id"], + "properties": { + "grant_id": { "type": "string", "format": "uuid" }, + "subject_type": { "enum": ["user", "workspace"] }, + "subject_id": { "type": "string", "format": "uuid" }, + "status": { "enum": ["active", "revoked", "expired"] }, + "external_reference": { "$ref": "#/$defs/nullableExternalReference" }, + "expires_at": { "type": ["string", "null"], "format": "date-time" }, + "reason": { "type": "string" } + }, + "additionalProperties": false + }, + "billing": { + "type": "object", + "required": ["status", "external_reference"], + "properties": { + "subscription_id": { "type": "string", "format": "uuid" }, + "invoice_id": { "type": "string", "format": "uuid" }, + "payment_id": { "type": "string", "format": "uuid" }, + "refund_id": { "type": "string", "format": "uuid" }, + "dispute_id": { "type": "string", "format": "uuid" }, + "subject_type": { "enum": ["user", "workspace"] }, + "subject_id": { "type": "string", "format": "uuid" }, + "status": { "type": "string", "minLength": 1 }, + "external_reference": { "$ref": "#/$defs/nullableExternalReference" } + }, + "oneOf": [ + { "required": ["subscription_id"] }, + { "required": ["invoice_id"] }, + { "required": ["payment_id"] }, + { "required": ["refund_id"] }, + { "required": ["dispute_id"] } + ], + "additionalProperties": false + } + } +} diff --git a/scripts/check-route-contract.mjs b/scripts/check-route-contract.mjs index d99a1f0..31cd9b8 100644 --- a/scripts/check-route-contract.mjs +++ b/scripts/check-route-contract.mjs @@ -7,7 +7,7 @@ const routePattern = /r(?:\.With\([^\n]*?\))?\.(Get|Post|Put|Patch|Delete)\("([^ for (const match of server.matchAll(routePattern)) { let path = match[2]; if (!path.startsWith("/")) continue; - if (/^\/(setup|control|management|applications)(\/|$)/.test(path)) { + if (/^\/(setup|control|management|applications|auth)(\/|$)/.test(path)) { path = `/v1${path}`; } mounted.add(`${match[1].toUpperCase()} ${path}`); diff --git a/scripts/project-openapi-30.mjs b/scripts/project-openapi-30.mjs index 4a5b266..1c397ee 100644 --- a/scripts/project-openapi-30.mjs +++ b/scripts/project-openapi-30.mjs @@ -1,12 +1,31 @@ import { readFileSync, writeFileSync } from "node:fs"; +import yaml from "js-yaml"; const sourcePath = "api/openapi/platform93.yaml"; const outputPath = "api/openapi/platform93.openapi30.yaml"; -const source = readFileSync(sourcePath, "utf8"); -const projected = source - .replace("openapi: 3.1.0", "# Generated from platform93.yaml; do not edit.\nopenapi: 3.0.3") - .replaceAll('type: [string, "null"]', "type: string, nullable: true") - .replaceAll('type: [object, "null"]', "type: object, nullable: true") - .replaceAll('type: [integer, "null"]', "type: integer, nullable: true") - .replace(/const: ([^ }]+)/g, "enum: [$1]"); -writeFileSync(outputPath, projected); +const document = yaml.load(readFileSync(sourcePath, "utf8")); + +function project(value) { + if (Array.isArray(value)) return value.map(project); + if (!value || typeof value !== "object") return value; + + const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, project(item)])); + if (Array.isArray(result.type) && result.type.includes("null")) { + const concreteTypes = result.type.filter((type) => type !== "null"); + if (concreteTypes.length !== 1) throw new Error(`Unsupported nullable type union: ${result.type.join(", ")}`); + result.type = concreteTypes[0]; + result.nullable = true; + } + if (Object.hasOwn(result, "const")) { + result.enum = [result.const]; + delete result.const; + } + return result; +} + +const projected = project(document); +projected.openapi = "3.0.3"; +writeFileSync( + outputPath, + `# Generated from platform93.yaml; do not edit.\n${yaml.dump(projected, { noRefs: true, lineWidth: 160, noCompatMode: true, sortKeys: false })}`, +); diff --git a/scripts/set-release-version.mjs b/scripts/set-release-version.mjs index 1680d13..8dd264d 100644 --- a/scripts/set-release-version.mjs +++ b/scripts/set-release-version.mjs @@ -5,7 +5,7 @@ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version ?? "")) { throw new Error("usage: node scripts/set-release-version.mjs "); } -const manifests = ["sdk", "auth", "react", "server", "events"].map( +const manifests = ["sdk", "auth", "expo", "react", "server", "events"].map( (name) => `sdk/typescript/${name}/package.json`, ); for (const path of manifests) { diff --git a/sdk/go/auth/auth.go b/sdk/go/auth/auth.go index 2dedb1b..c3fc3a0 100644 --- a/sdk/go/auth/auth.go +++ b/sdk/go/auth/auth.go @@ -11,28 +11,42 @@ import ( "io" "math/big" "net/http" + "regexp" "strings" "sync" "time" ) type Claims struct { - Issuer string `json:"iss"` - Subject string `json:"sub"` - Audience []string `json:"aud"` - ExpiresAt int64 `json:"exp"` - IssuedAt int64 `json:"iat"` - NotBefore int64 `json:"nbf"` - ApplicationID string `json:"application_id"` - TokenKind string `json:"token_kind"` - ActorType string `json:"actor_type"` - Scope string `json:"scope"` - Locale string `json:"locale,omitempty"` - EmailVerified bool `json:"email_verified"` - IsOrgVerified bool `json:"is_org_verified"` - Actor *Actor `json:"act,omitempty"` + Issuer string `json:"iss"` + Subject string `json:"sub"` + Audience []string `json:"aud"` + ExpiresAt int64 `json:"exp"` + IssuedAt int64 `json:"iat"` + NotBefore int64 `json:"nbf"` + ApplicationID string `json:"application_id"` + TokenKind string `json:"token_kind"` + ActorType string `json:"actor_type"` + Scope string `json:"scope"` + Roles RoleClaims `json:"roles"` + Locale string `json:"locale,omitempty"` + EmailVerified bool `json:"email_verified"` + IsOrgVerified bool `json:"is_org_verified"` + CustomClaims map[string]any `json:"custom_claims,omitempty"` + Actor *Actor `json:"act,omitempty"` } +type RoleClaims struct { + Application []string `json:"application"` + Workspaces map[string][]string `json:"workspaces"` +} + +var ( + permissionSegment = regexp.MustCompile(`^[a-z0-9][a-z0-9._-]{0,63}$`) + roleKey = regexp.MustCompile(`^[a-z][a-z0-9_-]{0,62}$`) + workspaceKey = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`) +) + type Actor struct { Subject string `json:"sub"` Type string `json:"type"` @@ -80,9 +94,15 @@ func (v *Verifier) Verify(ctx context.Context, token string) (Claims, error) { if json.Unmarshal(payload, &claims) != nil || claims.Issuer != strings.TrimRight(v.Issuer, "/") || claims.Subject == "" || claims.IssuedAt == 0 || claims.IssuedAt > now.Add(30*time.Second).Unix() || claims.ApplicationID != v.ApplicationID || claims.ExpiresAt <= now.Unix() || claims.NotBefore == 0 || claims.NotBefore > now.Add(30*time.Second).Unix() || !contains(claims.Audience, v.Audience) || claims.TokenKind == "access" && claims.ActorType != "user" || claims.TokenKind == "machine" && claims.ActorType != "client" || claims.TokenKind != "access" && claims.TokenKind != "machine" { return Claims{}, fmt.Errorf("token claims rejected") } - if claims.Actor != nil && (claims.TokenKind != "access" || claims.Actor.Type != "operator" || claims.Actor.Subject == "") { + if claims.Actor != nil && (claims.TokenKind != "access" || claims.Actor.Type != "control_user" || claims.Actor.Subject == "") { return Claims{}, fmt.Errorf("delegated token actor rejected") } + if !validScopeClaim(claims.Scope, v.ApplicationID) || !validRoleClaims(claims.Roles) { + return Claims{}, fmt.Errorf("token authorization claims rejected") + } + if claims.Actor != nil && (len(claims.Roles.Application) != 0 || len(claims.Roles.Workspaces) != 0) { + return Claims{}, fmt.Errorf("delegated token roles rejected") + } return claims, nil } func (v *Verifier) key(ctx context.Context, kid string) (*rsa.PublicKey, error) { @@ -152,7 +172,10 @@ func (c Claims) HasPermission(permission string) bool { } func permissionMatches(granted, wanted string) bool { - if granted == wanted || granted == "*" { + if !validAbsolutePermission(granted) || !validAbsolutePermission(wanted) { + return false + } + if granted == wanted { return true } if !strings.HasSuffix(granted, "/*") { @@ -161,3 +184,75 @@ func permissionMatches(granted, wanted string) bool { base := strings.TrimSuffix(granted, "/*") return wanted == base || strings.HasPrefix(wanted, base+"/") } + +func validScopeClaim(scope, applicationID string) bool { + if scope == "" { + return true + } + if scope != strings.TrimSpace(scope) || strings.ContainsAny(scope, "\t\r\n") || strings.Contains(scope, " ") { + return false + } + seen := map[string]struct{}{} + prefix := "/applications/" + applicationID + "/" + for _, value := range strings.Split(scope, " ") { + if _, duplicate := seen[value]; duplicate { + return false + } + seen[value] = struct{}{} + if value == "openid" || value == "profile" || value == "email" || value == "offline_access" { + continue + } + if !strings.HasPrefix(value, prefix) || !validAbsolutePermission(value) { + return false + } + } + return true +} + +func validAbsolutePermission(value string) bool { + if !strings.HasPrefix(value, "/") || strings.ContainsAny(value, " :\\%\t\r\n") { + return false + } + segments := strings.Split(value[1:], "/") + if len(segments) < 3 { + return false + } + for index, segment := range segments { + if segment == "*" { + if index != len(segments)-1 { + return false + } + continue + } + if !permissionSegment.MatchString(segment) { + return false + } + } + return true +} + +func validRoleClaims(roles RoleClaims) bool { + if roles.Application == nil || roles.Workspaces == nil || !uniqueRoles(roles.Application) { + return false + } + for workspaceID, values := range roles.Workspaces { + if !workspaceKey.MatchString(workspaceID) || values == nil || !uniqueRoles(values) { + return false + } + } + return true +} + +func uniqueRoles(values []string) bool { + seen := map[string]struct{}{} + for _, value := range values { + if !roleKey.MatchString(value) { + return false + } + if _, duplicate := seen[value]; duplicate { + return false + } + seen[value] = struct{}{} + } + return true +} diff --git a/sdk/go/auth/conformance_test.go b/sdk/go/auth/conformance_test.go index 1c51e63..4108cb7 100644 --- a/sdk/go/auth/conformance_test.go +++ b/sdk/go/auth/conformance_test.go @@ -62,14 +62,16 @@ func fixtureToken(t *testing.T, mutation, issuer string, fixture jwtFixture, key now := time.Now().Unix() header := map[string]any{"alg": "RS256", "typ": "JWT", "kid": "primary"} claims := map[string]any{"iss": issuer, "sub": "user-1", "aud": []string{fixture.Audience}, "exp": now + 300, "iat": now, "nbf": now - 1, - "application_id": fixture.ApplicationID, "token_kind": "access", "actor_type": "user", "scope": "/applications/app/profile/read"} + "application_id": fixture.ApplicationID, "token_kind": "access", "actor_type": "user", "scope": "/applications/" + fixture.ApplicationID + "/profile/read", + "roles": map[string]any{"application": []string{"member"}, "workspaces": map[string]any{}}} signingKey := key switch mutation { case "machine": claims["token_kind"] = "machine" claims["actor_type"] = "client" case "delegated": - claims["act"] = map[string]any{"sub": "operator-1", "type": "operator"} + claims["act"] = map[string]any{"sub": "control_user-1", "type": "control_user"} + claims["roles"] = map[string]any{"application": []string{}, "workspaces": map[string]any{}} case "wrong_issuer": claims["iss"] = "https://wrong.example" case "wrong_audience": @@ -90,8 +92,28 @@ func fixtureToken(t *testing.T, mutation, issuer string, fixture jwtFixture, key delete(claims, "token_kind") case "missing_actor_type": delete(claims, "actor_type") - case "operator_actor": - claims["actor_type"] = "operator" + case "missing_roles": + delete(claims, "roles") + case "space_injected_scope": + claims["scope"] = claims["scope"].(string) + " /applications/" + fixture.ApplicationID + "/billing/write" + case "tab_injected_scope": + claims["scope"] = claims["scope"].(string) + "\t/applications/" + fixture.ApplicationID + "/billing/write" + case "unicode_injected_scope": + claims["scope"] = claims["scope"].(string) + "\u200b/applications/" + fixture.ApplicationID + "/billing/write" + case "encoded_space_scope": + claims["scope"] = "/applications/" + fixture.ApplicationID + "/billing%20write" + case "cross_application_scope": + claims["scope"] = "/applications/01900000-0000-7000-8000-000000000000/billing/read" + case "embedded_wildcard_scope": + claims["scope"] = "/applications/" + fixture.ApplicationID + "/billing/*/write" + case "duplicate_scope": + claims["scope"] = claims["scope"].(string) + " " + claims["scope"].(string) + case "invalid_roles": + claims["roles"] = map[string]any{"application": []string{"billing admin"}, "workspaces": map[string]any{}} + case "delegated_roles": + claims["act"] = map[string]any{"sub": "control_user-1", "type": "control_user"} + case "control_user_actor": + claims["actor_type"] = "control_user" case "wrong_algorithm": header["alg"] = "HS256" case "missing_kid": @@ -101,7 +123,7 @@ func fixtureToken(t *testing.T, mutation, issuer string, fixture jwtFixture, key case "wrong_signature": signingKey = wrongKey case "delegated_wrong_actor_type": - claims["act"] = map[string]any{"sub": "operator-1", "type": "user"} + claims["act"] = map[string]any{"sub": "control_user-1", "type": "user"} } return signFixtureToken(t, header, claims, signingKey) } diff --git a/sdk/go/client/client.go b/sdk/go/client/client.go new file mode 100644 index 0000000..79a5a10 --- /dev/null +++ b/sdk/go/client/client.go @@ -0,0 +1,364 @@ +// Package client provides a server-side Platform93 machine client. +package client + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "sync" + "time" +) + +type Client struct { + BaseURL string + ApplicationID string + ClientID string + ClientSecret string + Scopes []string + HTTPClient *http.Client + + mu sync.Mutex + token string + expiresAt time.Time +} + +type Page[T any] struct { + Items []T `json:"items"` + NextCursor *string `json:"next_cursor"` +} + +type Notification struct { + TemplateKey string `json:"template_key"` + UserID string `json:"user_id,omitempty"` + Recipient string `json:"recipient,omitempty"` + Locale string `json:"locale,omitempty"` + Variables map[string]any `json:"variables,omitempty"` + Attachments []Attachment `json:"attachments,omitempty"` +} + +type Attachment struct { + Filename string `json:"filename"` + ContentType string `json:"content_type"` + ContentBase64 string `json:"content_base64"` +} + +type QueuedNotification struct { + ID string `json:"id"` + Status string `json:"status"` + RequestedLocale string `json:"requested_locale"` + ResolvedLocale string `json:"resolved_locale"` + FallbackUsed bool `json:"fallback_used"` +} + +type User struct { + ID string `json:"id"` + ApplicationID string `json:"application_id"` + Email string `json:"email"` + FirstName string `json:"first_name"` + LastName string `json:"last_name"` + Username *string `json:"username"` + Locale string `json:"locale"` + EmailVerified bool `json:"email_verified"` + OrganizationOK bool `json:"is_org_verified"` + Status string `json:"status"` + CustomAttributes json.RawMessage `json:"custom_attributes"` + Version int64 `json:"version"` +} + +type Workspace struct { + ID string `json:"id"` + ApplicationID string `json:"application_id"` + OwnerUserID string `json:"owner_user_id"` + Key string `json:"key"` + Name string `json:"name"` + Metadata json.RawMessage `json:"metadata"` + Status string `json:"status"` + Version int64 `json:"version"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +type WorkspaceAccess struct { + Type string `json:"type"` + WorkspaceID string `json:"workspace_id"` + UserID *string `json:"user_id"` + Email *string `json:"email"` + RoleKeys []string `json:"role_keys"` + InvitationID *string `json:"invitation_id"` + Status string `json:"status"` + ExpiresAt *time.Time `json:"expires_at"` +} + +type EntitlementGrant struct { + ID string `json:"id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + SourceType string `json:"source_type"` + SourceID *string `json:"source_id"` + FeatureValues json.RawMessage `json:"feature_values"` + Configuration json.RawMessage `json:"configuration"` + StartsAt time.Time `json:"starts_at"` + ExpiresAt *time.Time `json:"expires_at"` + RevokedAt *time.Time `json:"revoked_at"` + ExternalReference *string `json:"external_reference"` +} + +type BillingProfile struct { + ID string `json:"id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + Name *string `json:"name"` + Email *string `json:"email"` + TaxID *string `json:"tax_id"` + DefaultAddressID *string `json:"default_address_id"` + Version int64 `json:"version"` +} + +type Subscription struct { + ID string `json:"id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + PriceID string `json:"price_id"` + ProviderID string `json:"provider_id"` + Status string `json:"status"` + CurrentPeriodEnd *time.Time `json:"current_period_end"` + CancelAtPeriodEnd bool `json:"cancel_at_period_end"` + ExternalReference *string `json:"external_reference"` +} + +type BillingSummary struct { + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + BillingProfile *BillingProfile `json:"billing_profile"` + Subscriptions []Subscription `json:"subscriptions"` +} + +type CustomEvent struct { + Type string `json:"type"` + Subject string `json:"subject"` + Data json.RawMessage `json:"data"` + CorrelationID string `json:"correlation_id,omitempty"` + CausationID string `json:"causation_id,omitempty"` +} + +type PublishedEvent struct { + ID string `json:"id"` + SpecVersion string `json:"specversion"` + Source string `json:"source"` + Type string `json:"type"` + Subject string `json:"subject"` + SchemaVersion string `json:"schema_version"` + Data json.RawMessage `json:"data"` +} + +type Invitation struct { + ID string `json:"id"` + Email string `json:"email"` + WorkspaceID *string `json:"workspace_id"` + ApplicationRoleKeys []string `json:"application_role_keys"` + WorkspaceRoleKeys []string `json:"workspace_role_keys"` + Status string `json:"status"` + ExpiresAt time.Time `json:"expires_at"` + LastSentAt time.Time `json:"last_sent_at"` + ResendAvailableAt time.Time `json:"resend_available_at"` + AcceptedAt *time.Time `json:"accepted_at"` + RevokedAt *time.Time `json:"revoked_at"` +} + +type CreateInvitation struct { + Email string `json:"email"` + WorkspaceID string `json:"workspace_id,omitempty"` + ApplicationRoleKeys []string `json:"application_role_keys,omitempty"` + WorkspaceRoleKeys []string `json:"workspace_role_keys,omitempty"` + ExpiresIn int64 `json:"expires_in,omitempty"` +} + +func (c *Client) UpdateSecret(secret string) { + c.mu.Lock() + defer c.mu.Unlock() + c.ClientSecret = secret + c.token = "" + c.expiresAt = time.Time{} +} + +func (c *Client) SendNotification(ctx context.Context, input Notification, idempotencyKey string) (QueuedNotification, error) { + var output QueuedNotification + err := c.request(ctx, http.MethodPost, "/notifications", input, idempotencyKey, &output) + return output, err +} + +func (c *Client) CreateInvitation(ctx context.Context, input CreateInvitation) (Invitation, error) { + var output Invitation + err := c.request(ctx, http.MethodPost, "/invitations", input, "", &output) + return output, err +} + +func (c *Client) ListInvitations(ctx context.Context) (Page[Invitation], error) { + var output Page[Invitation] + err := c.request(ctx, http.MethodGet, "/invitations", nil, "", &output) + return output, err +} + +func (c *Client) GetInvitation(ctx context.Context, id string) (Invitation, error) { + var output Invitation + err := c.request(ctx, http.MethodGet, "/invitations/"+url.PathEscape(id), nil, "", &output) + return output, err +} + +func (c *Client) ResendInvitation(ctx context.Context, id string) (Invitation, error) { + var output Invitation + err := c.request(ctx, http.MethodPost, "/invitations/"+url.PathEscape(id)+"/resend", nil, "", &output) + return output, err +} + +func (c *Client) RevokeInvitation(ctx context.Context, id string) error { + return c.request(ctx, http.MethodDelete, "/invitations/"+url.PathEscape(id), nil, "", nil) +} + +func (c *Client) ListUsers(ctx context.Context) (Page[User], error) { + var output Page[User] + err := c.request(ctx, http.MethodGet, "/users", nil, "", &output) + return output, err +} + +func (c *Client) GetUser(ctx context.Context, id string) (User, error) { + var output User + err := c.request(ctx, http.MethodGet, "/users/"+url.PathEscape(id), nil, "", &output) + return output, err +} + +func (c *Client) ListWorkspaces(ctx context.Context) (Page[Workspace], error) { + var output Page[Workspace] + err := c.request(ctx, http.MethodGet, "/workspaces", nil, "", &output) + return output, err +} + +func (c *Client) GetWorkspace(ctx context.Context, id string) (Workspace, error) { + var output Workspace + err := c.request(ctx, http.MethodGet, "/service/workspaces/"+url.PathEscape(id), nil, "", &output) + return output, err +} + +func (c *Client) GetWorkspaceAccess(ctx context.Context, id string) (Page[WorkspaceAccess], error) { + var output Page[WorkspaceAccess] + err := c.request(ctx, http.MethodGet, "/service/workspaces/"+url.PathEscape(id)+"/access", nil, "", &output) + return output, err +} + +func (c *Client) SubjectEntitlements(ctx context.Context, subjectType, subjectID string) (Page[EntitlementGrant], error) { + var output Page[EntitlementGrant] + err := c.request(ctx, http.MethodGet, "/subjects/"+url.PathEscape(subjectType)+"/"+url.PathEscape(subjectID)+"/entitlements", nil, "", &output) + return output, err +} + +func (c *Client) SubjectBilling(ctx context.Context, subjectType, subjectID string) (BillingSummary, error) { + var output BillingSummary + err := c.request(ctx, http.MethodGet, "/subjects/"+url.PathEscape(subjectType)+"/"+url.PathEscape(subjectID)+"/billing", nil, "", &output) + return output, err +} + +func (c *Client) PublishEvent(ctx context.Context, input CustomEvent, idempotencyKey string) (PublishedEvent, error) { + var output PublishedEvent + err := c.request(ctx, http.MethodPost, "/events", input, idempotencyKey, &output) + return output, err +} + +func (c *Client) accessToken(ctx context.Context) (string, error) { + c.mu.Lock() + defer c.mu.Unlock() + if c.token != "" && time.Now().Before(c.expiresAt.Add(-30*time.Second)) { + return c.token, nil + } + if c.BaseURL == "" || c.ApplicationID == "" || c.ClientID == "" || c.ClientSecret == "" { + return "", fmt.Errorf("Platform93 machine client requires base URL, application ID, client ID, and client secret") + } + form := url.Values{"grant_type": {"client_credentials"}} + if len(c.Scopes) > 0 { + form.Set("scope", strings.Join(c.Scopes, " ")) + } + request, err := http.NewRequestWithContext(ctx, http.MethodPost, strings.TrimRight(c.BaseURL, "/")+"/oidc/token", strings.NewReader(form.Encode())) + if err != nil { + return "", err + } + request.SetBasicAuth(c.ClientID, c.ClientSecret) + request.Header.Set("Accept", "application/json") + request.Header.Set("Content-Type", "application/x-www-form-urlencoded") + response, err := c.httpClient().Do(request) + if err != nil { + return "", err + } + defer response.Body.Close() + if response.StatusCode < 200 || response.StatusCode >= 300 { + return "", responseError(response) + } + var payload struct { + AccessToken string `json:"access_token"` + ExpiresIn int64 `json:"expires_in"` + } + if err := json.NewDecoder(io.LimitReader(response.Body, 1<<20)).Decode(&payload); err != nil || payload.AccessToken == "" { + return "", fmt.Errorf("Platform93 token response is invalid") + } + if payload.ExpiresIn < 1 { + payload.ExpiresIn = 300 + } + c.token = payload.AccessToken + c.expiresAt = time.Now().Add(time.Duration(payload.ExpiresIn) * time.Second) + return c.token, nil +} + +func (c *Client) request(ctx context.Context, method, path string, input any, idempotencyKey string, output any) error { + var body io.Reader + if input != nil { + encoded, err := json.Marshal(input) + if err != nil { + return err + } + body = bytes.NewReader(encoded) + } + token, err := c.accessToken(ctx) + if err != nil { + return err + } + request, err := http.NewRequestWithContext(ctx, method, strings.TrimRight(c.BaseURL, "/")+"/v1/applications/"+url.PathEscape(c.ApplicationID)+path, body) + if err != nil { + return err + } + request.Header.Set("Accept", "application/json") + request.Header.Set("Authorization", "Bearer "+token) + if input != nil { + request.Header.Set("Content-Type", "application/json") + } + if idempotencyKey != "" { + request.Header.Set("Idempotency-Key", idempotencyKey) + } + response, err := c.httpClient().Do(request) + if err != nil { + return err + } + defer response.Body.Close() + if response.StatusCode < 200 || response.StatusCode >= 300 { + return responseError(response) + } + if output == nil || response.StatusCode == http.StatusNoContent { + _, _ = io.Copy(io.Discard, response.Body) + return nil + } + return json.NewDecoder(io.LimitReader(response.Body, 4<<20)).Decode(output) +} + +func responseError(response *http.Response) error { + excerpt, _ := io.ReadAll(io.LimitReader(response.Body, 4096)) + return fmt.Errorf("Platform93 request returned HTTP %d: %s", response.StatusCode, strings.TrimSpace(string(excerpt))) +} + +func (c *Client) httpClient() *http.Client { + if c.HTTPClient != nil { + return c.HTTPClient + } + return &http.Client{Timeout: 30 * time.Second} +} diff --git a/sdk/go/client/client_test.go b/sdk/go/client/client_test.go new file mode 100644 index 0000000..2c7535e --- /dev/null +++ b/sdk/go/client/client_test.go @@ -0,0 +1,54 @@ +package client + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "sync/atomic" + "testing" +) + +func TestClientCachesAndInvalidatesMachineToken(t *testing.T) { + t.Parallel() + var tokenRequests atomic.Int64 + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/oidc/token": + tokenRequests.Add(1) + clientID, secret, ok := r.BasicAuth() + if !ok || clientID != "machine" || secret != "secret" && secret != "rotated" { + http.Error(w, "invalid", http.StatusUnauthorized) + return + } + _ = json.NewEncoder(w).Encode(map[string]any{"access_token": "token", "expires_in": 300}) + case "/v1/applications/app/users": + if r.Header.Get("Authorization") != "Bearer token" { + http.Error(w, "missing token", http.StatusUnauthorized) + return + } + _ = json.NewEncoder(w).Encode(map[string]any{"items": []any{}, "next_cursor": nil}) + default: + http.NotFound(w, r) + } + })) + defer server.Close() + + client := &Client{BaseURL: server.URL, ApplicationID: "app", ClientID: "machine", ClientSecret: "secret"} + if _, err := client.ListUsers(context.Background()); err != nil { + t.Fatal(err) + } + if _, err := client.ListUsers(context.Background()); err != nil { + t.Fatal(err) + } + if tokenRequests.Load() != 1 { + t.Fatalf("expected one token exchange, got %d", tokenRequests.Load()) + } + client.UpdateSecret("rotated") + if _, err := client.ListUsers(context.Background()); err != nil { + t.Fatal(err) + } + if tokenRequests.Load() != 2 { + t.Fatalf("expected token cache invalidation after rotation, got %d exchanges", tokenRequests.Load()) + } +} diff --git a/sdk/go/webhooks/webhooks.go b/sdk/go/webhooks/webhooks.go index 2910417..2a92d58 100644 --- a/sdk/go/webhooks/webhooks.go +++ b/sdk/go/webhooks/webhooks.go @@ -1,6 +1,7 @@ package webhooks import ( + "context" "crypto/hmac" "crypto/sha256" "encoding/hex" @@ -27,9 +28,67 @@ type Event struct { Data json.RawMessage `json:"data"` } +type InvitationLifecycleData struct { + InvitationID string `json:"invitation_id"` + Status string `json:"status"` + WorkspaceID *string `json:"workspace_id,omitempty"` + UserID *string `json:"user_id,omitempty"` + ExpiresAt *string `json:"expires_at,omitempty"` +} + +type EntitlementLifecycleData struct { + GrantID string `json:"grant_id"` + Status string `json:"status,omitempty"` + SubjectType string `json:"subject_type,omitempty"` + SubjectID string `json:"subject_id,omitempty"` + ExternalReference *string `json:"external_reference,omitempty"` + ExpiresAt *string `json:"expires_at,omitempty"` + Reason string `json:"reason,omitempty"` +} + +type BillingLifecycleData struct { + SubscriptionID string `json:"subscription_id,omitempty"` + InvoiceID string `json:"invoice_id,omitempty"` + PaymentID string `json:"payment_id,omitempty"` + RefundID string `json:"refund_id,omitempty"` + DisputeID string `json:"dispute_id,omitempty"` + Status string `json:"status"` + SubjectType string `json:"subject_type,omitempty"` + SubjectID string `json:"subject_id,omitempty"` + ExternalReference *string `json:"external_reference"` +} + +type PermissionGrantLifecycleData struct { + GrantID string `json:"grant_id"` + SubjectType string `json:"subject_type"` + SubjectID string `json:"subject_id"` + WorkspaceID *string `json:"workspace_id"` + Permission string `json:"permission"` + CanonicalScope string `json:"canonical_scope"` +} + +type ControlUserIdentityData struct { + ControlUserID string `json:"control_user_id"` + Provider string `json:"provider"` +} + +type ControlInvitationData struct { + InvitationID string `json:"invitation_id"` + OrganizationID *string `json:"organization_id,omitempty"` + ControlUserID *string `json:"control_user_id,omitempty"` + Role string `json:"role"` + OnboardingMethod string `json:"onboarding_method"` + Status string `json:"status"` +} + var PlatformEventVersions = map[string]string{ "organization.created": "1.0", "organization.retired": "1.0", "organization.restored": "1.0", "application.created": "1.0", "application.retired": "1.0", "application.restored": "1.0", + "authorization.permission_grant.created": "1.0", "authorization.permission_grant.revoked": "1.0", + "control_user.identity_linked": "1.0", "control_user.identity_unlinked": "1.0", + "control_user.invitation_created": "1.0", "control_user.invitation_resent": "1.0", + "control_user.invitation_revoked": "1.0", "control_user.invitation_accepted": "1.0", + "control_auth.policy_updated": "1.0", "control_auth.provider_login_enabled": "1.0", "control_auth.provider_login_disabled": "1.0", "delegation.created": "1.0", "delegation.exchanged": "1.0", "delegation.revoked": "1.0", "entitlement.granted": "1.0", "local_entitlement_request.created": "1.0", "local_entitlement_request.approved": "1.0", "oauth.consent_revoked": "1.0", "platform93.webhook.test": "1.0", "user.created": "1.0", @@ -40,6 +99,34 @@ var PlatformEventVersions = map[string]string{ "user.pending_deletion": "1.0", "user.anonymized": "1.0", "user.deleted": "1.0", "user.suspended": "1.0", "user.restored": "1.0", "workspace.invitation_created": "1.0", "workspace.invitation_accepted": "1.0", "workspace.owner_transferred": "1.0", + "application_invitation.created": "1.0", "application_invitation.resent": "1.0", "application_invitation.revoked": "1.0", + "application_invitation.accepted": "1.0", "application_invitation.expired": "1.0", "user.updated": "1.0", + "workspace.created": "1.0", "workspace.updated": "1.0", "workspace.archived": "1.0", "workspace.member_added": "1.0", + "workspace.member_updated": "1.0", "workspace.member_removed": "1.0", "entitlement.adjusted": "1.0", + "entitlement.revoked": "1.0", "entitlement.restored": "1.0", "entitlement.expired": "1.0", "entitlement.effective_changed": "1.0", + "billing.subscription.updated": "1.0", "billing.invoice.updated": "1.0", "billing.payment.updated": "1.0", + "billing.refund.updated": "1.0", "billing.dispute.updated": "1.0", +} + +type Handler func(context.Context, Event) error + +// Dispatch routes a known Platform93 event by exact type and sends custom events +// to the optional fallback. It rejects unsupported major contract versions. +func Dispatch(ctx context.Context, event Event, handlers map[string]Handler, custom Handler) (bool, error) { + if event.IsCustom() { + if custom == nil { + return false, nil + } + return true, custom(ctx, event) + } + if !event.SupportsKnownVersion() { + return false, fmt.Errorf("unsupported Platform93 event contract %s version %s", event.Type, event.SchemaVersion) + } + handler := handlers[event.Type] + if handler == nil { + return false, nil + } + return true, handler(ctx, event) } func (e Event) IsPlatform() bool { return e.ContractSource == "platform93" } diff --git a/sdk/php/README.md b/sdk/php/README.md new file mode 100644 index 0000000..d45475a --- /dev/null +++ b/sdk/php/README.md @@ -0,0 +1,9 @@ +# supaapps/platform93 + +Framework-neutral Platform93 JWT and webhook verification, an optional Laravel +guard, and a backend-only `MachineClient` for application service APIs. + +The machine client exchanges OAuth client credentials and caches the short-lived +token. It supports template notifications, invitations, user/workspace reads, +entitlements, billing summaries, and custom events. Store its client secret in the +backend secret manager; never include it in a browser bundle, URL, or log. diff --git a/sdk/php/src/Claims.php b/sdk/php/src/Claims.php index 7d25a21..4636491 100644 --- a/sdk/php/src/Claims.php +++ b/sdk/php/src/Claims.php @@ -8,9 +8,11 @@ public function applicationId(): string { return (string) ($this->values['applic public function isOrgVerified(): bool { return (bool) ($this->values['is_org_verified'] ?? false); } public function emailVerified(): bool { return (bool) ($this->values['email_verified'] ?? false); } public function locale(): string { return (string) ($this->values['locale'] ?? ''); } + public function customClaims(): array { return is_array($this->values['custom_claims'] ?? null) ? $this->values['custom_claims'] : []; } + public function roles(): array { return (array) ($this->values['roles'] ?? []); } public function hasPermission(string $permission): bool { foreach (preg_split('/\s+/', trim((string) ($this->values['scope'] ?? ''))) ?: [] as $granted) { - if ($granted === '*' || $granted === $permission || (str_ends_with($granted, '/*') && ($permission === substr($granted, 0, -2) || str_starts_with($permission, substr($granted, 0, -1))))) return true; + if (Permission::matches($granted, $permission)) return true; } return false; } diff --git a/sdk/php/src/Laravel/Platform93User.php b/sdk/php/src/Laravel/Platform93User.php index b451784..51ae5b8 100644 --- a/sdk/php/src/Laravel/Platform93User.php +++ b/sdk/php/src/Laravel/Platform93User.php @@ -24,7 +24,7 @@ public function claims(): array { return $this->claims; } public function can(string $permission): bool { foreach (preg_split('/\s+/', trim((string) ($this->claims['scope'] ?? ''))) ?: [] as $granted) { - if ($granted === '*' || $granted === $permission || (str_ends_with($granted, '/*') && ($permission === substr($granted, 0, -2) || str_starts_with($permission, substr($granted, 0, -1))))) { + if (\Supaapps\Platform93\Permission::matches($granted, $permission)) { return true; } } diff --git a/sdk/php/src/MachineClient.php b/sdk/php/src/MachineClient.php new file mode 100644 index 0000000..f7dbd83 --- /dev/null +++ b/sdk/php/src/MachineClient.php @@ -0,0 +1,202 @@ +,attachments?:list} + * @phpstan-type QueuedNotification array{id:string,status:'queued'|'suppressed',requested_locale:string,resolved_locale:string,fallback_used:bool} + * @phpstan-type InvitationInput array{email:string,workspace_id?:string,application_role_keys?:list,workspace_role_keys?:list,expires_in?:int} + * @phpstan-type Invitation array{id:string,email:string,workspace_id:?string,application_role_keys:list,workspace_role_keys:list,status:string,expires_at:string} + * @phpstan-type InvitationResent array{id:string,last_sent_at:string,resend_available_at:string,expires_at:string} + * @phpstan-type User array{id:string,application_id:string,email:string,first_name:string,last_name:string,username:?string,locale:string,email_verified:bool,is_org_verified:bool,status:string,custom_attributes:array,version:int} + * @phpstan-type Workspace array{id:string,application_id:string,owner_user_id:string,key:string,name:string,metadata:array,status:string,version:int,created_at:string,updated_at:string} + * @phpstan-type WorkspaceAccess array{type:string,workspace_id:string,user_id:?string,email:?string,role_keys:list,invitation_id:?string,status:string,expires_at:?string} + * @phpstan-type EntitlementGrant array{id:string,subject_type:'user'|'workspace',subject_id:string,source_type:string,feature_values:array,configuration:array,starts_at:string,expires_at:?string,external_reference:?string} + * @phpstan-type BillingSummary array{subject_type:'user'|'workspace',subject_id:string,billing_profile:?array{id:string,name:?string,email:?string,tax_id:?string,version:int},subscriptions:list} + * @phpstan-type CustomEventInput array{type:string,subject:string,data:array,correlation_id?:string,causation_id?:string} + * @phpstan-type PublishedEvent array{id:string,specversion:string,source:string,type:string,subject:string,schema_version:string,data:array} + */ +final class MachineClient +{ + private ?string $accessToken = null; + private int $expiresAt = 0; + + /** @param list $scopes */ + public function __construct( + private readonly string $baseUrl, + private readonly string $applicationId, + private readonly string $clientId, + private string $clientSecret, + private readonly array $scopes = [], + ) { + if ($baseUrl === '' || $applicationId === '' || $clientId === '' || $clientSecret === '') { + throw new RuntimeException('Platform93 machine client requires base URL, application ID, client ID, and client secret.'); + } + } + + public function updateSecret(string $secret): void + { + if ($secret === '') { + throw new RuntimeException('Platform93 machine client secret is required.'); + } + $this->clientSecret = $secret; + $this->accessToken = null; + $this->expiresAt = 0; + } + + /** @param NotificationInput $notification @return QueuedNotification */ + public function sendNotification(array $notification, string $idempotencyKey): array + { + return $this->request('POST', '/notifications', $notification, $idempotencyKey); + } + + /** @param InvitationInput $invitation @return Invitation */ + public function createInvitation(array $invitation): array + { + return $this->request('POST', '/invitations', $invitation); + } + + /** @return array{items:list,next_cursor:?string} */ + public function listInvitations(): array + { + return $this->request('GET', '/invitations'); + } + + /** @return Invitation */ + public function getInvitation(string $id): array + { + return $this->request('GET', '/invitations/' . rawurlencode($id)); + } + + /** @return InvitationResent */ + public function resendInvitation(string $id): array + { + return $this->request('POST', '/invitations/' . rawurlencode($id) . '/resend'); + } + + public function revokeInvitation(string $id): void + { + $this->request('DELETE', '/invitations/' . rawurlencode($id)); + } + + /** @return array{items:list,next_cursor:?string} */ + public function listUsers(): array + { + return $this->request('GET', '/users'); + } + + /** @return User */ + public function getUser(string $id): array + { + return $this->request('GET', '/users/' . rawurlencode($id)); + } + + /** @return array{items:list,next_cursor:?string} */ + public function listWorkspaces(): array + { + return $this->request('GET', '/workspaces'); + } + + /** @return Workspace */ + public function getWorkspace(string $id): array + { + return $this->request('GET', '/service/workspaces/' . rawurlencode($id)); + } + + /** @return array{items:list,next_cursor:?string} */ + public function getWorkspaceAccess(string $id): array + { + return $this->request('GET', '/service/workspaces/' . rawurlencode($id) . '/access'); + } + + /** @return array{items:list,next_cursor:?string} */ + public function getEntitlements(string $subjectType, string $subjectId): array + { + return $this->request('GET', '/subjects/' . $this->subject($subjectType, $subjectId) . '/entitlements'); + } + + /** @return BillingSummary */ + public function getBilling(string $subjectType, string $subjectId): array + { + return $this->request('GET', '/subjects/' . $this->subject($subjectType, $subjectId) . '/billing'); + } + + /** @param CustomEventInput $event @return PublishedEvent */ + public function publishEvent(array $event, string $idempotencyKey): array + { + return $this->request('POST', '/events', $event, $idempotencyKey); + } + + private function subject(string $type, string $id): string + { + if (!in_array($type, ['user', 'workspace'], true)) { + throw new RuntimeException('Platform93 subject type must be user or workspace.'); + } + return $type . '/' . rawurlencode($id); + } + + /** @param array|null $body @return array */ + private function request(string $method, string $path, ?array $body = null, ?string $idempotencyKey = null): array + { + $headers = ['Accept: application/json', 'Authorization: Bearer ' . $this->token()]; + $content = null; + if ($body !== null) { + $content = json_encode($body, JSON_THROW_ON_ERROR); + $headers[] = 'Content-Type: application/json'; + } + if ($idempotencyKey !== null) { + $headers[] = 'Idempotency-Key: ' . $idempotencyKey; + } + return $this->http($method, '/v1/applications/' . rawurlencode($this->applicationId) . $path, $headers, $content); + } + + private function token(): string + { + if ($this->accessToken !== null && time() < $this->expiresAt - 30) { + return $this->accessToken; + } + $form = ['grant_type' => 'client_credentials']; + if ($this->scopes !== []) { + $form['scope'] = implode(' ', $this->scopes); + } + $payload = $this->http('POST', '/oidc/token', [ + 'Accept: application/json', + 'Content-Type: application/x-www-form-urlencoded', + 'Authorization: Basic ' . base64_encode($this->clientId . ':' . $this->clientSecret), + ], http_build_query($form)); + if (!isset($payload['access_token']) || !is_string($payload['access_token'])) { + throw new RuntimeException('Platform93 token response did not contain an access token.'); + } + $this->accessToken = $payload['access_token']; + $this->expiresAt = time() + max(1, (int) ($payload['expires_in'] ?? 300)); + return $this->accessToken; + } + + /** @param list $headers @return array */ + private function http(string $method, string $path, array $headers, ?string $content): array + { + $context = stream_context_create(['http' => [ + 'method' => $method, + 'header' => implode("\r\n", $headers), + 'content' => $content ?? '', + 'ignore_errors' => true, + 'timeout' => 30, + ]]); + $response = @file_get_contents(rtrim($this->baseUrl, '/') . $path, false, $context); + $statusLine = $http_response_header[0] ?? 'HTTP/1.1 500'; + preg_match('/\s(\d{3})\s/', $statusLine, $matches); + $status = (int) ($matches[1] ?? 500); + if ($response === false || $status < 200 || $status >= 300) { + throw new RuntimeException(sprintf('Platform93 request returned HTTP %d: %s', $status, substr((string) $response, 0, 4096))); + } + if ($response === '') { + return []; + } + $decoded = json_decode($response, true, 512, JSON_THROW_ON_ERROR); + return is_array($decoded) ? $decoded : []; + } +} diff --git a/sdk/php/src/Permission.php b/sdk/php/src/Permission.php new file mode 100644 index 0000000..bf5126d --- /dev/null +++ b/sdk/php/src/Permission.php @@ -0,0 +1,61 @@ + $workspaceRoles) { + if (!preg_match(self::WORKSPACE_KEY, (string) $workspaceId) || !is_array($workspaceRoles) || !self::uniqueRoles($workspaceRoles)) return false; + } + return !$delegated || ($value['application'] === [] && $workspaces === []); + } + + public static function matches(string $granted, string $wanted): bool { + if (!self::validAbsolute($granted) || !self::validAbsolute($wanted)) return false; + if ($granted === $wanted) return true; + if (!str_ends_with($granted, '/*')) return false; + $base = substr($granted, 0, -2); + return $wanted === $base || str_starts_with($wanted, $base.'/'); + } + + private static function validateScope(string $scope, string $applicationId): bool { + if ($scope === '') return true; + if ($scope !== trim($scope) || str_contains($scope, "\t") || str_contains($scope, "\r") || str_contains($scope, "\n") || str_contains($scope, ' ')) return false; + $values = explode(' ', $scope); + if (count($values) !== count(array_unique($values))) return false; + $prefix = '/applications/'.$applicationId.'/'; + foreach ($values as $value) { + if (in_array($value, ['openid', 'profile', 'email', 'offline_access'], true)) continue; + if (!str_starts_with($value, $prefix) || !self::validAbsolute($value)) return false; + } + return true; + } + + private static function validAbsolute(string $value): bool { + if (!str_starts_with($value, '/') || preg_match('/[ :\\\\%\t\r\n]/', $value)) return false; + $segments = explode('/', substr($value, 1)); + if (count($segments) < 3) return false; + foreach ($segments as $index => $segment) { + if ($segment === '*') { + if ($index !== array_key_last($segments)) return false; + continue; + } + if (!preg_match(self::SEGMENT, $segment)) return false; + } + return true; + } + + private static function uniqueRoles(array $values): bool { + foreach ($values as $value) if (!is_string($value) || !preg_match(self::ROLE_KEY, $value)) return false; + return count($values) === count(array_unique($values)); + } +} diff --git a/sdk/php/src/Verifier.php b/sdk/php/src/Verifier.php index 30e2729..c4049df 100644 --- a/sdk/php/src/Verifier.php +++ b/sdk/php/src/Verifier.php @@ -25,14 +25,15 @@ public function verify(string $token): Claims { } else $jwks = $item->get(); $claims = (array) JWT::decode($token, JWK::parseKeySet($jwks, 'RS256')); $audiences = (array) ($claims['aud'] ?? []); - foreach (['iss','sub','aud','exp','iat','nbf','application_id','token_kind','actor_type','scope'] as $required) { + foreach (['iss','sub','aud','exp','iat','nbf','application_id','token_kind','actor_type','scope','roles'] as $required) { if (!array_key_exists($required, $claims)) throw new \UnexpectedValueException('Platform93 token claim missing'); } $validActor = ($claims['token_kind'] ?? null) === 'access' && ($claims['actor_type'] ?? null) === 'user' || ($claims['token_kind'] ?? null) === 'machine' && ($claims['actor_type'] ?? null) === 'client'; if (!is_string($claims['sub']) || $claims['sub'] === '' || ($claims['iss'] ?? null) !== $this->issuer || !in_array($this->audience, $audiences, true) || ($claims['application_id'] ?? null) !== $this->applicationId || !$validActor || !is_string($claims['scope']) || !is_int($claims['iat']) || $claims['iat'] > time() + JWT::$leeway) throw new \UnexpectedValueException('Platform93 token context rejected'); $actor = (array) ($claims['act'] ?? []); - if ($actor !== [] && ($claims['token_kind'] !== 'access' || !is_string($actor['sub'] ?? null) || $actor['sub'] === '' || ($actor['type'] ?? null) !== 'operator')) throw new \UnexpectedValueException('Platform93 delegated token actor rejected'); + if ($actor !== [] && ($claims['token_kind'] !== 'access' || !is_string($actor['sub'] ?? null) || $actor['sub'] === '' || ($actor['type'] ?? null) !== 'control_user')) throw new \UnexpectedValueException('Platform93 delegated token actor rejected'); + if (!Permission::validateAuthorizationClaims($claims['scope'], $claims['roles'], $this->applicationId, $actor !== [])) throw new \UnexpectedValueException('Platform93 token authorization claims rejected'); return new Claims($claims); } } diff --git a/sdk/php/src/Webhook.php b/sdk/php/src/Webhook.php index ef56496..8285240 100644 --- a/sdk/php/src/Webhook.php +++ b/sdk/php/src/Webhook.php @@ -5,6 +5,10 @@ final class Webhook { public const PLATFORM_EVENT_VERSIONS = [ 'organization.created'=>'1.0','organization.retired'=>'1.0','organization.restored'=>'1.0', 'application.created'=>'1.0','application.retired'=>'1.0','application.restored'=>'1.0', + 'authorization.permission_grant.created'=>'1.0','authorization.permission_grant.revoked'=>'1.0', + 'control_user.identity_linked'=>'1.0','control_user.identity_unlinked'=>'1.0', + 'control_user.invitation_created'=>'1.0','control_user.invitation_resent'=>'1.0','control_user.invitation_revoked'=>'1.0','control_user.invitation_accepted'=>'1.0', + 'control_auth.policy_updated'=>'1.0','control_auth.provider_login_enabled'=>'1.0','control_auth.provider_login_disabled'=>'1.0', 'delegation.created'=>'1.0','delegation.exchanged'=>'1.0','delegation.revoked'=>'1.0', 'entitlement.granted'=>'1.0','local_entitlement_request.created'=>'1.0','local_entitlement_request.approved'=>'1.0', 'oauth.consent_revoked'=>'1.0','platform93.webhook.test'=>'1.0','user.created'=>'1.0', @@ -15,6 +19,12 @@ final class Webhook { 'user.pending_deletion'=>'1.0','user.anonymized'=>'1.0','user.deleted'=>'1.0', 'user.suspended'=>'1.0','user.restored'=>'1.0','workspace.invitation_created'=>'1.0', 'workspace.invitation_accepted'=>'1.0','workspace.owner_transferred'=>'1.0', + 'application_invitation.created'=>'1.0','application_invitation.resent'=>'1.0','application_invitation.revoked'=>'1.0', + 'application_invitation.accepted'=>'1.0','application_invitation.expired'=>'1.0','user.updated'=>'1.0', + 'workspace.created'=>'1.0','workspace.updated'=>'1.0','workspace.archived'=>'1.0', + 'workspace.member_added'=>'1.0','workspace.member_updated'=>'1.0','workspace.member_removed'=>'1.0', + 'entitlement.adjusted'=>'1.0','entitlement.revoked'=>'1.0','entitlement.restored'=>'1.0','entitlement.expired'=>'1.0','entitlement.effective_changed'=>'1.0', + 'billing.subscription.updated'=>'1.0','billing.invoice.updated'=>'1.0','billing.payment.updated'=>'1.0','billing.refund.updated'=>'1.0','billing.dispute.updated'=>'1.0', ]; public static function verify(string $rawBody, string $header, string $secret, int $tolerance = 300): array { @@ -33,4 +43,9 @@ public static function assertSupportedPlatformEvent(array $event): void { $supported=self::PLATFORM_EVENT_VERSIONS[$event['type']]; if(explode('.',$supported,2)[0]!==explode('.',$event['schema_version'],2)[0]) throw new \UnexpectedValueException('Unsupported Platform93 event schema version'); } + + public static function dispatch(array $event, array $handlers, ?callable $custom = null): bool { + if(self::isCustomEvent($event)){if($custom===null)return false;$custom($event);return true;} + self::assertSupportedPlatformEvent($event);$handler=$handlers[$event['type']]??null;if(!is_callable($handler))return false;$handler($event);return true; + } } diff --git a/sdk/php/tests/auth_conformance.php b/sdk/php/tests/auth_conformance.php index ab0367e..5f10bed 100644 --- a/sdk/php/tests/auth_conformance.php +++ b/sdk/php/tests/auth_conformance.php @@ -50,12 +50,13 @@ public function commit(): bool { return true; } foreach ($fixture['cases'] as $case) { $now = time(); $claims = ['iss' => $issuer, 'sub' => 'user-1', 'aud' => [$fixture['audience']], 'exp' => $now + 300, 'iat' => $now, 'nbf' => $now - 1, - 'application_id' => $fixture['application_id'], 'token_kind' => 'access', 'actor_type' => 'user', 'scope' => '/applications/app/profile/read']; + 'application_id' => $fixture['application_id'], 'token_kind' => 'access', 'actor_type' => 'user', + 'scope' => '/applications/'.$fixture['application_id'].'/profile/read', 'roles' => ['application' => ['member'], 'workspaces' => new stdClass()]]; $kid = 'primary'; $key = $primaryPEM; switch ($case['mutation']) { case 'machine': $claims['token_kind'] = 'machine'; $claims['actor_type'] = 'client'; break; - case 'delegated': $claims['act'] = ['sub' => 'operator-1', 'type' => 'operator']; break; + case 'delegated': $claims['act'] = ['sub' => 'control_user-1', 'type' => 'control_user']; $claims['roles'] = ['application' => [], 'workspaces' => new stdClass()]; break; case 'wrong_issuer': $claims['iss'] = 'https://wrong.example'; break; case 'wrong_audience': $claims['aud'] = ['wrong-api']; break; case 'wrong_application': $claims['application_id'] = '01900000-0000-7000-8000-000000000000'; break; @@ -66,11 +67,21 @@ public function commit(): bool { return true; } case 'missing_application': unset($claims['application_id']); break; case 'missing_token_kind': unset($claims['token_kind']); break; case 'missing_actor_type': unset($claims['actor_type']); break; - case 'operator_actor': $claims['actor_type'] = 'operator'; break; + case 'missing_roles': unset($claims['roles']); break; + case 'space_injected_scope': $claims['scope'] .= ' /applications/'.$fixture['application_id'].'/billing/write'; break; + case 'tab_injected_scope': $claims['scope'] .= "\t/applications/".$fixture['application_id'].'/billing/write'; break; + case 'unicode_injected_scope': $claims['scope'] .= "\u{200B}/applications/".$fixture['application_id'].'/billing/write'; break; + case 'encoded_space_scope': $claims['scope'] = '/applications/'.$fixture['application_id'].'/billing%20write'; break; + case 'cross_application_scope': $claims['scope'] = '/applications/01900000-0000-7000-8000-000000000000/billing/read'; break; + case 'embedded_wildcard_scope': $claims['scope'] = '/applications/'.$fixture['application_id'].'/billing/*/write'; break; + case 'duplicate_scope': $claims['scope'] .= ' '.$claims['scope']; break; + case 'invalid_roles': $claims['roles'] = ['application' => ['billing admin'], 'workspaces' => new stdClass()]; break; + case 'delegated_roles': $claims['act'] = ['sub' => 'control_user-1', 'type' => 'control_user']; break; + case 'control_user_actor': $claims['actor_type'] = 'control_user'; break; case 'missing_kid': $kid = null; break; case 'unknown_kid': $kid = 'unknown'; break; case 'wrong_signature': $key = $wrongPEM; break; - case 'delegated_wrong_actor_type': $claims['act'] = ['sub' => 'operator-1', 'type' => 'user']; break; + case 'delegated_wrong_actor_type': $claims['act'] = ['sub' => 'control_user-1', 'type' => 'user']; break; } $token = JWT::encode($claims, $key, 'RS256', $kid, ['typ' => 'JWT']); if ($case['mutation'] === 'wrong_algorithm') { diff --git a/sdk/python/auth/README.md b/sdk/python/auth/README.md index 4fd169a..7835249 100644 --- a/sdk/python/auth/README.md +++ b/sdk/python/auth/README.md @@ -1,5 +1,10 @@ # supaapps-platform93-auth +Strict Platform93 JWT verification plus a backend-only `MachineClient`. The machine +client uses OAuth client credentials and provides notification, invitation, user, +workspace, entitlement, billing-summary, and custom-event methods. Keep its client +secret in backend secret storage and never expose it to browser code. + Strict server-side verification for Platform93 application JWTs, including issuer, audience, actor type, application boundary, expiry, and JWKS rotation checks. diff --git a/sdk/python/auth/src/platform93_auth/__init__.py b/sdk/python/auth/src/platform93_auth/__init__.py index 8d6cae4..910700a 100644 --- a/sdk/python/auth/src/platform93_auth/__init__.py +++ b/sdk/python/auth/src/platform93_auth/__init__.py @@ -1,3 +1,38 @@ from .verifier import Claims, Verifier +from .machine import ( + BillingSummary, + CustomEventInput, + EntitlementPage, + Invitation, + InvitationInput, + InvitationPage, + MachineClient, + NotificationInput, + PublishedEvent, + QueuedNotification, + User, + UserPage, + Workspace, + WorkspaceAccessPage, + WorkspacePage, +) -__all__ = ["Claims", "Verifier"] +__all__ = [ + "BillingSummary", + "Claims", + "CustomEventInput", + "EntitlementPage", + "Invitation", + "InvitationInput", + "InvitationPage", + "MachineClient", + "NotificationInput", + "PublishedEvent", + "QueuedNotification", + "User", + "UserPage", + "Verifier", + "Workspace", + "WorkspaceAccessPage", + "WorkspacePage", +] diff --git a/sdk/python/auth/src/platform93_auth/machine.py b/sdk/python/auth/src/platform93_auth/machine.py new file mode 100644 index 0000000..5ded135 --- /dev/null +++ b/sdk/python/auth/src/platform93_auth/machine.py @@ -0,0 +1,295 @@ +from __future__ import annotations + +import threading +import time +from typing import NotRequired, TypedDict, cast +from urllib.parse import quote + +import httpx + + +JsonValue = str | int | float | bool | None | list["JsonValue"] | dict[str, "JsonValue"] + + +class NotificationInput(TypedDict): + template_key: str + user_id: NotRequired[str] + recipient: NotRequired[str] + locale: NotRequired[str] + variables: NotRequired[dict[str, JsonValue]] + + +class QueuedNotification(TypedDict): + id: str + status: str + requested_locale: str + resolved_locale: str + fallback_used: bool + + +class InvitationInput(TypedDict): + email: str + workspace_id: NotRequired[str] + application_role_keys: NotRequired[list[str]] + workspace_role_keys: NotRequired[list[str]] + expires_in: NotRequired[int] + + +class Invitation(TypedDict): + id: str + email: str + workspace_id: str | None + application_role_keys: list[str] + workspace_role_keys: list[str] + status: str + expires_at: str + + +class InvitationPage(TypedDict): + items: list[Invitation] + next_cursor: str | None + + +class InvitationResent(TypedDict): + id: str + last_sent_at: str + resend_available_at: str + expires_at: str + + +class User(TypedDict): + id: str + application_id: str + email: str + first_name: str + last_name: str + username: str | None + locale: str + email_verified: bool + is_org_verified: bool + status: str + custom_attributes: dict[str, JsonValue] + version: int + + +class UserPage(TypedDict): + items: list[User] + next_cursor: str | None + + +class Workspace(TypedDict): + id: str + application_id: str + owner_user_id: str + key: str + name: str + metadata: dict[str, JsonValue] + status: str + version: int + created_at: str + updated_at: str + + +class WorkspacePage(TypedDict): + items: list[Workspace] + next_cursor: str | None + + +class WorkspaceAccess(TypedDict): + type: str + workspace_id: str + user_id: str | None + email: str | None + role_keys: list[str] + invitation_id: str | None + status: str + expires_at: str | None + + +class WorkspaceAccessPage(TypedDict): + items: list[WorkspaceAccess] + next_cursor: str | None + + +class EntitlementGrant(TypedDict): + id: str + subject_type: str + subject_id: str + source_type: str + feature_values: dict[str, JsonValue] + configuration: dict[str, JsonValue] + starts_at: str + expires_at: str | None + external_reference: str | None + + +class EntitlementPage(TypedDict): + items: list[EntitlementGrant] + next_cursor: str | None + + +class BillingProfile(TypedDict): + id: str + subject_type: str + subject_id: str + name: str | None + email: str | None + tax_id: str | None + version: int + + +class Subscription(TypedDict): + id: str + subject_type: str + subject_id: str + price_id: str + provider_id: str + status: str + external_reference: str | None + + +class BillingSummary(TypedDict): + subject_type: str + subject_id: str + billing_profile: BillingProfile | None + subscriptions: list[Subscription] + + +class CustomEventInput(TypedDict): + type: str + subject: str + data: dict[str, JsonValue] + correlation_id: NotRequired[str] + causation_id: NotRequired[str] + + +class PublishedEvent(TypedDict): + id: str + specversion: str + source: str + type: str + subject: str + schema_version: str + data: dict[str, JsonValue] + + +class MachineClient: + """Server-only Platform93 client with cached OAuth client credentials.""" + + def __init__( + self, + *, + base_url: str, + application_id: str, + client_id: str, + client_secret: str, + scopes: list[str] | None = None, + client: httpx.Client | None = None, + ) -> None: + if not all((base_url, application_id, client_id, client_secret)): + raise ValueError("Platform93 machine client requires base_url, application_id, client_id, and client_secret") + self.base_url = base_url.rstrip("/") + self.application_id = application_id + self.client_id = client_id + self.client_secret = client_secret + self.scopes = scopes or [] + self.client = client or httpx.Client(timeout=30.0) + self._token: str | None = None + self._expires_at = 0.0 + self._lock = threading.Lock() + + def update_secret(self, secret: str) -> None: + if not secret: + raise ValueError("Platform93 machine client secret is required") + with self._lock: + self.client_secret = secret + self._token = None + self._expires_at = 0.0 + + def send_notification(self, notification: NotificationInput, idempotency_key: str) -> QueuedNotification: + return cast(QueuedNotification, self._request("POST", "/notifications", notification, idempotency_key)) + + def create_invitation(self, invitation: InvitationInput) -> Invitation: + return cast(Invitation, self._request("POST", "/invitations", invitation)) + + def list_invitations(self) -> InvitationPage: + return cast(InvitationPage, self._request("GET", "/invitations")) + + def get_invitation(self, invitation_id: str) -> Invitation: + return cast(Invitation, self._request("GET", f"/invitations/{quote(invitation_id, safe='')}")) + + def resend_invitation(self, invitation_id: str) -> InvitationResent: + return cast(InvitationResent, self._request("POST", f"/invitations/{quote(invitation_id, safe='')}/resend")) + + def revoke_invitation(self, invitation_id: str) -> None: + self._request("DELETE", f"/invitations/{quote(invitation_id, safe='')}") + + def list_users(self) -> UserPage: + return cast(UserPage, self._request("GET", "/users")) + + def get_user(self, user_id: str) -> User: + return cast(User, self._request("GET", f"/users/{quote(user_id, safe='')}")) + + def list_workspaces(self) -> WorkspacePage: + return cast(WorkspacePage, self._request("GET", "/workspaces")) + + def get_workspace(self, workspace_id: str) -> Workspace: + return cast(Workspace, self._request("GET", f"/service/workspaces/{quote(workspace_id, safe='')}")) + + def get_workspace_access(self, workspace_id: str) -> WorkspaceAccessPage: + return cast(WorkspaceAccessPage, self._request("GET", f"/service/workspaces/{quote(workspace_id, safe='')}/access")) + + def get_entitlements(self, subject_type: str, subject_id: str) -> EntitlementPage: + return cast(EntitlementPage, self._request("GET", f"/subjects/{self._subject(subject_type, subject_id)}/entitlements")) + + def get_billing(self, subject_type: str, subject_id: str) -> BillingSummary: + return cast(BillingSummary, self._request("GET", f"/subjects/{self._subject(subject_type, subject_id)}/billing")) + + def publish_event(self, event: CustomEventInput, idempotency_key: str) -> PublishedEvent: + return cast(PublishedEvent, self._request("POST", "/events", event, idempotency_key)) + + def _subject(self, subject_type: str, subject_id: str) -> str: + if subject_type not in {"user", "workspace"}: + raise ValueError("Platform93 subject type must be user or workspace") + return f"{subject_type}/{quote(subject_id, safe='')}" + + def _access_token(self) -> str: + with self._lock: + if self._token and time.time() < self._expires_at - 30: + return self._token + data = {"grant_type": "client_credentials"} + if self.scopes: + data["scope"] = " ".join(self.scopes) + response = self.client.post( + f"{self.base_url}/oidc/token", + data=data, + auth=(self.client_id, self.client_secret), + headers={"Accept": "application/json"}, + ) + response.raise_for_status() + payload = response.json() + token = payload.get("access_token") + if not isinstance(token, str) or not token: + raise RuntimeError("Platform93 token response did not contain an access token") + self._token = token + self._expires_at = time.time() + max(1, int(payload.get("expires_in", 300))) + return token + + def _request( + self, + method: str, + path: str, + body: dict[str, object] | None = None, + idempotency_key: str | None = None, + ) -> dict[str, object]: + headers = {"Accept": "application/json", "Authorization": f"Bearer {self._access_token()}"} + if idempotency_key: + headers["Idempotency-Key"] = idempotency_key + response = self.client.request( + method, + f"{self.base_url}/v1/applications/{quote(self.application_id, safe='')}{path}", + json=body, + headers=headers, + ) + response.raise_for_status() + return response.json() if response.content else {} diff --git a/sdk/python/auth/src/platform93_auth/verifier.py b/sdk/python/auth/src/platform93_auth/verifier.py index 4aad8df..6f45f8f 100644 --- a/sdk/python/auth/src/platform93_auth/verifier.py +++ b/sdk/python/auth/src/platform93_auth/verifier.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +import re from typing import Any import jwt @@ -13,15 +14,26 @@ class Claims: def locale(self) -> str: return str(self.values.get("locale", "")) + @property + def custom_claims(self) -> dict[str, Any]: + value = self.values.get("custom_claims", {}) + return value if isinstance(value, dict) else {} + + @property + def roles(self) -> dict[str, Any]: + return self.values["roles"] + def has_permission(self, permission: str) -> bool: + if not _valid_absolute_permission(permission): + return False return any( value == permission - or value == "*" or ( value.endswith("/*") and (permission == value[:-2] or permission.startswith(value[:-1])) ) - for value in self.values.get("scope", "").split() + for value in self.values.get("scope", "").split(" ") + if _valid_absolute_permission(value) ) @@ -53,7 +65,7 @@ def verify(self, token: str) -> Claims: options={ "require": [ "exp", "iat", "nbf", "iss", "sub", "aud", - "application_id", "token_kind", "actor_type", "scope", + "application_id", "token_kind", "actor_type", "scope", "roles", ] }, ) @@ -74,9 +86,60 @@ def verify(self, token: str) -> Claims: if actor is not None and ( values["token_kind"] != "access" or not isinstance(actor, dict) - or actor.get("type") != "operator" + or actor.get("type") != "control_user" or not isinstance(actor.get("sub"), str) or not actor["sub"] ): raise jwt.InvalidTokenError("Platform93 delegated token actor rejected") + if not _valid_scope_claim(values["scope"], self.application_id) or not _valid_roles_claim(values.get("roles")): + raise jwt.InvalidTokenError("Platform93 token authorization claims rejected") + if actor is not None and (values["roles"]["application"] or values["roles"]["workspaces"]): + raise jwt.InvalidTokenError("Platform93 delegated token roles rejected") return Claims(values) + + +def _valid_scope_claim(scope: Any, application_id: str) -> bool: + if not isinstance(scope, str): + return False + if scope == "": + return True + if scope != scope.strip() or any(value in scope for value in ("\t", "\r", "\n", " ")): + return False + values = scope.split(" ") + if len(values) != len(set(values)): + return False + prefix = f"/applications/{application_id}/" + return all(value in _PROTOCOL_SCOPES or value.startswith(prefix) and _valid_absolute_permission(value) for value in values) + + +def _valid_absolute_permission(value: str) -> bool: + if not isinstance(value, str) or not value.startswith("/") or any(character in value for character in " :\\%\t\r\n"): + return False + segments = value[1:].split("/") + return len(segments) >= 3 and all( + index == len(segments) - 1 if segment == "*" else bool(_SEGMENT.fullmatch(segment)) + for index, segment in enumerate(segments) + ) + + +def _valid_roles_claim(value: Any) -> bool: + if not isinstance(value, dict) or set(value) != {"application", "workspaces"}: + return False + application, workspaces = value["application"], value["workspaces"] + if not isinstance(application, list) or not isinstance(workspaces, dict) or not _unique_roles(application): + return False + return all( + bool(_WORKSPACE_KEY.fullmatch(workspace_id)) and isinstance(roles, list) and _unique_roles(roles) + for workspace_id, roles in workspaces.items() + ) + + +def _unique_roles(values: list[Any]) -> bool: + if not all(isinstance(value, str) and _ROLE_KEY.fullmatch(value) for value in values): + return False + return len(values) == len(set(values)) + +_SEGMENT = re.compile(r"^[a-z0-9][a-z0-9._-]{0,63}$") +_ROLE_KEY = re.compile(r"^[a-z][a-z0-9_-]{0,62}$") +_WORKSPACE_KEY = re.compile(r"^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$") +_PROTOCOL_SCOPES = {"openid", "profile", "email", "offline_access"} diff --git a/sdk/python/auth/tests/conformance.py b/sdk/python/auth/tests/conformance.py index 3622945..e58d517 100644 --- a/sdk/python/auth/tests/conformance.py +++ b/sdk/python/auth/tests/conformance.py @@ -51,11 +51,14 @@ def token_for(mutation: str) -> str: "application_id": fixture["application_id"], "token_kind": "access", "actor_type": "user", - "scope": "/applications/app/profile/read", + "scope": f"/applications/{fixture['application_id']}/profile/read", + "roles": {"application": ["member"], "workspaces": {}}, } signing_key = primary if mutation == "machine": claims.update(token_kind="machine", actor_type="client") - elif mutation == "delegated": claims["act"] = {"sub": "operator-1", "type": "operator"} + elif mutation == "delegated": + claims["act"] = {"sub": "control_user-1", "type": "control_user"} + claims["roles"] = {"application": [], "workspaces": {}} elif mutation == "wrong_issuer": claims["iss"] = "https://wrong.example" elif mutation == "wrong_audience": claims["aud"] = ["wrong-api"] elif mutation == "wrong_application": claims["application_id"] = "01900000-0000-7000-8000-000000000000" @@ -66,11 +69,21 @@ def token_for(mutation: str) -> str: elif mutation == "missing_application": claims.pop("application_id") elif mutation == "missing_token_kind": claims.pop("token_kind") elif mutation == "missing_actor_type": claims.pop("actor_type") - elif mutation == "operator_actor": claims["actor_type"] = "operator" + elif mutation == "missing_roles": claims.pop("roles") + elif mutation == "space_injected_scope": claims["scope"] += f" /applications/{fixture['application_id']}/billing/write" + elif mutation == "tab_injected_scope": claims["scope"] += f"\t/applications/{fixture['application_id']}/billing/write" + elif mutation == "unicode_injected_scope": claims["scope"] += f"\u200b/applications/{fixture['application_id']}/billing/write" + elif mutation == "encoded_space_scope": claims["scope"] = f"/applications/{fixture['application_id']}/billing%20write" + elif mutation == "cross_application_scope": claims["scope"] = "/applications/01900000-0000-7000-8000-000000000000/billing/read" + elif mutation == "embedded_wildcard_scope": claims["scope"] = f"/applications/{fixture['application_id']}/billing/*/write" + elif mutation == "duplicate_scope": claims["scope"] += f" {claims['scope']}" + elif mutation == "invalid_roles": claims["roles"] = {"application": ["billing admin"], "workspaces": {}} + elif mutation == "delegated_roles": claims["act"] = {"sub": "control_user-1", "type": "control_user"} + elif mutation == "control_user_actor": claims["actor_type"] = "control_user" elif mutation == "missing_kid": headers.pop("kid") elif mutation == "unknown_kid": headers["kid"] = "unknown" elif mutation == "wrong_signature": signing_key = wrong - elif mutation == "delegated_wrong_actor_type": claims["act"] = {"sub": "operator-1", "type": "user"} + elif mutation == "delegated_wrong_actor_type": claims["act"] = {"sub": "control_user-1", "type": "user"} token = jwt.encode(claims, signing_key, algorithm="RS256", headers=headers) if mutation == "wrong_algorithm": parts = token.split(".") diff --git a/sdk/python/webhooks/src/platform93_webhooks/__init__.py b/sdk/python/webhooks/src/platform93_webhooks/__init__.py index e2583dc..25a5d81 100644 --- a/sdk/python/webhooks/src/platform93_webhooks/__init__.py +++ b/sdk/python/webhooks/src/platform93_webhooks/__init__.py @@ -1,7 +1,9 @@ from .verifier import ( PLATFORM_EVENT_VERSIONS, Platform93Event, + PermissionGrantLifecycleData, assert_supported_platform_event, + dispatch_event, is_custom_event, is_platform_event, verify_webhook, @@ -10,7 +12,9 @@ __all__ = [ "PLATFORM_EVENT_VERSIONS", "Platform93Event", + "PermissionGrantLifecycleData", "assert_supported_platform_event", + "dispatch_event", "is_custom_event", "is_platform_event", "verify_webhook", diff --git a/sdk/python/webhooks/src/platform93_webhooks/verifier.py b/sdk/python/webhooks/src/platform93_webhooks/verifier.py index 18a74a1..789b269 100644 --- a/sdk/python/webhooks/src/platform93_webhooks/verifier.py +++ b/sdk/python/webhooks/src/platform93_webhooks/verifier.py @@ -21,9 +21,37 @@ class Platform93Event(TypedDict): data: dict[str, Any] +class PermissionGrantLifecycleData(TypedDict): + grant_id: str + subject_type: Literal["user", "client"] + subject_id: str + workspace_id: str | None + permission: str + canonical_scope: str + + +class ControlUserIdentityData(TypedDict): + control_user_id: str + provider: Literal["google", "apple"] + + +class ControlInvitationData(TypedDict, total=False): + invitation_id: str + organization_id: str | None + control_user_id: str + role: Literal["owner", "admin", "member", "auditor"] + onboarding_method: Literal["email", "google", "apple"] + status: Literal["pending", "accepted", "revoked"] + + PLATFORM_EVENT_VERSIONS = dict.fromkeys(( "organization.created", "organization.retired", "organization.restored", "application.created", "application.retired", "application.restored", + "authorization.permission_grant.created", "authorization.permission_grant.revoked", + "control_user.identity_linked", "control_user.identity_unlinked", + "control_user.invitation_created", "control_user.invitation_resent", + "control_user.invitation_revoked", "control_user.invitation_accepted", + "control_auth.policy_updated", "control_auth.provider_login_enabled", "control_auth.provider_login_disabled", "delegation.created", "delegation.exchanged", "delegation.revoked", "entitlement.granted", "local_entitlement_request.created", "local_entitlement_request.approved", "oauth.consent_revoked", "platform93.webhook.test", "user.created", @@ -33,6 +61,13 @@ class Platform93Event(TypedDict): "user.organization_unverified", "user.email_changed", "user.password_reset", "user.pending_deletion", "user.anonymized", "user.deleted", "user.suspended", "user.restored", "workspace.invitation_created", "workspace.invitation_accepted", "workspace.owner_transferred", + "application_invitation.created", "application_invitation.resent", "application_invitation.revoked", + "application_invitation.accepted", "application_invitation.expired", "user.updated", + "workspace.created", "workspace.updated", "workspace.archived", "workspace.member_added", + "workspace.member_updated", "workspace.member_removed", "entitlement.adjusted", "entitlement.revoked", + "entitlement.restored", "entitlement.expired", "entitlement.effective_changed", + "billing.subscription.updated", "billing.invoice.updated", "billing.payment.updated", + "billing.refund.updated", "billing.dispute.updated", ), "1.0") @@ -85,3 +120,17 @@ def assert_supported_platform_event(event: Platform93Event) -> None: supported = PLATFORM_EVENT_VERSIONS[event["type"]] if event["schema_version"].split(".", 1)[0] != supported.split(".", 1)[0]: raise ValueError("Unsupported Platform93 event schema version") + + +def dispatch_event(event: Platform93Event, handlers: dict[str, Any], custom: Any = None) -> bool: + if is_custom_event(event): + if custom is None: + return False + custom(event) + return True + assert_supported_platform_event(event) + handler = handlers.get(event["type"]) + if handler is None: + return False + handler(event) + return True diff --git a/sdk/typescript/auth/src/index.ts b/sdk/typescript/auth/src/index.ts index 46155d4..81e0335 100644 --- a/sdk/typescript/auth/src/index.ts +++ b/sdk/typescript/auth/src/index.ts @@ -4,6 +4,10 @@ import { type ApplicationFlowConfig, type EmailStart, type EmailVerify, + type ExternalAuthAuthorization, + type ExternalAuthFlow, + type ExternalAuthProvider, + type InvitationCredential, type MFAChallenge, type MFAVerify, type PasswordSignIn, @@ -28,8 +32,18 @@ export type PKCEAuthorizationOptions = { scopes?: string[]; state?: string; nonce?: string; + clientId?: string; + redirectUri?: string; }; +export type ExternalAuthStartOptions = { + redirectUri: string; + flow?: ExternalAuthFlow; + loginHint?: string; +}; + +export type InvitationLink = { applicationId: string; invitationId: string; linkToken: string }; + export interface TokenStore { loadRefreshToken(): Promise; saveRefreshToken(value: string | null): Promise; @@ -117,6 +131,7 @@ export type Platform93AuthOptions = { export class Platform93Auth extends EventTarget { private accessToken: string | null = null; + private accessTokenExpiresAt = 0; private status: AuthSnapshot["status"] = "anonymous"; private refreshPromise: Promise | null = null; private readonly adapter: SessionAdapter; @@ -151,41 +166,99 @@ export class Platform93Auth extends EventTarget { } snapshot(): AuthSnapshot { return { status: this.status, accessToken: this.accessToken }; } + async getAccessToken(leewaySeconds = 10) { + if (this.accessToken && Date.now() + leewaySeconds * 1000 < this.accessTokenExpiresAt) return this.accessToken; + return this.refresh(false); + } signIn(input: PasswordSignIn) { return this.resolve(this.client.application().signIn(input)); } signUp(input: PasswordSignUp) { return this.resolve(this.client.application().signUp(input)); } startEmail(input: EmailStart) { return this.client.application().startEmail(input); } verifyEmail(input: EmailVerify) { return this.resolve(this.client.application().verifyEmail(input)); } + startExternalAuth(provider: ExternalAuthProvider, options: ExternalAuthStartOptions): Promise { + return this.client.application().startExternalAuth(provider, { + redirect_uri: options.redirectUri, + flow: options.flow, + ...(options.loginHint ? { login_hint: options.loginHint } : {}), + }); + } + startGoogleAuth(options: ExternalAuthStartOptions) { return this.startExternalAuth("google", options); } + startAppleAuth(options: Omit) { return this.startExternalAuth("apple", options); } + exchangeExternalAuth(provider: ExternalAuthProvider, exchange: string) { + return this.resolve(this.client.application().exchangeExternalAuth(provider, exchange)); + } + exchangeGoogleAuth(exchange: string) { return this.exchangeExternalAuth("google", exchange); } + exchangeAppleAuth(exchange: string) { return this.exchangeExternalAuth("apple", exchange); } + completeExternalAuthRedirect(provider: ExternalAuthProvider, input: string | URL) { + const redirect = input instanceof URL ? input : new URL(input); + const providerError = redirect.searchParams.get("external_auth_error"); + if (providerError) throw new Error(`Platform93 ${provider} authentication failed: ${providerError}`); + const exchange = redirect.searchParams.get("external_auth_exchange"); + if (!exchange) throw new Error(`Platform93 ${provider} redirect is missing its one-time exchange credential`); + return this.exchangeExternalAuth(provider, exchange); + } + async exchangeInvitation(input: InvitationCredential) { + const codeVerifier = randomBase64URL(32); + const codeChallenge = await sha256Base64URL(codeVerifier); + const authorization = await this.client.application().exchangeInvitation({ ...input, code_challenge: codeChallenge }); + return this.resolve(this.client.application().redeemInvitation({ authorization_code: authorization.authorization_code, code_verifier: codeVerifier })); + } verifyMFA(input: MFAVerify) { return this.resolve(this.client.application().verifyMFA(input)); } async createAuthorizationRequest(options: PKCEAuthorizationOptions = {}): Promise { const runtime = await this.client.application().publicConfig(); const flows = runtime.auth.flows as ApplicationFlowConfig | undefined; - if (!flows?.oauth_client_id || !flows.sign_in_redirect_uri) { + const hasOverride = options.clientId !== undefined || options.redirectUri !== undefined; + if (hasOverride && (!options.clientId || !options.redirectUri)) { + throw new Error("Platform93 authorization overrides require both clientId and redirectUri"); + } + const clientId = options.clientId ?? flows?.oauth_client_id; + const redirectUri = options.redirectUri ?? flows?.sign_in_redirect_uri; + if (!clientId || !redirectUri) { throw new Error("Platform93 application sign-in flow is not configured"); } const codeVerifier = randomBase64URL(32); const challenge = await sha256Base64URL(codeVerifier); const state = options.state ?? randomBase64URL(24); const authorization = new URL("/oidc/authorize", runtime.issuer); - authorization.searchParams.set("client_id", flows.oauth_client_id); - authorization.searchParams.set("redirect_uri", flows.sign_in_redirect_uri); + authorization.searchParams.set("client_id", clientId); + authorization.searchParams.set("redirect_uri", redirectUri); authorization.searchParams.set("response_type", "code"); authorization.searchParams.set("scope", (options.scopes ?? ["openid", "profile", "email"]).join(" ")); authorization.searchParams.set("state", state); authorization.searchParams.set("code_challenge", challenge); authorization.searchParams.set("code_challenge_method", "S256"); if (options.nonce) authorization.searchParams.set("nonce", options.nonce); - return { authorizationUrl: authorization.toString(), codeVerifier, state, clientId: flows.oauth_client_id, redirectUri: flows.sign_in_redirect_uri }; + return { authorizationUrl: authorization.toString(), codeVerifier, state, clientId, redirectUri }; } async verifyEmailLink(input: string | URL = globalThis.location.href) { const link = input instanceof URL ? input : new URL(input, globalThis.location?.origin); const challengeId = link.searchParams.get("challenge_id"); - const linkToken = link.searchParams.get("link_token"); + const linkToken = link.searchParams.get("link_token") ?? link.searchParams.get("invitation_token"); if (!challengeId || !linkToken) throw new Error("Platform93 email link is missing its one-time credential"); return this.verifyEmail({ challenge_id: challengeId, link_token: linkToken }); } + parseInvitationLink(input: string | URL = globalThis.location.href): InvitationLink { + const link = input instanceof URL ? input : new URL(input, globalThis.location?.origin); + const applicationId = link.searchParams.get("application_id"); + const invitationId = link.searchParams.get("invitation_id"); + const linkToken = link.searchParams.get("link_token"); + if (!applicationId || !invitationId || !linkToken || applicationId !== this.applicationId) { + throw new Error("Platform93 invitation link is missing or has the wrong application context"); + } + return { applicationId, invitationId, linkToken }; + } + + exchangeInvitationLink(input: string | URL = globalThis.location.href) { + const invitation = this.parseInvitationLink(input); + return this.exchangeInvitation({ invitation_id: invitation.invitationId, link_token: invitation.linkToken }); + } + + exchangeInvitationCode(email: string, code: string) { + return this.exchangeInvitation({ email, code: code.trim().toUpperCase() }); + } + async refresh(broadcast = true) { if (this.refreshPromise) return this.refreshPromise; this.refreshPromise = this.withRefreshLock(async () => { @@ -222,12 +295,14 @@ export class Platform93Auth extends EventTarget { private async accept(tokens: TokenResponse, broadcast: boolean) { await this.adapter.accept(tokens); this.accessToken = tokens.access_token; + this.accessTokenExpiresAt = Date.now() + tokens.expires_in * 1000; this.setStatus("authenticated"); if (broadcast) this.channel?.postMessage({ type: "session-changed", source: this.source }); } private async clear(broadcast: boolean) { this.accessToken = null; + this.accessTokenExpiresAt = 0; await this.adapter.clear(); this.setStatus("anonymous"); if (broadcast) this.channel?.postMessage({ type: "logout", source: this.source }); diff --git a/sdk/typescript/auth/test/auth.test.mjs b/sdk/typescript/auth/test/auth.test.mjs index bf4d2a1..9b981a5 100644 --- a/sdk/typescript/auth/test/auth.test.mjs +++ b/sdk/typescript/auth/test/auth.test.mjs @@ -73,3 +73,49 @@ test("configured application authorization creates an S256 PKCE request", async assert.match(request.codeVerifier, /^[A-Za-z0-9_-]{43}$/); assert.match(authorization.searchParams.get("code_challenge"), /^[A-Za-z0-9_-]{43}$/); }); + +test("native authorization can select a separately registered public client", async () => { + const fetch = async () => Response.json({ + issuer: "https://platform93.test/oidc", + auth: { flows: { oauth_client_id: "web", sign_in_redirect_uri: "https://app.test/auth/callback" } }, + }); + const auth = new Platform93Auth({ baseUrl: "https://platform93.test", applicationId: "application", fetch, channelName: false }); + const request = await auth.createAuthorizationRequest({ clientId: "mobile", redirectUri: "sampleapp://auth/callback" }); + const authorization = new URL(request.authorizationUrl); + assert.equal(authorization.searchParams.get("client_id"), "mobile"); + assert.equal(authorization.searchParams.get("redirect_uri"), "sampleapp://auth/callback"); +}); + +test("external provider redirects exchange their one-time credential", async () => { + const calls = []; + const fetch = async (input, init = {}) => { + calls.push([String(input), JSON.parse(init.body ?? "{}")]); + if (String(input).endsWith("/auth/providers/google/start")) { + return Response.json({ provider: "google", authorize_url: "https://accounts.google.test/authorize", expires_in: 600 }, { status: 201 }); + } + if (String(input).endsWith("/auth/providers/google/exchange")) return Response.json(tokens("native")); + throw new Error(`unexpected request ${input}`); + }; + const auth = new Platform93Auth({ baseUrl: "https://platform93.test", applicationId: "application", fetch, channelName: false }); + const start = await auth.startGoogleAuth({ redirectUri: "sampleapp://auth/callback", flow: "automatic" }); + assert.equal(start.authorize_url, "https://accounts.google.test/authorize"); + await auth.completeExternalAuthRedirect("google", "sampleapp://auth/callback?external_auth_exchange=exchange-value"); + assert.equal(auth.snapshot().status, "authenticated"); + assert.deepEqual(calls[0][1], { redirect_uri: "sampleapp://auth/callback", flow: "automatic" }); + assert.deepEqual(calls[1][1], { exchange: "exchange-value" }); +}); + +test("access token retrieval refreshes only when the current token expires", async () => { + let refreshes = 0; + const store = new MemoryTokenStore(); + await store.saveRefreshToken("existing-refresh"); + const fetch = async (input) => { + if (!String(input).endsWith("/auth/token/refresh")) throw new Error(`unexpected request ${input}`); + refreshes += 1; + return Response.json(tokens(`refresh-${refreshes}`)); + }; + const auth = new Platform93Auth({ baseUrl: "https://platform93.test", applicationId: "application", fetch, channelName: false, adapter: new TokenStoreSessionAdapter(store) }); + assert.equal(await auth.getAccessToken(), "access-refresh-1"); + assert.equal(await auth.getAccessToken(), "access-refresh-1"); + assert.equal(refreshes, 1); +}); diff --git a/sdk/typescript/events/src/index.ts b/sdk/typescript/events/src/index.ts index b046edb..2cc3035 100644 --- a/sdk/typescript/events/src/index.ts +++ b/sdk/typescript/events/src/index.ts @@ -30,6 +30,13 @@ type UserStateData = UserIDData & { reason: string }; type VerificationData = UserIDData & { verified: Verified; reason: string }; type StorageObjectData = { object_id: ID; owner_type: "installation" | "application" | "user" | "workspace"; visibility: "public" | "private"; size_bytes: number }; type StorageProviderData = { provider_id: ID; scope: "installation" | "organization" | "application"; public_enabled: boolean; private_enabled: boolean }; +type InvitationLifecycleData = { invitation_id: ID; status: "pending" | "accepted" | "revoked" | "expired"; workspace_id?: ID | null; user_id?: ID; expires_at?: string }; +type WorkspaceLifecycleData = { workspace_id: ID; status: "active" | "archived" | "removed"; user_id?: ID; owner_user_id?: ID; role_keys?: string[]; changed_fields?: string[] }; +type EntitlementLifecycleData = { grant_id: ID; status?: "active" | "revoked" | "expired"; subject_type?: "user" | "workspace"; subject_id?: ID; external_reference?: string | null; expires_at?: string | null; reason?: string }; +type BillingLifecycleData = { status: string; external_reference: string | null } & Record; +type PermissionGrantLifecycleData = { grant_id: ID; subject_type: "user" | "client"; subject_id: ID; workspace_id: ID | null; permission: string; canonical_scope: string }; +type ControlUserIdentityData = { control_user_id: ID; provider: "google" | "apple" }; +type ControlInvitationData = { invitation_id: ID; organization_id?: ID | null; control_user_id?: ID; role: "owner" | "admin" | "member" | "auditor"; onboarding_method: "email" | "google" | "apple"; status: "pending" | "accepted" | "revoked" }; export interface Platform93EventDataMap { "organization.created": NamedData; @@ -38,10 +45,31 @@ export interface Platform93EventDataMap { "application.created": NamedData; "application.retired": { organization_id: ID; reason: string }; "application.restored": { organization_id: ID; reason: string }; + "authorization.permission_grant.created": PermissionGrantLifecycleData; + "authorization.permission_grant.revoked": PermissionGrantLifecycleData; + "control_user.identity_linked": ControlUserIdentityData; + "control_user.identity_unlinked": ControlUserIdentityData; + "control_user.invitation_created": ControlInvitationData; + "control_user.invitation_resent": ControlInvitationData; + "control_user.invitation_revoked": ControlInvitationData; + "control_user.invitation_accepted": ControlInvitationData & { control_user_id: ID }; + "control_auth.policy_updated": { email_code_enabled: boolean; magic_link_enabled: boolean; password_enabled: boolean }; + "control_auth.provider_login_enabled": { provider: "google" | "apple"; enabled: true }; + "control_auth.provider_login_disabled": { provider: "google" | "apple"; enabled: false }; "delegation.created": { delegation_id: ID; user_id: ID; workspace_id: ID | null; permissions: string[]; reason: string; expires_at: string }; "delegation.exchanged": { delegation_id: ID; user_id: ID }; "delegation.revoked": { delegation_id: ID }; - "entitlement.granted": { grant_id: ID; subject_type: "user" | "workspace"; subject_id: ID; reason: string }; + "entitlement.granted": EntitlementLifecycleData & { subject_type: "user" | "workspace"; subject_id: ID; status: "active" }; + "entitlement.adjusted": EntitlementLifecycleData; + "entitlement.revoked": EntitlementLifecycleData; + "entitlement.restored": EntitlementLifecycleData; + "entitlement.expired": EntitlementLifecycleData; + "entitlement.effective_changed": EntitlementLifecycleData; + "application_invitation.created": InvitationLifecycleData; + "application_invitation.resent": InvitationLifecycleData; + "application_invitation.revoked": InvitationLifecycleData; + "application_invitation.accepted": InvitationLifecycleData; + "application_invitation.expired": InvitationLifecycleData; "local_entitlement_request.created": { request_id: ID; subject_type: "user" | "workspace"; subject_id: ID; price_id: ID }; "local_entitlement_request.approved": { request_id: ID; grant_id: ID }; "oauth.consent_revoked": { user_id: ID; client_id: ID; client_key: string }; @@ -52,6 +80,7 @@ export interface Platform93EventDataMap { "storage.provider.verified": StorageProviderData; "storage.provider.disabled": StorageProviderData; "user.created": UserIDData & { email_verified: boolean; is_org_verified: boolean }; + "user.updated": UserIDData & { changed_fields: string[] }; "user.email_verified": VerificationData; "user.email_unverified": VerificationData; "user.organization_verified": VerificationData; @@ -66,6 +95,17 @@ export interface Platform93EventDataMap { "workspace.invitation_created": { invitation_id: ID; workspace_id: ID; role_keys: string[] }; "workspace.invitation_accepted": { invitation_id: ID; workspace_id: ID; user_id: ID }; "workspace.owner_transferred": { workspace_id: ID; previous_owner_user_id: ID; new_owner_user_id: ID; previous_owner_disposition: "member" | "remove" }; + "workspace.created": WorkspaceLifecycleData; + "workspace.updated": WorkspaceLifecycleData; + "workspace.archived": WorkspaceLifecycleData; + "workspace.member_added": WorkspaceLifecycleData; + "workspace.member_updated": WorkspaceLifecycleData; + "workspace.member_removed": WorkspaceLifecycleData; + "billing.subscription.updated": BillingLifecycleData<"subscription_id"> & { subject_type: "user" | "workspace"; subject_id: ID }; + "billing.invoice.updated": BillingLifecycleData<"invoice_id">; + "billing.payment.updated": BillingLifecycleData<"payment_id">; + "billing.refund.updated": BillingLifecycleData<"refund_id">; + "billing.dispute.updated": BillingLifecycleData<"dispute_id">; } export type Platform93EventType = keyof Platform93EventDataMap; @@ -78,6 +118,11 @@ export type AnyPlatform93Event = KnownPlatform93Event | CustomPlatform93Event; export const platform93EventVersions: Readonly> = { "organization.created": "1.0", "organization.retired": "1.0", "organization.restored": "1.0", "application.created": "1.0", "application.retired": "1.0", "application.restored": "1.0", + "authorization.permission_grant.created": "1.0", "authorization.permission_grant.revoked": "1.0", + "control_user.identity_linked": "1.0", "control_user.identity_unlinked": "1.0", + "control_user.invitation_created": "1.0", "control_user.invitation_resent": "1.0", + "control_user.invitation_revoked": "1.0", "control_user.invitation_accepted": "1.0", + "control_auth.policy_updated": "1.0", "control_auth.provider_login_enabled": "1.0", "control_auth.provider_login_disabled": "1.0", "delegation.created": "1.0", "delegation.exchanged": "1.0", "delegation.revoked": "1.0", "entitlement.granted": "1.0", "local_entitlement_request.created": "1.0", "local_entitlement_request.approved": "1.0", "oauth.consent_revoked": "1.0", "platform93.webhook.test": "1.0", "user.created": "1.0", @@ -88,6 +133,14 @@ export const platform93EventVersions: Readonly=22" + } +} diff --git a/sdk/typescript/expo/src/index.ts b/sdk/typescript/expo/src/index.ts new file mode 100644 index 0000000..ee99757 --- /dev/null +++ b/sdk/typescript/expo/src/index.ts @@ -0,0 +1,105 @@ +import { + Platform93Auth, + TokenStoreSessionAdapter, + type ExternalAuthStartOptions, + type TokenStore, +} from "@supaapps/platform93-auth"; +import type { + AuthenticationResult, + ExternalAuthFlow, + ExternalAuthProvider, + PasswordSignIn, + PasswordSignUp, +} from "@supaapps/platform93-sdk"; + +export interface ExpoSecureStore { + getItemAsync(key: string): Promise; + setItemAsync(key: string, value: string): Promise; + deleteItemAsync(key: string): Promise; +} + +export interface ExpoWebBrowser { + openAuthSessionAsync(url: string, redirectUrl: string): Promise<{ type: string; url?: string | null }>; +} + +export class ExpoSecureStoreTokenStore implements TokenStore { + constructor( + private readonly secureStore: ExpoSecureStore, + private readonly key = "platform93.refresh_token", + ) {} + + loadRefreshToken() { return this.secureStore.getItemAsync(this.key); } + + async saveRefreshToken(value: string | null) { + if (value === null) await this.secureStore.deleteItemAsync(this.key); + else await this.secureStore.setItemAsync(this.key, value); + } +} + +export type Platform93ExpoAuthOptions = { + baseUrl: string; + applicationId: string; + redirectUri: string; + secureStore: ExpoSecureStore; + webBrowser: ExpoWebBrowser; + storageKey?: string; + fetch?: typeof globalThis.fetch; +}; + +export class Platform93NativeAuthSessionError extends Error { + constructor(public readonly resultType: string) { + super(`Platform93 native authentication did not complete (${resultType})`); + this.name = "Platform93NativeAuthSessionError"; + } +} + +export class Platform93ExpoAuth { + readonly auth: Platform93Auth; + readonly redirectUri: string; + private readonly webBrowser: ExpoWebBrowser; + + constructor(options: Platform93ExpoAuthOptions) { + if (!options.redirectUri) throw new Error("Platform93 native redirectUri is required"); + this.redirectUri = options.redirectUri; + this.webBrowser = options.webBrowser; + const key = options.storageKey ?? `platform93.${options.applicationId}.refresh_token`; + this.auth = new Platform93Auth({ + baseUrl: options.baseUrl, + applicationId: options.applicationId, + adapter: new TokenStoreSessionAdapter(new ExpoSecureStoreTokenStore(options.secureStore, key)), + fetch: options.fetch, + channelName: false, + }); + } + + initialize() { return this.auth.refresh(false); } + snapshot() { return this.auth.snapshot(); } + getAccessToken() { return this.auth.getAccessToken(); } + signIn(input: PasswordSignIn) { return this.auth.signIn(input); } + signUp(input: PasswordSignUp) { return this.auth.signUp(input); } + logout() { return this.auth.logout(); } + + signInWithGoogle(options: Omit = {}) { + return this.openProviderSession("google", options); + } + + signInWithApple(options: { flow?: ExternalAuthFlow } = {}) { + return this.openProviderSession("apple", options); + } + + async openProviderSession( + provider: ExternalAuthProvider, + options: { flow?: ExternalAuthFlow; loginHint?: string } = {}, + ): Promise { + const authorization = await this.auth.startExternalAuth(provider, { + redirectUri: this.redirectUri, + flow: options.flow, + loginHint: options.loginHint, + }); + const result = await this.webBrowser.openAuthSessionAsync(authorization.authorize_url, this.redirectUri); + if (result.type !== "success" || !result.url) { + throw new Platform93NativeAuthSessionError(result.type); + } + return this.auth.completeExternalAuthRedirect(provider, result.url); + } +} diff --git a/sdk/typescript/expo/test/expo.test.mjs b/sdk/typescript/expo/test/expo.test.mjs new file mode 100644 index 0000000..b203edf --- /dev/null +++ b/sdk/typescript/expo/test/expo.test.mjs @@ -0,0 +1,46 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { Platform93ExpoAuth, Platform93NativeAuthSessionError } from "../dist/index.js"; + +const tokens = { access_token: "access", refresh_token: "refresh", token_type: "Bearer", expires_in: 300 }; + +test("Google login opens an auth session and stores the exchanged refresh token", async () => { + const values = new Map(); + const secureStore = { + getItemAsync: async (key) => values.get(key) ?? null, + setItemAsync: async (key, value) => { values.set(key, value); }, + deleteItemAsync: async (key) => { values.delete(key); }, + }; + const webBrowser = { + openAuthSessionAsync: async (url, redirectUri) => { + assert.equal(url, "https://accounts.google.test/authorize"); + assert.equal(redirectUri, "sampleapp://auth/callback"); + return { type: "success", url: "sampleapp://auth/callback?external_auth_exchange=once" }; + }, + }; + const fetch = async (input, init = {}) => { + if (String(input).endsWith("/auth/providers/google/start")) { + assert.deepEqual(JSON.parse(init.body), { redirect_uri: "sampleapp://auth/callback", flow: "automatic" }); + return Response.json({ provider: "google", authorize_url: "https://accounts.google.test/authorize", expires_in: 600 }, { status: 201 }); + } + if (String(input).endsWith("/auth/providers/google/exchange")) return Response.json(tokens); + throw new Error(`unexpected request ${input}`); + }; + const auth = new Platform93ExpoAuth({ baseUrl: "https://platform93.test", applicationId: "application", redirectUri: "sampleapp://auth/callback", secureStore, webBrowser, fetch }); + await auth.signInWithGoogle({ flow: "automatic" }); + assert.equal(values.get("platform93.application.refresh_token"), "refresh"); + assert.equal(auth.snapshot().status, "authenticated"); +}); + +test("cancelled native authentication is reported without exchanging credentials", async () => { + const auth = new Platform93ExpoAuth({ + baseUrl: "https://platform93.test", + applicationId: "application", + redirectUri: "sampleapp://auth/callback", + secureStore: { getItemAsync: async () => null, setItemAsync: async () => {}, deleteItemAsync: async () => {} }, + webBrowser: { openAuthSessionAsync: async () => ({ type: "cancel" }) }, + fetch: async () => Response.json({ provider: "apple", authorize_url: "https://appleid.apple.com/auth/authorize", expires_in: 600 }, { status: 201 }), + }); + await assert.rejects(() => auth.signInWithApple(), (error) => error instanceof Platform93NativeAuthSessionError && error.resultType === "cancel"); +}); diff --git a/sdk/typescript/expo/tsconfig.json b/sdk/typescript/expo/tsconfig.json new file mode 100644 index 0000000..5669b10 --- /dev/null +++ b/sdk/typescript/expo/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { "outDir": "dist", "rootDir": "src" }, + "include": ["src/**/*.ts"] +} diff --git a/sdk/typescript/sdk/src/generated/index.ts b/sdk/typescript/sdk/src/generated/index.ts index 5f044b3..a3b048a 100644 --- a/sdk/typescript/sdk/src/generated/index.ts +++ b/sdk/typescript/sdk/src/generated/index.ts @@ -1,4 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts -export { acceptMyWorkspaceInvitation, acceptOrganizationInvitation, activateMyAddress, activateTotpEnrollment, activateWorkspaceAddress, anonymizeMyAccount, appleAuthCallback, approveLocalEntitlementRequest, archiveEventType, archiveInstallationNotificationTemplate, archiveMyWorkspace, archiveNotificationTemplate, authMethods, beginOidcAuthorization, beginWebAuthnAuthentication, beginWebAuthnRegistration, bootstrap, cancelMyLocalEntitlementRequest, cancelSubscription, changeOperatorPassword, changeSubscriptionPrice, checkMyPermissions, completeApplicationStorageUpload, completeControlApplicationStorageUpload, completeInstallationStorageUpload, completeMyStorageUpload, completeSetup, completeWorkspaceStorageUpload, configureAppleProvider, configureGoogleProvider, configureInstallationAuthProvider, configureOrganizationAuthProvider, createApplication, createApplicationDomain, createApplicationStorageProvider, createApplicationStorageUpload, createAuditExport, createBillingPortalSession, createBillingProvider, createBillingReconciliationRun, createCheckoutSession, createClient, createControlApplicationStorageUpload, createDelegation, createEntitlement, createEventType, createFeature, createInstallationBillingProvider, createInstallationNotificationProvider, createInstallationNotificationTemplate, createInstallationOperator, createInstallationStorageProvider, createInstallationStorageUpload, createManagementClient, createMyAddress, createMyStorageUpload, createMyWorkspace, createMyWorkspaceInvitation, createNotificationProvider, createNotificationTemplate, createOrganization, createOrganizationBillingProvider, createOrganizationInvitation, createOrganizationNotificationProvider, createOrganizationStorageProvider, createPersonalApiKey, createPrice, createProduct, createRefund, createRole, createRoleAssignment, createSenderIdentity, createSetupNotificationProvider, createUser, createWebhook, createWorkspace, createWorkspaceAddress, createWorkspaceInvitation, createWorkspaceStorageUpload, decideOidcAuthorization, deleteApplicationDomain, deleteApplicationStorageObject, deleteControlApplicationStorageObject, deleteInstallationOperator, deleteInstallationStorageObject, deleteMyAccount, deleteMyAddress, deleteMyStorageObject, deleteOrganizationMember, deleteOrganizationStorageObject, deleteRole, deleteRoleAssignment, deleteWorkspace, deleteWorkspaceAddress, deleteWorkspaceMember, deleteWorkspaceStorageObject, disableApplicationAuthProvider, disableApplicationStorageProvider, disableBillingProvider, disableClient, disableInstallationAuthProvider, disableInstallationBillingProvider, disableInstallationNotificationProvider, disableInstallationStorageProvider, disableManagementClient, disableMfaMethod, disableNotificationProvider, disableOrganizationAuthProvider, disableOrganizationBillingProvider, disableOrganizationNotificationProvider, disableOrganizationStorageProvider, disableWebhook, downloadApplicationStorageObject, downloadControlApplicationStorageObject, downloadInstallationStorageObject, downloadMyStorageObject, downloadOrganizationStorageObject, downloadWorkspaceStorageObject, emailChangeStart, emailChangeVerify, emailStart, emailVerificationStart, emailVerificationVerify, emailVerify, enableApplicationStorageProvider, enableInstallationStorageProvider, enableOrganizationStorageProvider, exchangeAppleAuth, exchangeDelegation, exchangeGoogleAuth, exchangeOidcToken, exportMyAccount, finishWebAuthnAuthentication, finishWebAuthnRegistration, getApplication, getApplicationStatistics, getApplicationStorageObject, getApplicationStorageProvider, getAuditExport, getAuditLog, getBillingProvider, getBillingReconciliationRun, getBillingStatistics, getCheckoutSession, getControlApplicationStorageObject, getCurrentUser, getDelegation, getDispute, getEntitlement, getEvent, getEventType, getInstallationBillingProvider, getInstallationNotificationProvider, getInstallationNotificationTemplate, getInstallationStorageObject, getInstallationStorageProvider, getInvoice, getLocalEntitlementRequest, getManagementApiStatus, getMyBillingProfile, getMyBillingSummary, getMyLocalEntitlementRequest, getMyStorageObject, getMyWorkspace, getNotification, getNotificationProvider, getNotificationStatistics, getNotificationTemplate, getOperatorAccount, getOrganization, getOrganizationBillingProvider, getOrganizationNotificationProvider, getOrganizationPolicy, getOrganizationStorageObject, getOrganizationStorageProvider, getPayment, getProduct, getRefund, getRole, getSubscription, getUser, getWebhook, getWebhookDelivery, getWorkspace, getWorkspaceBillingProfile, getWorkspaceStorageObject, googleAuthCallback, health, introspectOidcToken, leaveWorkspace, listApplicationAuthProviders, listApplicationDomains, listApplications, listApplicationStorageObjects, listApplicationStorageProviders, listAuditLogs, listAuthProviders, listBillingProviderEvents, listBillingProviders, listBillingReconciliationRuns, listClients, listControlApplicationStorageObjects, listDelegations, listDisputes, listEntitlements, listEvents, listEventTypes, listFeatures, listInstallationAuthProviders, listInstallationBillingProviders, listInstallationNotificationProviders, listInstallationNotificationTemplates, listInstallationNotificationTemplateVariables, listInstallationOperators, listInstallationStorageObjects, listInstallationStorageProviders, listInvoices, listLocalEntitlementRequests, listManagementClients, listMyAddresses, listMyEntitlements, listMyIdentities, listMyInvoices, listMyLocalEntitlementRequests, listMyMfaMethods, listMyNotificationPreferences, listMyOAuthConsents, listMyPayments, listMySessions, listMyStorageObjects, listMySubscriptions, listMyWorkspaceInvitations, listMyWorkspaceMembers, listMyWorkspaces, listNotificationProviders, listNotifications, listNotificationTemplates, listNotificationTemplateVariables, listOAuthConsents, listOperatorSessions, listOrganizationAuditLogs, listOrganizationAuthProviders, listOrganizationBillingProviders, listOrganizationInvitations, listOrganizationMembers, listOrganizationNotificationProviders, listOrganizations, listOrganizationStorageObjects, listOrganizationStorageProviders, listPayments, listPersonalApiKeys, listPrices, listProducts, listRefunds, listRoleAssignments, listRoles, listSenderIdentities, listSigningKeys, listSubscriptions, listUserAddresses, listUsers, listUserSessions, listWebhookDeliveries, listWebhooks, listWorkspaceAddresses, listWorkspaceInvitations, listWorkspaceMembers, listWorkspaces, listWorkspaceStorageObjects, localEntitlementCheckout, loginOperatorWithPassword, logoutAll, logoutAllOperatorSessions, logoutCurrentSession, logoutOperator, managementCreateApplication, managementCreateOrganization, managementGetOrganization, managementGetOrganizationPolicy, managementListApplications, managementListOrganizations, managementRestoreApplication, managementRestoreOrganization, managementRetireApplication, managementRetireOrganization, managementUpdateApplication, managementUpdateOrganization, managementUpdateOrganizationPolicy, oidcDiscovery, oidcJwks, oidcUserinfo, type Options, passwordChange, passwordResetStart, passwordResetVerify, passwordSignIn, passwordSignUp, previewInstallationNotificationTemplate, previewNotificationTemplate, publicCatalog, publicConfig, publishCustomEvent, publishInstallationNotificationTemplate, publishNotificationTemplate, queueNotification, readiness, recoverWorkspaceOwnership, refresh, refreshOperatorSession, regenerateRecoveryCodes, rejectLocalEntitlementRequest, removeMyWorkspaceMember, reopenLocalEntitlementRequest, replaceMyWorkspaceMemberRoles, replaceWorkspaceMemberRoles, replayBillingProviderEvent, replayWebhookDelivery, resendOrganizationInvitation, restoreApplication, restoreEntitlement, restoreOrganization, restoreUser, resumeSubscription, retireApplication, retireOrganization, retryNotification, revokeDelegation, revokeEntitlement, revokeMyOAuthConsent, revokeMySession, revokeOAuthConsent, revokeOidcToken, revokeOperatorSession, revokeOrganizationInvitation, revokePersonalApiKey, revokeUserSessions, revokeWorkspaceInvitation, rotateClientSecret, rotateManagementClientSecret, rotateSigningKey, rotateWebhookSecret, setDefaultSenderIdentity, setupStatus, startAppleAuth, startAppleLink, startGoogleAuth, startGoogleLink, startOperatorEmailLogin, startTotpEnrollment, stripeWebhook, suspendUser, testInstallationNotificationProvider, testNotificationProvider, testOrganizationNotificationProvider, testWebhook, transferMyWorkspaceOwnership, unlinkMyIdentity, unverifyUserEmail, unverifyUserOrganization, updateApplication, updateApplicationStorageProvider, updateAuthConfig, updateBillingProvider, updateClient, updateCurrentUser, updateEventType, updateInstallationAuthProvider, updateInstallationBillingProvider, updateInstallationNotificationProvider, updateInstallationNotificationTemplate, updateInstallationOperator, updateInstallationStorageProvider, updateInternalApplicationConfig, updateManagementApiStatus, updateMyAddress, updateMyBillingProfile, updateMyNotificationPreference, updateMyWorkspace, updateNotificationProvider, updateNotificationTemplate, updateOperatorAccount, updateOrganization, updateOrganizationAuthProvider, updateOrganizationBillingProvider, updateOrganizationMember, updateOrganizationNotificationProvider, updateOrganizationPolicy, updateOrganizationStorageProvider, updateProduct, updatePublicApplicationConfig, updateRole, updateUser, updateWebhook, updateWorkspace, updateWorkspaceAddress, updateWorkspaceBillingProfile, verifyApplicationDomain, verifyApplicationStorageProvider, verifyBillingProvider, verifyInstallationBillingProvider, verifyInstallationNotificationProvider, verifyInstallationStorageProvider, verifyMfa, verifyNotificationProvider, verifyOperatorEmailLogin, verifyOrganizationBillingProvider, verifyOrganizationNotificationProvider, verifyOrganizationStorageProvider, verifyUserEmail, verifyUserOrganization, version } from './sdk.gen.js'; -export type { AcceptMyWorkspaceInvitationData, AcceptMyWorkspaceInvitationResponses, AcceptOrganizationInvitation, AcceptOrganizationInvitationData, AcceptOrganizationInvitationError, AcceptOrganizationInvitationErrors, AcceptOrganizationInvitationResponses, AcceptOrganizationInvitationWritable, ActivateMyAddressData, ActivateMyAddressResponse, ActivateMyAddressResponses, ActivateTotpEnrollmentData, ActivateTotpEnrollmentResponses, ActivateWorkspaceAddressData, ActivateWorkspaceAddressResponse, ActivateWorkspaceAddressResponses, AnonymizeMyAccountData, AnonymizeMyAccountResponse, AnonymizeMyAccountResponses, AppleAuthCallbackData, ApplicationAuthConfig, ApplicationAuthConfig2, ApplicationFlowConfig, ApplicationId, ApplicationInternalConfig, ApproveLocalEntitlementRequestData, ApproveLocalEntitlementRequestResponses, ArchiveEventTypeData, ArchiveEventTypeResponse, ArchiveEventTypeResponses, ArchiveInstallationNotificationTemplateData, ArchiveInstallationNotificationTemplateResponse, ArchiveInstallationNotificationTemplateResponses, ArchiveMyWorkspaceData, ArchiveMyWorkspaceResponse, ArchiveMyWorkspaceResponses, ArchiveNotificationTemplateData, ArchiveNotificationTemplateResponse, ArchiveNotificationTemplateResponses, AuthMethodsData, AuthMethodsResponses, BeginOidcAuthorizationData, BeginOidcAuthorizationResponses, BeginWebAuthnAuthenticationData, BeginWebAuthnAuthenticationResponses, BeginWebAuthnRegistrationData, BeginWebAuthnRegistrationResponses, BootstrapData, BootstrapError, BootstrapErrors, BootstrapRequest, BootstrapRequestWritable, BootstrapResponses, CancelMyLocalEntitlementRequestData, CancelMyLocalEntitlementRequestResponse, CancelMyLocalEntitlementRequestResponses, CancelSubscriptionData, CancelSubscriptionResponse, CancelSubscriptionResponses, ChangeOperatorPasswordData, ChangeOperatorPasswordError, ChangeOperatorPasswordErrors, ChangeOperatorPasswordResponse, ChangeOperatorPasswordResponses, ChangeSubscriptionPriceData, ChangeSubscriptionPriceResponses, CheckMyPermissionsData, CheckMyPermissionsResponses, ClientOptions, CompleteApplicationStorageUploadData, CompleteApplicationStorageUploadResponses, CompleteControlApplicationStorageUploadData, CompleteControlApplicationStorageUploadResponses, CompleteInstallationStorageUploadData, CompleteInstallationStorageUploadResponses, CompleteMyStorageUploadData, CompleteMyStorageUploadResponses, CompleteSetupData, CompleteSetupError, CompleteSetupErrors, CompleteSetupResponses, CompleteWorkspaceStorageUploadData, CompleteWorkspaceStorageUploadResponses, ConfigureAppleProviderData, ConfigureAppleProviderResponses, ConfigureGoogleProviderData, ConfigureGoogleProviderResponses, ConfigureInstallationAuthProviderData, ConfigureInstallationAuthProviderResponses, ConfigureOrganizationAuthProviderData, ConfigureOrganizationAuthProviderResponses, ConfirmAffectedObjects, CreateApplicationData, CreateApplicationDomainData, CreateApplicationDomainResponses, CreateApplicationResponses, CreateApplicationStorageProviderData, CreateApplicationStorageProviderResponses, CreateApplicationStorageUploadData, CreateApplicationStorageUploadResponses, CreateAuditExportData, CreateAuditExportResponses, CreateBillingPortalSessionData, CreateBillingPortalSessionResponses, CreateBillingProvider, CreateBillingProviderData, CreateBillingProviderResponses, CreateBillingProviderWritable, CreateBillingReconciliationRunData, CreateBillingReconciliationRunResponses, CreateCheckout, CreateCheckoutSessionData, CreateCheckoutSessionResponses, CreateClientData, CreateClientResponses, CreateControlApplicationStorageUploadData, CreateControlApplicationStorageUploadResponses, CreateDelegationData, CreateDelegationResponses, CreateEntitlementData, CreateEntitlementResponses, CreateEventType, CreateEventTypeData, CreateEventTypeError, CreateEventTypeErrors, CreateEventTypeResponses, CreateFeature, CreateFeatureData, CreateFeatureError, CreateFeatureErrors, CreateFeatureResponses, CreateInstallationBillingProviderData, CreateInstallationBillingProviderResponses, CreateInstallationNotificationProviderData, CreateInstallationNotificationProviderResponses, CreateInstallationNotificationTemplateData, CreateInstallationNotificationTemplateResponses, CreateInstallationOperatorData, CreateInstallationOperatorResponses, CreateInstallationStorageProviderData, CreateInstallationStorageProviderResponses, CreateInstallationStorageUploadData, CreateInstallationStorageUploadResponse, CreateInstallationStorageUploadResponses, CreateManagementClient, CreateManagementClientData, CreateManagementClientError, CreateManagementClientErrors, CreateManagementClientResponses, CreateMyAddressData, CreateMyAddressResponses, CreateMyStorageUploadData, CreateMyStorageUploadResponses, CreateMyWorkspaceData, CreateMyWorkspaceInvitationData, CreateMyWorkspaceInvitationResponses, CreateMyWorkspaceResponses, CreateNotificationProviderData, CreateNotificationProviderResponses, CreateNotificationTemplateData, CreateNotificationTemplateResponses, CreateOrganizationBillingProviderData, CreateOrganizationBillingProviderResponses, CreateOrganizationData, CreateOrganizationError, CreateOrganizationErrors, CreateOrganizationInvitationData, CreateOrganizationInvitationResponses, CreateOrganizationNotificationProviderData, CreateOrganizationNotificationProviderResponses, CreateOrganizationResponses, CreateOrganizationStorageProviderData, CreateOrganizationStorageProviderResponses, CreatePersonalApiKey, CreatePersonalApiKeyData, CreatePersonalApiKeyResponses, CreatePrice, CreatePriceData, CreatePriceResponses, CreateProduct, CreateProductData, CreateProductResponses, CreateRefundData, CreateRefundResponses, CreateRoleAssignmentData, CreateRoleAssignmentResponses, CreateRoleData, CreateRoleResponses, CreateSenderIdentityData, CreateSenderIdentityResponses, CreateSetupNotificationProviderData, CreateSetupNotificationProviderResponses, CreateStorageProvider, CreateStorageProviderWritable, CreateStorageUpload, CreateUserData, CreateUserResponses, CreateWebhookData, CreateWebhookResponses, CreateWorkspaceAddressData, CreateWorkspaceAddressResponses, CreateWorkspaceData, CreateWorkspaceInvitationData, CreateWorkspaceInvitationResponses, CreateWorkspaceResponses, CreateWorkspaceStorageUploadData, CreateWorkspaceStorageUploadResponses, DecideOidcAuthorizationData, DecideOidcAuthorizationResponses, DeleteApplicationDomainData, DeleteApplicationDomainResponse, DeleteApplicationDomainResponses, DeleteApplicationStorageObjectData, DeleteApplicationStorageObjectResponse, DeleteApplicationStorageObjectResponses, DeleteControlApplicationStorageObjectData, DeleteControlApplicationStorageObjectResponse, DeleteControlApplicationStorageObjectResponses, DeleteInstallationOperatorData, DeleteInstallationOperatorResponse, DeleteInstallationOperatorResponses, DeleteInstallationStorageObjectData, DeleteInstallationStorageObjectResponse, DeleteInstallationStorageObjectResponses, DeleteMyAccountData, DeleteMyAccountResponse, DeleteMyAccountResponses, DeleteMyAddressData, DeleteMyAddressResponse, DeleteMyAddressResponses, DeleteMyStorageObjectData, DeleteMyStorageObjectResponse, DeleteMyStorageObjectResponses, DeleteOrganizationMemberData, DeleteOrganizationMemberResponse, DeleteOrganizationMemberResponses, DeleteOrganizationStorageObjectData, DeleteOrganizationStorageObjectResponse, DeleteOrganizationStorageObjectResponses, DeleteRoleAssignmentData, DeleteRoleAssignmentResponse, DeleteRoleAssignmentResponses, DeleteRoleData, DeleteRoleError, DeleteRoleErrors, DeleteRoleResponse, DeleteRoleResponses, DeleteWorkspaceAddressData, DeleteWorkspaceAddressResponse, DeleteWorkspaceAddressResponses, DeleteWorkspaceData, DeleteWorkspaceError, DeleteWorkspaceErrors, DeleteWorkspaceMemberData, DeleteWorkspaceMemberResponse, DeleteWorkspaceMemberResponses, DeleteWorkspaceResponse, DeleteWorkspaceResponses, DeleteWorkspaceStorageObjectData, DeleteWorkspaceStorageObjectResponse, DeleteWorkspaceStorageObjectResponses, DisableApplicationAuthProviderData, DisableApplicationAuthProviderResponse, DisableApplicationAuthProviderResponses, DisableApplicationStorageProviderData, DisableApplicationStorageProviderError, DisableApplicationStorageProviderErrors, DisableApplicationStorageProviderResponse, DisableApplicationStorageProviderResponses, DisableBillingProviderData, DisableBillingProviderError, DisableBillingProviderErrors, DisableBillingProviderResponse, DisableBillingProviderResponses, DisableClientData, DisableClientResponse, DisableClientResponses, DisableInstallationAuthProviderData, DisableInstallationAuthProviderResponse, DisableInstallationAuthProviderResponses, DisableInstallationBillingProviderData, DisableInstallationBillingProviderResponse, DisableInstallationBillingProviderResponses, DisableInstallationNotificationProviderData, DisableInstallationNotificationProviderError, DisableInstallationNotificationProviderErrors, DisableInstallationNotificationProviderResponse, DisableInstallationNotificationProviderResponses, DisableInstallationStorageProviderData, DisableInstallationStorageProviderError, DisableInstallationStorageProviderErrors, DisableInstallationStorageProviderResponse, DisableInstallationStorageProviderResponses, DisableManagementClientData, DisableManagementClientResponse, DisableManagementClientResponses, DisableMfaMethodData, DisableMfaMethodResponse, DisableMfaMethodResponses, DisableNotificationProviderData, DisableNotificationProviderResponse, DisableNotificationProviderResponses, DisableOrganizationAuthProviderData, DisableOrganizationAuthProviderResponse, DisableOrganizationAuthProviderResponses, DisableOrganizationBillingProviderData, DisableOrganizationBillingProviderResponse, DisableOrganizationBillingProviderResponses, DisableOrganizationNotificationProviderData, DisableOrganizationNotificationProviderResponse, DisableOrganizationNotificationProviderResponses, DisableOrganizationStorageProviderData, DisableOrganizationStorageProviderError, DisableOrganizationStorageProviderErrors, DisableOrganizationStorageProviderResponse, DisableOrganizationStorageProviderResponses, DisableWebhookData, DisableWebhookResponse, DisableWebhookResponses, DownloadApplicationStorageObjectData, DownloadApplicationStorageObjectResponses, DownloadControlApplicationStorageObjectData, DownloadControlApplicationStorageObjectResponses, DownloadInstallationStorageObjectData, DownloadInstallationStorageObjectResponses, DownloadMyStorageObjectData, DownloadMyStorageObjectResponses, DownloadOrganizationStorageObjectData, DownloadOrganizationStorageObjectResponses, DownloadWorkspaceStorageObjectData, DownloadWorkspaceStorageObjectResponses, EmailChangeStartData, EmailChangeStartResponses, EmailChangeVerifyData, EmailChangeVerifyResponse, EmailChangeVerifyResponses, EmailStart, EmailStartData, EmailStartResponses, EmailVerificationStartData, EmailVerificationStartResponses, EmailVerificationVerifyData, EmailVerificationVerifyResponse, EmailVerificationVerifyResponses, EmailVerify, EmailVerifyData, EmailVerifyResponse, EmailVerifyResponses, EmailVerifyWritable, EnableApplicationStorageProviderData, EnableApplicationStorageProviderResponses, EnableInstallationStorageProviderData, EnableInstallationStorageProviderResponses, EnableOrganizationStorageProviderData, EnableOrganizationStorageProviderResponses, EventEnvelope, EventTypeDefinition, ExchangeAppleAuthData, ExchangeAppleAuthResponse, ExchangeAppleAuthResponses, ExchangeDelegationData, ExchangeDelegationResponses, ExchangeGoogleAuthData, ExchangeGoogleAuthResponse, ExchangeGoogleAuthResponses, ExchangeOidcTokenData, ExchangeOidcTokenErrors, ExchangeOidcTokenResponses, ExportMyAccountData, ExportMyAccountResponses, FeatureValue, FinishWebAuthnAuthenticationData, FinishWebAuthnAuthenticationError, FinishWebAuthnAuthenticationErrors, FinishWebAuthnAuthenticationResponse, FinishWebAuthnAuthenticationResponses, FinishWebAuthnRegistrationData, FinishWebAuthnRegistrationResponses, ForceDelete, GetApplicationData, GetApplicationResponses, GetApplicationStatisticsData, GetApplicationStatisticsResponses, GetApplicationStorageObjectData, GetApplicationStorageObjectResponses, GetApplicationStorageProviderData, GetApplicationStorageProviderResponses, GetAuditExportData, GetAuditExportResponses, GetAuditLogData, GetAuditLogResponses, GetBillingProviderData, GetBillingProviderResponses, GetBillingReconciliationRunData, GetBillingReconciliationRunResponses, GetBillingStatisticsData, GetBillingStatisticsResponses, GetCheckoutSessionData, GetCheckoutSessionResponses, GetControlApplicationStorageObjectData, GetControlApplicationStorageObjectResponses, GetCurrentUserData, GetCurrentUserResponse, GetCurrentUserResponses, GetDelegationData, GetDelegationResponses, GetDisputeData, GetDisputeResponses, GetEntitlementData, GetEntitlementResponses, GetEventData, GetEventResponse, GetEventResponses, GetEventTypeData, GetEventTypeResponse, GetEventTypeResponses, GetInstallationBillingProviderData, GetInstallationBillingProviderResponses, GetInstallationNotificationProviderData, GetInstallationNotificationProviderError, GetInstallationNotificationProviderErrors, GetInstallationNotificationProviderResponses, GetInstallationNotificationTemplateData, GetInstallationNotificationTemplateResponses, GetInstallationStorageObjectData, GetInstallationStorageObjectResponses, GetInstallationStorageProviderData, GetInstallationStorageProviderResponses, GetInvoiceData, GetInvoiceResponses, GetLocalEntitlementRequestData, GetLocalEntitlementRequestResponses, GetManagementApiStatusData, GetManagementApiStatusResponse, GetManagementApiStatusResponses, GetMyBillingProfileData, GetMyBillingProfileResponses, GetMyBillingSummaryData, GetMyBillingSummaryResponses, GetMyLocalEntitlementRequestData, GetMyLocalEntitlementRequestResponses, GetMyStorageObjectData, GetMyStorageObjectResponses, GetMyWorkspaceData, GetMyWorkspaceResponses, GetNotificationData, GetNotificationProviderData, GetNotificationProviderResponses, GetNotificationResponses, GetNotificationStatisticsData, GetNotificationStatisticsResponses, GetNotificationTemplateData, GetNotificationTemplateResponses, GetOperatorAccountData, GetOperatorAccountResponses, GetOrganizationBillingProviderData, GetOrganizationBillingProviderResponses, GetOrganizationData, GetOrganizationNotificationProviderData, GetOrganizationNotificationProviderResponses, GetOrganizationPolicyData, GetOrganizationPolicyResponse, GetOrganizationPolicyResponses, GetOrganizationResponses, GetOrganizationStorageObjectData, GetOrganizationStorageObjectResponses, GetOrganizationStorageProviderData, GetOrganizationStorageProviderResponses, GetPaymentData, GetPaymentResponses, GetProductData, GetProductResponses, GetRefundData, GetRefundResponses, GetRoleData, GetRoleError, GetRoleErrors, GetRoleResponses, GetSubscriptionData, GetSubscriptionResponses, GetUserData, GetUserResponses, GetWebhookData, GetWebhookDeliveryData, GetWebhookDeliveryError, GetWebhookDeliveryErrors, GetWebhookDeliveryResponses, GetWebhookError, GetWebhookErrors, GetWebhookResponses, GetWorkspaceBillingProfileData, GetWorkspaceBillingProfileResponses, GetWorkspaceData, GetWorkspaceResponses, GetWorkspaceStorageObjectData, GetWorkspaceStorageObjectResponses, GoogleAuthCallbackData, HealthData, HealthResponses, IdempotencyKey, IfMatch, IncludeRetired, InternalApplicationConfig, IntrospectOidcTokenData, IntrospectOidcTokenResponses, LeaveWorkspaceData, LeaveWorkspaceResponse, LeaveWorkspaceResponses, ListApplicationAuthProvidersData, ListApplicationAuthProvidersResponse, ListApplicationAuthProvidersResponses, ListApplicationDomainsData, ListApplicationDomainsResponse, ListApplicationDomainsResponses, ListApplicationsData, ListApplicationsResponse, ListApplicationsResponses, ListApplicationStorageObjectsData, ListApplicationStorageObjectsResponse, ListApplicationStorageObjectsResponses, ListApplicationStorageProvidersData, ListApplicationStorageProvidersResponse, ListApplicationStorageProvidersResponses, ListAuditLogsData, ListAuditLogsResponse, ListAuditLogsResponses, ListAuthProvidersData, ListAuthProvidersResponse, ListAuthProvidersResponses, ListBillingProviderEventsData, ListBillingProviderEventsResponse, ListBillingProviderEventsResponses, ListBillingProvidersData, ListBillingProvidersResponse, ListBillingProvidersResponses, ListBillingReconciliationRunsData, ListBillingReconciliationRunsResponse, ListBillingReconciliationRunsResponses, ListClientsData, ListClientsResponse, ListClientsResponses, ListControlApplicationStorageObjectsData, ListControlApplicationStorageObjectsResponse, ListControlApplicationStorageObjectsResponses, ListDelegationsData, ListDelegationsResponse, ListDelegationsResponses, ListDisputesData, ListDisputesResponse, ListDisputesResponses, ListEntitlementsData, ListEntitlementsResponse, ListEntitlementsResponses, ListEventsData, ListEventsResponse, ListEventsResponses, ListEventTypesData, ListEventTypesResponse, ListEventTypesResponses, ListFeaturesData, ListFeaturesResponse, ListFeaturesResponses, ListInstallationAuthProvidersData, ListInstallationAuthProvidersResponse, ListInstallationAuthProvidersResponses, ListInstallationBillingProvidersData, ListInstallationBillingProvidersResponse, ListInstallationBillingProvidersResponses, ListInstallationNotificationProvidersData, ListInstallationNotificationProvidersResponse, ListInstallationNotificationProvidersResponses, ListInstallationNotificationTemplatesData, ListInstallationNotificationTemplatesResponse, ListInstallationNotificationTemplatesResponses, ListInstallationNotificationTemplateVariablesData, ListInstallationNotificationTemplateVariablesResponses, ListInstallationOperatorsData, ListInstallationOperatorsResponse, ListInstallationOperatorsResponses, ListInstallationStorageObjectsData, ListInstallationStorageObjectsResponse, ListInstallationStorageObjectsResponses, ListInstallationStorageProvidersData, ListInstallationStorageProvidersResponse, ListInstallationStorageProvidersResponses, ListInvoicesData, ListInvoicesResponse, ListInvoicesResponses, ListLocalEntitlementRequestsData, ListLocalEntitlementRequestsResponse, ListLocalEntitlementRequestsResponses, ListManagementClientsData, ListManagementClientsResponse, ListManagementClientsResponses, ListMyAddressesData, ListMyAddressesResponse, ListMyAddressesResponses, ListMyEntitlementsData, ListMyEntitlementsResponses, ListMyIdentitiesData, ListMyIdentitiesResponse, ListMyIdentitiesResponses, ListMyInvoicesData, ListMyInvoicesResponse, ListMyInvoicesResponses, ListMyLocalEntitlementRequestsData, ListMyLocalEntitlementRequestsResponse, ListMyLocalEntitlementRequestsResponses, ListMyMfaMethodsData, ListMyMfaMethodsResponse, ListMyMfaMethodsResponses, ListMyNotificationPreferencesData, ListMyNotificationPreferencesResponse, ListMyNotificationPreferencesResponses, ListMyOAuthConsentsData, ListMyOAuthConsentsResponse, ListMyOAuthConsentsResponses, ListMyPaymentsData, ListMyPaymentsResponse, ListMyPaymentsResponses, ListMySessionsData, ListMySessionsResponse, ListMySessionsResponses, ListMyStorageObjectsData, ListMyStorageObjectsResponse, ListMyStorageObjectsResponses, ListMySubscriptionsData, ListMySubscriptionsResponse, ListMySubscriptionsResponses, ListMyWorkspaceInvitationsData, ListMyWorkspaceInvitationsResponse, ListMyWorkspaceInvitationsResponses, ListMyWorkspaceMembersData, ListMyWorkspaceMembersResponse, ListMyWorkspaceMembersResponses, ListMyWorkspacesData, ListMyWorkspacesResponse, ListMyWorkspacesResponses, ListNotificationProvidersData, ListNotificationProvidersResponse, ListNotificationProvidersResponses, ListNotificationsData, ListNotificationsResponse, ListNotificationsResponses, ListNotificationTemplatesData, ListNotificationTemplatesResponse, ListNotificationTemplatesResponses, ListNotificationTemplateVariablesData, ListNotificationTemplateVariablesResponses, ListOAuthConsentsData, ListOAuthConsentsResponse, ListOAuthConsentsResponses, ListOperatorSessionsData, ListOperatorSessionsResponse, ListOperatorSessionsResponses, ListOrganizationAuditLogsData, ListOrganizationAuditLogsResponse, ListOrganizationAuditLogsResponses, ListOrganizationAuthProvidersData, ListOrganizationAuthProvidersResponse, ListOrganizationAuthProvidersResponses, ListOrganizationBillingProvidersData, ListOrganizationBillingProvidersResponse, ListOrganizationBillingProvidersResponses, ListOrganizationInvitationsData, ListOrganizationInvitationsResponse, ListOrganizationInvitationsResponses, ListOrganizationMembersData, ListOrganizationMembersResponse, ListOrganizationMembersResponses, ListOrganizationNotificationProvidersData, ListOrganizationNotificationProvidersResponse, ListOrganizationNotificationProvidersResponses, ListOrganizationsData, ListOrganizationsResponse, ListOrganizationsResponses, ListOrganizationStorageObjectsData, ListOrganizationStorageObjectsResponse, ListOrganizationStorageObjectsResponses, ListOrganizationStorageProvidersData, ListOrganizationStorageProvidersResponse, ListOrganizationStorageProvidersResponses, ListPaymentsData, ListPaymentsResponse, ListPaymentsResponses, ListPersonalApiKeysData, ListPersonalApiKeysError, ListPersonalApiKeysErrors, ListPersonalApiKeysResponse, ListPersonalApiKeysResponses, ListPricesData, ListPricesResponse, ListPricesResponses, ListProductsData, ListProductsResponse, ListProductsResponses, ListRefundsData, ListRefundsResponse, ListRefundsResponses, ListRoleAssignmentsData, ListRoleAssignmentsResponse, ListRoleAssignmentsResponses, ListRolesData, ListRolesResponse, ListRolesResponses, ListSenderIdentitiesData, ListSenderIdentitiesResponse, ListSenderIdentitiesResponses, ListSigningKeysData, ListSigningKeysResponse, ListSigningKeysResponses, ListSubscriptionsData, ListSubscriptionsResponse, ListSubscriptionsResponses, ListUserAddressesData, ListUserAddressesResponse, ListUserAddressesResponses, ListUsersData, ListUserSessionsData, ListUserSessionsResponse, ListUserSessionsResponses, ListUsersResponse, ListUsersResponses, ListWebhookDeliveriesData, ListWebhookDeliveriesResponse, ListWebhookDeliveriesResponses, ListWebhooksData, ListWebhooksResponse, ListWebhooksResponses, ListWorkspaceAddressesData, ListWorkspaceAddressesResponse, ListWorkspaceAddressesResponses, ListWorkspaceInvitationsData, ListWorkspaceInvitationsResponse, ListWorkspaceInvitationsResponses, ListWorkspaceMembersData, ListWorkspaceMembersResponse, ListWorkspaceMembersResponses, ListWorkspacesData, ListWorkspacesResponse, ListWorkspacesResponses, ListWorkspaceStorageObjectsData, ListWorkspaceStorageObjectsResponse, ListWorkspaceStorageObjectsResponses, LocalCheckout, Locale, LocalEntitlementCheckoutData, LocalEntitlementCheckoutResponses, LoginOperatorWithPasswordData, LoginOperatorWithPasswordError, LoginOperatorWithPasswordErrors, LoginOperatorWithPasswordResponses, LogoutAllData, LogoutAllOperatorSessionsData, LogoutAllOperatorSessionsResponse, LogoutAllOperatorSessionsResponses, LogoutAllResponse, LogoutAllResponses, LogoutCurrentSessionData, LogoutCurrentSessionResponse, LogoutCurrentSessionResponses, LogoutOperatorData, LogoutOperatorResponse, LogoutOperatorResponses, ManagementApiStatus, ManagementCreateApplicationData, ManagementCreateApplicationError, ManagementCreateApplicationErrors, ManagementCreateApplicationResponses, ManagementCreateOrganizationData, ManagementCreateOrganizationResponses, ManagementGetOrganizationData, ManagementGetOrganizationPolicyData, ManagementGetOrganizationPolicyResponse, ManagementGetOrganizationPolicyResponses, ManagementGetOrganizationResponses, ManagementListApplicationsData, ManagementListApplicationsResponse, ManagementListApplicationsResponses, ManagementListOrganizationsData, ManagementListOrganizationsResponse, ManagementListOrganizationsResponses, ManagementRestoreApplicationData, ManagementRestoreApplicationResponse, ManagementRestoreApplicationResponses, ManagementRestoreOrganizationData, ManagementRestoreOrganizationResponse, ManagementRestoreOrganizationResponses, ManagementRetireApplicationData, ManagementRetireApplicationResponse, ManagementRetireApplicationResponses, ManagementRetireOrganizationData, ManagementRetireOrganizationResponse, ManagementRetireOrganizationResponses, ManagementUpdateApplicationData, ManagementUpdateApplicationResponse, ManagementUpdateApplicationResponses, ManagementUpdateOrganizationData, ManagementUpdateOrganizationPolicyData, ManagementUpdateOrganizationPolicyResponse, ManagementUpdateOrganizationPolicyResponses, ManagementUpdateOrganizationResponse, ManagementUpdateOrganizationResponses, Named, OAuthAuthorizationDecision, OAuthClientId, OAuthCodeChallenge, OAuthCodeChallengeMethod, OAuthRedirectUri, OAuthResponseType, OAuthScope, OAuthState, OAuthToken, OAuthTokenCredential, Object, ObjectId, OidcDiscoveryData, OidcDiscoveryResponses, OidcJwksData, OidcJwksResponses, OidcUserinfoData, OidcUserinfoError, OidcUserinfoErrors, OidcUserinfoResponses, OperatorPasswordChange, OperatorPasswordLogin, OperatorPasswordLoginWritable, OrganizationEnabledSettings, OrganizationId, OrganizationPage, OrganizationPolicy, OwnershipTransfer, OwnershipTransfer2, OwnershipTransferResult, Page, PasswordChangeData, PasswordChangeResponse, PasswordChangeResponses, PasswordResetStartData, PasswordResetStartResponses, PasswordResetVerifyData, PasswordResetVerifyResponse, PasswordResetVerifyResponses, PasswordSignIn, PasswordSignInData, PasswordSignInError, PasswordSignInErrors, PasswordSignInResponse, PasswordSignInResponses, PasswordSignInWritable, PasswordSignUp, PasswordSignUpData, PasswordSignUpError, PasswordSignUpErrors, PasswordSignUpResponse, PasswordSignUpResponses, PasswordSignUpWritable, PaymentId, PreviewInstallationNotificationTemplateData, PreviewInstallationNotificationTemplateResponses, PreviewNotificationTemplateData, PreviewNotificationTemplateResponses, Problem, ProviderId, ProviderInheritance, PublicApplicationConfig, PublicCatalogData, PublicCatalogResponse, PublicCatalogResponses, PublicConfigData, PublicConfigResponse, PublicConfigResponses, PublishCustomEvent, PublishCustomEventData, PublishCustomEventError, PublishCustomEventErrors, PublishCustomEventResponse, PublishCustomEventResponses, PublishInstallationNotificationTemplateData, PublishInstallationNotificationTemplateResponse, PublishInstallationNotificationTemplateResponses, PublishNotificationTemplateData, PublishNotificationTemplateResponse, PublishNotificationTemplateResponses, QueuedNotification, QueueNotification, QueueNotificationData, QueueNotificationResponse, QueueNotificationResponses, ReadinessData, ReadinessError, ReadinessErrors, ReadinessResponses, RecoverWorkspaceOwnershipData, RecoverWorkspaceOwnershipResponse, RecoverWorkspaceOwnershipResponses, RefreshData, RefreshOperatorSessionData, RefreshOperatorSessionResponses, RefreshResponse, RefreshResponses, RegenerateRecoveryCodesData, RegenerateRecoveryCodesResponses, RejectLocalEntitlementRequestData, RejectLocalEntitlementRequestResponse, RejectLocalEntitlementRequestResponses, RemoveMyWorkspaceMemberData, RemoveMyWorkspaceMemberResponse, RemoveMyWorkspaceMemberResponses, Rename, ReopenLocalEntitlementRequestData, ReopenLocalEntitlementRequestResponse, ReopenLocalEntitlementRequestResponses, ReplaceMyWorkspaceMemberRolesData, ReplaceMyWorkspaceMemberRolesResponses, ReplaceWorkspaceMemberRolesData, ReplaceWorkspaceMemberRolesResponses, ReplayBillingProviderEventData, ReplayBillingProviderEventResponse, ReplayBillingProviderEventResponses, ReplayWebhookDeliveryData, ReplayWebhookDeliveryResponse, ReplayWebhookDeliveryResponses, RequestId, RequiredIdempotencyKey, ResendOrganizationInvitationData, ResendOrganizationInvitationResponses, RestoreApplicationData, RestoreApplicationResponse, RestoreApplicationResponses, RestoreEntitlementData, RestoreEntitlementResponse, RestoreEntitlementResponses, RestoreOrganizationData, RestoreOrganizationResponse, RestoreOrganizationResponses, RestoreUserData, RestoreUserResponse, RestoreUserResponses, ResumeSubscriptionData, ResumeSubscriptionResponse, ResumeSubscriptionResponses, RetireApplicationData, RetireApplicationResponse, RetireApplicationResponses, RetireOrganizationData, RetireOrganizationResponse, RetireOrganizationResponses, RetryNotificationData, RetryNotificationResponse, RetryNotificationResponses, RevokeDelegationData, RevokeDelegationResponse, RevokeDelegationResponses, RevokeEntitlementData, RevokeEntitlementResponse, RevokeEntitlementResponses, RevokeMyOAuthConsentData, RevokeMyOAuthConsentResponse, RevokeMyOAuthConsentResponses, RevokeMySessionData, RevokeMySessionResponse, RevokeMySessionResponses, RevokeOAuthConsentData, RevokeOAuthConsentResponse, RevokeOAuthConsentResponses, RevokeOidcTokenData, RevokeOidcTokenResponses, RevokeOperatorSessionData, RevokeOperatorSessionResponse, RevokeOperatorSessionResponses, RevokeOrganizationInvitationData, RevokeOrganizationInvitationResponse, RevokeOrganizationInvitationResponses, RevokePersonalApiKeyData, RevokePersonalApiKeyResponse, RevokePersonalApiKeyResponses, RevokeUserSessionsData, RevokeUserSessionsResponses, RevokeWorkspaceInvitationData, RevokeWorkspaceInvitationResponse, RevokeWorkspaceInvitationResponses, RoleAssignment, RoleAssignment2, RotateClientSecretData, RotateClientSecretResponses, RotateManagementClientSecretData, RotateManagementClientSecretResponses, RotateSigningKeyData, RotateSigningKeyResponses, RotateWebhookSecretData, RotateWebhookSecretResponses, RuntimeAuthConfig, RuntimeConfig, RuntimeStorageConfig, SessionId, SetDefaultSenderIdentityData, SetDefaultSenderIdentityResponse, SetDefaultSenderIdentityResponses, SetupStatusData, SetupStatusResponse, SetupStatusResponses, SmtpProvider, StartAppleAuthData, StartAppleAuthResponses, StartAppleLinkData, StartAppleLinkResponses, StartGoogleAuthData, StartGoogleAuthResponses, StartGoogleLinkData, StartGoogleLinkResponses, StartOperatorEmailLoginData, StartOperatorEmailLoginResponses, StartTotpEnrollmentData, StartTotpEnrollmentResponses, StorageObject, StorageProvider, StorageUpload, StorageUploadAuthorization, StorageUploadAuthorizationWritable, StripeWebhookData, StripeWebhookError, StripeWebhookErrors, StripeWebhookResponses, SubscriptionId, SuspendUserData, SuspendUserResponse, SuspendUserResponses, TestInstallationNotificationProviderData, TestInstallationNotificationProviderError, TestInstallationNotificationProviderErrors, TestInstallationNotificationProviderResponses, TestNotificationProviderData, TestNotificationProviderResponses, TestOrganizationNotificationProviderData, TestOrganizationNotificationProviderResponses, TestWebhookData, TestWebhookError, TestWebhookErrors, TestWebhookResponses, TokenResponse, TokenResponseWritable, TransferMyWorkspaceOwnershipData, TransferMyWorkspaceOwnershipResponse, TransferMyWorkspaceOwnershipResponses, UnlinkMyIdentityData, UnlinkMyIdentityResponse, UnlinkMyIdentityResponses, UnverifyUserEmailData, UnverifyUserEmailResponse, UnverifyUserEmailResponses, UnverifyUserOrganizationData, UnverifyUserOrganizationResponse, UnverifyUserOrganizationResponses, UpdateApplicationData, UpdateApplicationError, UpdateApplicationErrors, UpdateApplicationResponse, UpdateApplicationResponses, UpdateApplicationStorageProviderData, UpdateApplicationStorageProviderResponses, UpdateAuthConfigData, UpdateAuthConfigResponse, UpdateAuthConfigResponses, UpdateBillingProviderData, UpdateBillingProviderResponse, UpdateBillingProviderResponses, UpdateClientData, UpdateClientResponse, UpdateClientResponses, UpdateCurrentUserData, UpdateCurrentUserResponse, UpdateCurrentUserResponses, UpdateEventType, UpdateEventTypeData, UpdateEventTypeError, UpdateEventTypeErrors, UpdateEventTypeResponse, UpdateEventTypeResponses, UpdateInstallationAuthProviderData, UpdateInstallationAuthProviderError, UpdateInstallationAuthProviderErrors, UpdateInstallationAuthProviderResponse, UpdateInstallationAuthProviderResponses, UpdateInstallationBillingProviderData, UpdateInstallationBillingProviderResponse, UpdateInstallationBillingProviderResponses, UpdateInstallationNotificationProviderData, UpdateInstallationNotificationProviderError, UpdateInstallationNotificationProviderErrors, UpdateInstallationNotificationProviderResponses, UpdateInstallationNotificationTemplateData, UpdateInstallationNotificationTemplateResponses, UpdateInstallationOperatorData, UpdateInstallationOperatorResponse, UpdateInstallationOperatorResponses, UpdateInstallationStorageProviderData, UpdateInstallationStorageProviderResponses, UpdateInternalApplicationConfigData, UpdateInternalApplicationConfigError, UpdateInternalApplicationConfigErrors, UpdateInternalApplicationConfigResponse, UpdateInternalApplicationConfigResponses, UpdateManagementApiStatusData, UpdateManagementApiStatusResponses, UpdateMyAddressData, UpdateMyAddressResponse, UpdateMyAddressResponses, UpdateMyBillingProfileData, UpdateMyBillingProfileResponse, UpdateMyBillingProfileResponses, UpdateMyNotificationPreferenceData, UpdateMyNotificationPreferenceResponse, UpdateMyNotificationPreferenceResponses, UpdateMyWorkspaceData, UpdateMyWorkspaceResponse, UpdateMyWorkspaceResponses, UpdateNotificationProviderData, UpdateNotificationProviderResponses, UpdateNotificationTemplateData, UpdateNotificationTemplateResponses, UpdateOperatorAccountData, UpdateOperatorAccountResponse, UpdateOperatorAccountResponses, UpdateOrganizationAuthProviderData, UpdateOrganizationAuthProviderError, UpdateOrganizationAuthProviderErrors, UpdateOrganizationAuthProviderResponse, UpdateOrganizationAuthProviderResponses, UpdateOrganizationBillingProviderData, UpdateOrganizationBillingProviderResponse, UpdateOrganizationBillingProviderResponses, UpdateOrganizationData, UpdateOrganizationError, UpdateOrganizationErrors, UpdateOrganizationMemberData, UpdateOrganizationMemberResponse, UpdateOrganizationMemberResponses, UpdateOrganizationNotificationProviderData, UpdateOrganizationNotificationProviderResponses, UpdateOrganizationPolicy, UpdateOrganizationPolicyData, UpdateOrganizationPolicyError, UpdateOrganizationPolicyErrors, UpdateOrganizationPolicyResponse, UpdateOrganizationPolicyResponses, UpdateOrganizationResponse, UpdateOrganizationResponses, UpdateOrganizationStorageProviderData, UpdateOrganizationStorageProviderResponses, UpdateProduct, UpdateProductData, UpdateProductResponse, UpdateProductResponses, UpdatePublicApplicationConfigData, UpdatePublicApplicationConfigError, UpdatePublicApplicationConfigErrors, UpdatePublicApplicationConfigResponse, UpdatePublicApplicationConfigResponses, UpdateRoleData, UpdateRoleError, UpdateRoleErrors, UpdateRoleResponse, UpdateRoleResponses, UpdateUserData, UpdateUserProfile, UpdateUserResponse, UpdateUserResponses, UpdateWebhookData, UpdateWebhookError, UpdateWebhookErrors, UpdateWebhookResponse, UpdateWebhookResponses, UpdateWorkspaceAddressData, UpdateWorkspaceAddressResponse, UpdateWorkspaceAddressResponses, UpdateWorkspaceBillingProfileData, UpdateWorkspaceBillingProfileResponse, UpdateWorkspaceBillingProfileResponses, UpdateWorkspaceData, UpdateWorkspaceResponse, UpdateWorkspaceResponses, User, Uuid, VerifyApplicationDomainData, VerifyApplicationDomainResponse, VerifyApplicationDomainResponses, VerifyApplicationStorageProviderData, VerifyApplicationStorageProviderResponse, VerifyApplicationStorageProviderResponses, VerifyBillingProviderData, VerifyBillingProviderResponse, VerifyBillingProviderResponses, VerifyInstallationBillingProviderData, VerifyInstallationBillingProviderResponse, VerifyInstallationBillingProviderResponses, VerifyInstallationNotificationProviderData, VerifyInstallationNotificationProviderError, VerifyInstallationNotificationProviderErrors, VerifyInstallationNotificationProviderResponse, VerifyInstallationNotificationProviderResponses, VerifyInstallationStorageProviderData, VerifyInstallationStorageProviderError, VerifyInstallationStorageProviderErrors, VerifyInstallationStorageProviderResponse, VerifyInstallationStorageProviderResponses, VerifyMfaData, VerifyMfaError, VerifyMfaErrors, VerifyMfaResponse, VerifyMfaResponses, VerifyNotificationProviderData, VerifyNotificationProviderError, VerifyNotificationProviderErrors, VerifyNotificationProviderResponse, VerifyNotificationProviderResponses, VerifyOperatorEmailLoginData, VerifyOperatorEmailLoginResponses, VerifyOrganizationBillingProviderData, VerifyOrganizationBillingProviderResponse, VerifyOrganizationBillingProviderResponses, VerifyOrganizationNotificationProviderData, VerifyOrganizationNotificationProviderResponse, VerifyOrganizationNotificationProviderResponses, VerifyOrganizationStorageProviderData, VerifyOrganizationStorageProviderResponse, VerifyOrganizationStorageProviderResponses, VerifyUserEmailData, VerifyUserEmailResponse, VerifyUserEmailResponses, VerifyUserOrganizationData, VerifyUserOrganizationResponse, VerifyUserOrganizationResponses, VersionData, VersionResponse, VersionResponses, WorkspaceId, WorkspaceIdQuery } from './types.gen.js'; +export { acceptControlUserInvitation, activateMyAddress, activateTotpEnrollment, activateWorkspaceAddress, adjustEntitlement, anonymizeMyAccount, appleAuthCallback, approveLocalEntitlementRequest, archiveEventType, archiveInstallationNotificationTemplate, archiveMyWorkspace, archiveNotificationTemplate, authMethods, beginOidcAuthorization, beginWebAuthnAuthentication, beginWebAuthnRegistration, bootstrap, cancelMyLocalEntitlementRequest, cancelSubscription, changeControlUserPassword, changeSubscriptionPrice, checkMyPermissions, completeApplicationStorageUpload, completeControlApplicationStorageUpload, completeInstallationStorageUpload, completeMyStorageUpload, completeSetup, completeWorkspaceStorageUpload, configureAppleProvider, configureGoogleProvider, configureInstallationAuthProvider, configureOrganizationAuthProvider, createApplication, createApplicationDomain, createApplicationInvitationControl, createApplicationInvitationMachine, createApplicationStorageProvider, createApplicationStorageUpload, createAuditExport, createBillingPortalSession, createBillingProvider, createBillingReconciliationRun, createCheckoutSession, createClient, createControlApplicationStorageUpload, createControlPermissionGrant, createDelegation, createEntitlement, createEventType, createFeature, createInstallationBillingProvider, createInstallationControlUserInvitation, createInstallationNotificationProvider, createInstallationNotificationTemplate, createInstallationStorageProvider, createInstallationStorageUpload, createManagementClient, createMyAddress, createMyStorageUpload, createMyWorkspace, createMyWorkspaceInvitation, createNotificationProvider, createNotificationTemplate, createOrganization, createOrganizationBillingProvider, createOrganizationInvitation, createOrganizationNotificationProvider, createOrganizationStorageProvider, createPermissionGrant, createPersonalApiKey, createPrice, createProduct, createRefund, createRole, createRoleAssignment, createSenderIdentity, createSetupNotificationProvider, createUser, createWebhook, createWorkspace, createWorkspaceAddress, createWorkspacePermissionGrant, createWorkspaceStorageUpload, decideOidcAuthorization, deleteApplicationDomain, deleteApplicationStorageObject, deleteControlApplicationStorageObject, deleteInstallationControlUser, deleteInstallationStorageObject, deleteMyAccount, deleteMyAddress, deleteMyStorageObject, deleteOrganizationMember, deleteOrganizationStorageObject, deleteRole, deleteRoleAssignment, deleteWorkspace, deleteWorkspaceAddress, deleteWorkspaceMember, deleteWorkspaceStorageObject, disableApplicationAuthProvider, disableApplicationStorageProvider, disableBillingProvider, disableClient, disableInstallationAuthProvider, disableInstallationBillingProvider, disableInstallationNotificationProvider, disableInstallationStorageProvider, disableManagementClient, disableMfaMethod, disableNotificationProvider, disableOrganizationAuthProvider, disableOrganizationBillingProvider, disableOrganizationNotificationProvider, disableOrganizationStorageProvider, disableWebhook, downloadApplicationStorageObject, downloadControlApplicationStorageObject, downloadInstallationStorageObject, downloadMyStorageObject, downloadOrganizationStorageObject, downloadWorkspaceStorageObject, emailChangeStart, emailChangeVerify, emailStart, emailVerificationStart, emailVerificationVerify, emailVerify, enableApplicationStorageProvider, enableInstallationStorageProvider, enableOrganizationStorageProvider, exchangeAppleAuth, exchangeApplicationInvitation, exchangeDelegation, exchangeGoogleAuth, exchangeOidcToken, exportMyAccount, finishWebAuthnAuthentication, finishWebAuthnRegistration, getApplication, getApplicationInvitation, getApplicationInvitationControl, getApplicationStatistics, getApplicationStorageObject, getApplicationStorageProvider, getAuditExport, getAuditLog, getBillingProvider, getBillingReconciliationRun, getBillingStatistics, getCheckoutSession, getClient, getControlApplicationStorageObject, getControlAuthMethods, getControlAuthPolicy, getControlEffectiveAccess, getControlPermissionGrant, getControlUserAccount, getCurrentUser, getDelegation, getDispute, getEffectiveAccess, getEntitlement, getEvent, getEventType, getInstallationBillingProvider, getInstallationNotificationProvider, getInstallationNotificationTemplate, getInstallationStorageObject, getInstallationStorageProvider, getInvoice, getLocalEntitlementRequest, getManagementApiStatus, getMyBillingProfile, getMyBillingSummary, getMyLocalEntitlementRequest, getMyStorageObject, getMyWorkspace, getNotification, getNotificationProvider, getNotificationStatistics, getNotificationTemplate, getOrganization, getOrganizationBillingProvider, getOrganizationNotificationProvider, getOrganizationPolicy, getOrganizationStorageObject, getOrganizationStorageProvider, getPayment, getPermissionGrant, getProduct, getRefund, getRole, getSubscription, getUser, getWebhook, getWebhookDelivery, getWorkspace, getWorkspaceBillingProfile, getWorkspacePermissionGrant, getWorkspaceStorageObject, googleAuthCallback, health, introspectOidcToken, leaveWorkspace, linkControlExternalIdentity, listApplicationAuthProviders, listApplicationDomains, listApplicationInvitations, listApplicationInvitationsControl, listApplications, listApplicationStorageObjects, listApplicationStorageProviders, listAuditLogs, listAuthProviders, listBillingProviderEvents, listBillingProviders, listBillingReconciliationRuns, listClients, listControlApplicationStorageObjects, listControlPermissionGrants, listControlUserSessions, listDelegations, listDisputes, listEntitlements, listEvents, listEventTypes, listFeatures, listInstallationAuthProviders, listInstallationBillingProviders, listInstallationControlUserInvitations, listInstallationControlUsers, listInstallationNotificationProviders, listInstallationNotificationTemplates, listInstallationNotificationTemplateVariables, listInstallationStorageObjects, listInstallationStorageProviders, listInvoices, listLocalEntitlementRequests, listManagementClients, listMyAddresses, listMyEntitlements, listMyIdentities, listMyInvoices, listMyLocalEntitlementRequests, listMyMfaMethods, listMyNotificationPreferences, listMyOAuthConsents, listMyPayments, listMyPendingInvitations, listMySessions, listMyStorageObjects, listMySubscriptions, listMyWorkspaceAccess, listMyWorkspaceInvitations, listMyWorkspaceMembers, listMyWorkspaces, listNotificationProviders, listNotifications, listNotificationTemplates, listNotificationTemplateVariables, listOAuthConsents, listOrganizationAuditLogs, listOrganizationAuthProviders, listOrganizationBillingProviders, listOrganizationInvitations, listOrganizationMembers, listOrganizationNotificationProviders, listOrganizations, listOrganizationStorageObjects, listOrganizationStorageProviders, listPayments, listPermissionGrants, listPersonalApiKeys, listPrices, listProducts, listRefunds, listRoleAssignments, listRoles, listSenderIdentities, listSigningKeys, listSubscriptions, listUserAddresses, listUsers, listUserSessions, listWebhookDeliveries, listWebhooks, listWorkspaceAddresses, listWorkspaceMembers, listWorkspacePermissionGrants, listWorkspaces, listWorkspaceStorageObjects, localEntitlementCheckout, loginControlUserWithPassword, logoutAll, logoutAllControlUserSessions, logoutControlUser, logoutCurrentSession, managementCreateApplication, managementCreateOrganization, managementGetOrganization, managementGetOrganizationPolicy, managementListApplications, managementListOrganizations, managementRestoreApplication, managementRestoreOrganization, managementRetireApplication, managementRetireOrganization, managementUpdateApplication, managementUpdateOrganization, managementUpdateOrganizationPolicy, oidcDiscovery, oidcJwks, oidcUserinfo, type Options, passwordChange, passwordResetStart, passwordResetVerify, passwordSignIn, passwordSignUp, previewInstallationNotificationTemplate, previewNotificationTemplate, publicCatalog, publicConfig, publishCustomEvent, publishInstallationNotificationTemplate, publishNotificationTemplate, readiness, recoverWorkspaceOwnership, redeemApplicationInvitation, refresh, refreshControlUserSession, regenerateRecoveryCodes, rejectLocalEntitlementRequest, removeMyWorkspaceMember, reopenLocalEntitlementRequest, replaceMyWorkspaceMemberRoles, replaceWorkspaceMemberRoles, replayBillingProviderEvent, replayWebhookDelivery, resendApplicationInvitation, resendApplicationInvitationControl, resendInstallationControlUserInvitation, resendMyWorkspaceInvitation, resendOrganizationInvitation, restoreApplication, restoreEntitlement, restoreOrganization, restoreUser, resumeSubscription, retireApplication, retireOrganization, retryNotification, revokeApplicationInvitation, revokeApplicationInvitationControl, revokeControlPermissionGrant, revokeControlUserSession, revokeDelegation, revokeEntitlement, revokeInstallationControlUserInvitation, revokeMyOAuthConsent, revokeMySession, revokeMyWorkspaceInvitation, revokeOAuthConsent, revokeOidcToken, revokeOrganizationInvitation, revokePermissionGrant, revokePersonalApiKey, revokeUserSessions, revokeWorkspacePermissionGrant, rotateClientSecret, rotateManagementClientSecret, rotateSigningKey, rotateWebhookSecret, sendMachineNotification, serviceGetApplicationUser, serviceGetApplicationWorkspace, serviceGetSubjectBilling, serviceGetSubjectEntitlements, serviceListApplicationUsers, serviceListApplicationWorkspaceAccess, serviceListApplicationWorkspaces, setDefaultSenderIdentity, setupStatus, startAppleAuth, startAppleLink, startControlExternalLogin, startControlInvitationExternalLogin, startControlUserEmailLogin, startGoogleAuth, startGoogleLink, startTotpEnrollment, stripeWebhook, suspendUser, testInstallationNotificationProvider, testNotificationProvider, testOrganizationNotificationProvider, testWebhook, transferMyWorkspaceOwnership, unlinkControlExternalIdentity, unlinkMyIdentity, unverifyUserEmail, unverifyUserOrganization, updateApplication, updateApplicationStorageProvider, updateAuthConfig, updateBillingProvider, updateClient, updateControlAuthPolicy, updateControlUserAccount, updateCurrentUser, updateEventType, updateInstallationAuthProvider, updateInstallationBillingProvider, updateInstallationControlUser, updateInstallationNotificationProvider, updateInstallationNotificationTemplate, updateInstallationStorageProvider, updateInternalApplicationConfig, updateManagementApiStatus, updateMyAddress, updateMyBillingProfile, updateMyNotificationPreference, updateMyWorkspace, updateNotificationProvider, updateNotificationTemplate, updateOrganization, updateOrganizationAuthProvider, updateOrganizationBillingProvider, updateOrganizationMember, updateOrganizationNotificationProvider, updateOrganizationPolicy, updateOrganizationStorageProvider, updateProduct, updatePublicApplicationConfig, updateRole, updateUser, updateWebhook, updateWorkspace, updateWorkspaceAddress, updateWorkspaceBillingProfile, verifyApplicationDomain, verifyApplicationStorageProvider, verifyBillingProvider, verifyControlUserEmailLogin, verifyInstallationBillingProvider, verifyInstallationNotificationProvider, verifyInstallationStorageProvider, verifyMfa, verifyNotificationProvider, verifyOrganizationBillingProvider, verifyOrganizationNotificationProvider, verifyOrganizationStorageProvider, verifyUserEmail, verifyUserOrganization, version } from './sdk.gen.js'; +export type { AcceptControlUserInvitation, AcceptControlUserInvitationData, AcceptControlUserInvitationError, AcceptControlUserInvitationErrors, AcceptControlUserInvitationResponse, AcceptControlUserInvitationResponses, AcceptControlUserInvitationWritable, AccountChallenge, AccountChallengeWritable, AccountExport, ActivateMyAddressData, ActivateMyAddressResponse, ActivateMyAddressResponses, ActivateTotp, ActivateTotpEnrollmentData, ActivateTotpEnrollmentResponse, ActivateTotpEnrollmentResponses, ActivateWorkspaceAddressData, ActivateWorkspaceAddressResponse, ActivateWorkspaceAddressResponses, Address, AddressPage, AdjustEntitlement, AdjustEntitlementData, AdjustEntitlementResponse, AdjustEntitlementResponses, AnonymizeMyAccountData, AnonymizeMyAccountResponse, AnonymizeMyAccountResponses, AppleAuthCallbackData, Application, ApplicationAuthConfig, ApplicationAuthConfig2, ApplicationDomain, ApplicationDomainPage, ApplicationFlowConfig, ApplicationId, ApplicationInternalConfig, ApplicationInvitation, ApplicationInvitationPage, ApplicationInvitationPageWritable, ApplicationInvitationWritable, ApplicationPage, ApplicationStatistics, ApproveLocalEntitlementRequestData, ApproveLocalEntitlementRequestResponse, ApproveLocalEntitlementRequestResponses, ArchiveEventTypeData, ArchiveEventTypeResponse, ArchiveEventTypeResponses, ArchiveInstallationNotificationTemplateData, ArchiveInstallationNotificationTemplateResponse, ArchiveInstallationNotificationTemplateResponses, ArchiveMyWorkspaceData, ArchiveMyWorkspaceResponse, ArchiveMyWorkspaceResponses, ArchiveNotificationTemplateData, ArchiveNotificationTemplateResponse, ArchiveNotificationTemplateResponses, AuditExport, AuditExportRecord, AuditReason, AuditRecord, AuditRecordPage, AuthMethods, AuthMethodsData, AuthMethodsResponse, AuthMethodsResponses, AuthorizationRedirect, AuthProvider, AuthProviderPage, BeginOidcAuthorizationData, BeginOidcAuthorizationResponse, BeginOidcAuthorizationResponses, BeginWebAuthnAuthentication, BeginWebAuthnAuthenticationData, BeginWebAuthnAuthenticationResponse, BeginWebAuthnAuthenticationResponses, BeginWebAuthnRegistration, BeginWebAuthnRegistrationData, BeginWebAuthnRegistrationResponse, BeginWebAuthnRegistrationResponses, BillingProfile, BillingProvider, BillingProviderEvent, BillingProviderEventPage, BillingProviderPage, BillingStatistics, BillingSummary, BootstrapData, BootstrapError, BootstrapErrors, BootstrapRequest, BootstrapRequestWritable, BootstrapResponse, BootstrapResponses, CancelMyLocalEntitlementRequestData, CancelMyLocalEntitlementRequestResponse, CancelMyLocalEntitlementRequestResponses, CancelSubscription, CancelSubscriptionData, CancelSubscriptionResponse, CancelSubscriptionResponses, ChallengeAccepted, ChangeControlUserPasswordData, ChangeControlUserPasswordError, ChangeControlUserPasswordErrors, ChangeControlUserPasswordResponse, ChangeControlUserPasswordResponses, ChangeSubscriptionPrice, ChangeSubscriptionPriceData, ChangeSubscriptionPriceResponse, ChangeSubscriptionPriceResponses, CheckMyPermissionsData, CheckMyPermissionsResponse, CheckMyPermissionsResponses, CheckoutSession, ClientOptions, CompleteApplicationStorageUploadData, CompleteApplicationStorageUploadResponse, CompleteApplicationStorageUploadResponses, CompleteControlApplicationStorageUploadData, CompleteControlApplicationStorageUploadResponse, CompleteControlApplicationStorageUploadResponses, CompleteInstallationStorageUploadData, CompleteInstallationStorageUploadResponse, CompleteInstallationStorageUploadResponses, CompleteMyStorageUploadData, CompleteMyStorageUploadResponse, CompleteMyStorageUploadResponses, CompleteSetup, CompleteSetupData, CompleteSetupError, CompleteSetupErrors, CompleteSetupResponse, CompleteSetupResponses, CompleteWorkspaceStorageUploadData, CompleteWorkspaceStorageUploadResponse, CompleteWorkspaceStorageUploadResponses, ConfigureAppleProviderData, ConfigureAppleProviderResponse, ConfigureAppleProviderResponses, ConfigureAuthProvider, ConfigureAuthProviderWritable, ConfigureGoogleProviderData, ConfigureGoogleProviderResponse, ConfigureGoogleProviderResponses, ConfigureInstallationAuthProviderData, ConfigureInstallationAuthProviderResponse, ConfigureInstallationAuthProviderResponses, ConfigureOrganizationAuthProviderData, ConfigureOrganizationAuthProviderResponse, ConfigureOrganizationAuthProviderResponses, ConfirmAffectedObjects, ControlAuthMethods, ControlAuthPolicy, ControlEmailStart, ControlInvitationProviderStart, ControlUser, ControlUserAccount, ControlUserInvitation, ControlUserInvitationPage, ControlUserInvitationPageWritable, ControlUserInvitationWritable, ControlUserPage, ControlUserPasswordChange, ControlUserPasswordLogin, ControlUserPasswordLoginWritable, CreateAddress, CreateApplicationData, CreateApplicationDomain, CreateApplicationDomainData, CreateApplicationDomainResponse, CreateApplicationDomainResponses, CreateApplicationInvitationControlData, CreateApplicationInvitationControlResponse, CreateApplicationInvitationControlResponses, CreateApplicationInvitationMachineData, CreateApplicationInvitationMachineResponse, CreateApplicationInvitationMachineResponses, CreateApplicationResponse, CreateApplicationResponses, CreateApplicationStorageProviderData, CreateApplicationStorageProviderResponse, CreateApplicationStorageProviderResponses, CreateApplicationStorageUploadData, CreateApplicationStorageUploadResponse, CreateApplicationStorageUploadResponses, CreateAuditExportData, CreateAuditExportResponse, CreateAuditExportResponses, CreateBillingPortalSessionData, CreateBillingPortalSessionResponse, CreateBillingPortalSessionResponses, CreateBillingProvider, CreateBillingProviderData, CreateBillingProviderResponse, CreateBillingProviderResponses, CreateBillingProviderWritable, CreateBillingReconciliationRunData, CreateBillingReconciliationRunResponse, CreateBillingReconciliationRunResponses, CreateCheckout, CreateCheckoutSessionData, CreateCheckoutSessionResponse, CreateCheckoutSessionResponses, CreateClient, CreateClientData, CreateClientResponse, CreateClientResponses, CreateControlApplicationStorageUploadData, CreateControlApplicationStorageUploadResponse, CreateControlApplicationStorageUploadResponses, CreateControlPermissionGrantData, CreateControlPermissionGrantError, CreateControlPermissionGrantErrors, CreateControlPermissionGrantResponse, CreateControlPermissionGrantResponses, CreateControlUserInvitation, CreateDelegation, CreateDelegationData, CreateDelegationResponse, CreateDelegationResponses, CreateEntitlement, CreateEntitlementData, CreateEntitlementResponse, CreateEntitlementResponses, CreateEventType, CreateEventTypeData, CreateEventTypeError, CreateEventTypeErrors, CreateEventTypeResponse, CreateEventTypeResponses, CreateFeature, CreateFeatureData, CreateFeatureError, CreateFeatureErrors, CreateFeatureResponse, CreateFeatureResponses, CreateInstallationBillingProviderData, CreateInstallationBillingProviderResponse, CreateInstallationBillingProviderResponses, CreateInstallationControlUserInvitationData, CreateInstallationControlUserInvitationResponse, CreateInstallationControlUserInvitationResponses, CreateInstallationNotificationProviderData, CreateInstallationNotificationProviderResponse, CreateInstallationNotificationProviderResponses, CreateInstallationNotificationTemplateData, CreateInstallationNotificationTemplateResponse, CreateInstallationNotificationTemplateResponses, CreateInstallationStorageProviderData, CreateInstallationStorageProviderResponse, CreateInstallationStorageProviderResponses, CreateInstallationStorageUploadData, CreateInstallationStorageUploadResponse, CreateInstallationStorageUploadResponses, CreateInvitation, CreateManagementClient, CreateManagementClientData, CreateManagementClientError, CreateManagementClientErrors, CreateManagementClientResponse, CreateManagementClientResponses, CreateMyAddressData, CreateMyAddressResponse, CreateMyAddressResponses, CreateMyStorageUploadData, CreateMyStorageUploadResponse, CreateMyStorageUploadResponses, CreateMyWorkspaceData, CreateMyWorkspaceInvitationData, CreateMyWorkspaceInvitationResponse, CreateMyWorkspaceInvitationResponses, CreateMyWorkspaceResponse, CreateMyWorkspaceResponses, CreateNotificationProviderData, CreateNotificationProviderResponse, CreateNotificationProviderResponses, CreateNotificationTemplate, CreateNotificationTemplateData, CreateNotificationTemplateResponse, CreateNotificationTemplateResponses, CreateOrganizationBillingProviderData, CreateOrganizationBillingProviderResponse, CreateOrganizationBillingProviderResponses, CreateOrganizationData, CreateOrganizationError, CreateOrganizationErrors, CreateOrganizationInvitationData, CreateOrganizationInvitationResponse, CreateOrganizationInvitationResponses, CreateOrganizationNotificationProviderData, CreateOrganizationNotificationProviderResponse, CreateOrganizationNotificationProviderResponses, CreateOrganizationResponse, CreateOrganizationResponses, CreateOrganizationStorageProviderData, CreateOrganizationStorageProviderResponse, CreateOrganizationStorageProviderResponses, CreatePermissionGrant, CreatePermissionGrantData, CreatePermissionGrantError, CreatePermissionGrantErrors, CreatePermissionGrantResponse, CreatePermissionGrantResponses, CreatePersonalApiKey, CreatePersonalApiKeyData, CreatePersonalApiKeyResponse, CreatePersonalApiKeyResponses, CreatePortalSession, CreatePrice, CreatePriceData, CreatePriceResponse, CreatePriceResponses, CreateProduct, CreateProductData, CreateProductResponse, CreateProductResponses, CreateRefund, CreateRefundData, CreateRefundResponse, CreateRefundResponses, CreateRole, CreateRoleAssignmentData, CreateRoleAssignmentResponse, CreateRoleAssignmentResponses, CreateRoleData, CreateRoleError, CreateRoleErrors, CreateRoleResponse, CreateRoleResponses, CreateSenderIdentity, CreateSenderIdentityData, CreateSenderIdentityResponse, CreateSenderIdentityResponses, CreateSetupNotificationProviderData, CreateSetupNotificationProviderResponse, CreateSetupNotificationProviderResponses, CreateStorageProvider, CreateStorageProviderWritable, CreateStorageUpload, CreateUser, CreateUserData, CreateUserResponse, CreateUserResponses, CreateUserWritable, CreateWebhook, CreateWebhookData, CreateWebhookResponse, CreateWebhookResponses, CreateWorkspace, CreateWorkspaceAddressData, CreateWorkspaceAddressResponse, CreateWorkspaceAddressResponses, CreateWorkspaceData, CreateWorkspacePermissionGrantData, CreateWorkspacePermissionGrantError, CreateWorkspacePermissionGrantErrors, CreateWorkspacePermissionGrantResponse, CreateWorkspacePermissionGrantResponses, CreateWorkspaceResponse, CreateWorkspaceResponses, CreateWorkspaceStorageUploadData, CreateWorkspaceStorageUploadResponse, CreateWorkspaceStorageUploadResponses, CurrencyTotal, DecideOidcAuthorizationData, DecideOidcAuthorizationResponse, DecideOidcAuthorizationResponses, Delegation, DelegationPage, DelegationPageWritable, DelegationWritable, DeleteApplicationDomainData, DeleteApplicationDomainResponse, DeleteApplicationDomainResponses, DeleteApplicationStorageObjectData, DeleteApplicationStorageObjectResponse, DeleteApplicationStorageObjectResponses, DeleteControlApplicationStorageObjectData, DeleteControlApplicationStorageObjectResponse, DeleteControlApplicationStorageObjectResponses, DeleteInstallationControlUserData, DeleteInstallationControlUserResponse, DeleteInstallationControlUserResponses, DeleteInstallationStorageObjectData, DeleteInstallationStorageObjectResponse, DeleteInstallationStorageObjectResponses, DeleteMyAccountData, DeleteMyAccountResponse, DeleteMyAccountResponses, DeleteMyAddressData, DeleteMyAddressResponse, DeleteMyAddressResponses, DeleteMyStorageObjectData, DeleteMyStorageObjectResponse, DeleteMyStorageObjectResponses, DeleteOrganizationMemberData, DeleteOrganizationMemberResponse, DeleteOrganizationMemberResponses, DeleteOrganizationStorageObjectData, DeleteOrganizationStorageObjectResponse, DeleteOrganizationStorageObjectResponses, DeleteRoleAssignmentData, DeleteRoleAssignmentResponse, DeleteRoleAssignmentResponses, DeleteRoleData, DeleteRoleError, DeleteRoleErrors, DeleteRoleResponse, DeleteRoleResponses, DeleteWorkspaceAddressData, DeleteWorkspaceAddressResponse, DeleteWorkspaceAddressResponses, DeleteWorkspaceData, DeleteWorkspaceError, DeleteWorkspaceErrors, DeleteWorkspaceMemberData, DeleteWorkspaceMemberResponse, DeleteWorkspaceMemberResponses, DeleteWorkspaceResponse, DeleteWorkspaceResponses, DeleteWorkspaceStorageObjectData, DeleteWorkspaceStorageObjectResponse, DeleteWorkspaceStorageObjectResponses, DisableApplicationAuthProviderData, DisableApplicationAuthProviderResponse, DisableApplicationAuthProviderResponses, DisableApplicationStorageProviderData, DisableApplicationStorageProviderError, DisableApplicationStorageProviderErrors, DisableApplicationStorageProviderResponse, DisableApplicationStorageProviderResponses, DisableBillingProviderData, DisableBillingProviderError, DisableBillingProviderErrors, DisableBillingProviderResponse, DisableBillingProviderResponses, DisableClientData, DisableClientResponse, DisableClientResponses, DisableInstallationAuthProviderData, DisableInstallationAuthProviderResponse, DisableInstallationAuthProviderResponses, DisableInstallationBillingProviderData, DisableInstallationBillingProviderResponse, DisableInstallationBillingProviderResponses, DisableInstallationNotificationProviderData, DisableInstallationNotificationProviderError, DisableInstallationNotificationProviderErrors, DisableInstallationNotificationProviderResponse, DisableInstallationNotificationProviderResponses, DisableInstallationStorageProviderData, DisableInstallationStorageProviderError, DisableInstallationStorageProviderErrors, DisableInstallationStorageProviderResponse, DisableInstallationStorageProviderResponses, DisableManagementClientData, DisableManagementClientResponse, DisableManagementClientResponses, DisableMfaMethodData, DisableMfaMethodResponse, DisableMfaMethodResponses, DisableNotificationProviderData, DisableNotificationProviderResponse, DisableNotificationProviderResponses, DisableOrganizationAuthProviderData, DisableOrganizationAuthProviderResponse, DisableOrganizationAuthProviderResponses, DisableOrganizationBillingProviderData, DisableOrganizationBillingProviderResponse, DisableOrganizationBillingProviderResponses, DisableOrganizationNotificationProviderData, DisableOrganizationNotificationProviderResponse, DisableOrganizationNotificationProviderResponses, DisableOrganizationStorageProviderData, DisableOrganizationStorageProviderError, DisableOrganizationStorageProviderErrors, DisableOrganizationStorageProviderResponse, DisableOrganizationStorageProviderResponses, DisableWebhookData, DisableWebhookResponse, DisableWebhookResponses, Dispute, DisputePage, DownloadApplicationStorageObjectData, DownloadApplicationStorageObjectResponse, DownloadApplicationStorageObjectResponses, DownloadControlApplicationStorageObjectData, DownloadControlApplicationStorageObjectResponse, DownloadControlApplicationStorageObjectResponses, DownloadInstallationStorageObjectData, DownloadInstallationStorageObjectResponse, DownloadInstallationStorageObjectResponses, DownloadMyStorageObjectData, DownloadMyStorageObjectResponse, DownloadMyStorageObjectResponses, DownloadOrganizationStorageObjectData, DownloadOrganizationStorageObjectResponse, DownloadOrganizationStorageObjectResponses, DownloadWorkspaceStorageObjectData, DownloadWorkspaceStorageObjectResponse, DownloadWorkspaceStorageObjectResponses, EffectiveAccess, EffectiveEntitlements, EmailAddress, EmailChangeStartData, EmailChangeStartResponse, EmailChangeStartResponses, EmailChangeVerifyData, EmailChangeVerifyResponse, EmailChangeVerifyResponses, EmailStart, EmailStartData, EmailStartResponse, EmailStartResponses, EmailVerificationStartData, EmailVerificationStartResponse, EmailVerificationStartResponses, EmailVerificationVerifyData, EmailVerificationVerifyResponse, EmailVerificationVerifyResponses, EmailVerify, EmailVerifyData, EmailVerifyResponse, EmailVerifyResponses, EmailVerifyWritable, EmptyResponse, EnableApplicationStorageProviderData, EnableApplicationStorageProviderResponse, EnableApplicationStorageProviderResponses, EnableInstallationStorageProviderData, EnableInstallationStorageProviderResponse, EnableInstallationStorageProviderResponses, EnableOrganizationStorageProviderData, EnableOrganizationStorageProviderResponse, EnableOrganizationStorageProviderResponses, EntitlementGrant, EntitlementGrantPage, EventEnvelope, EventPage, EventTypeDefinition, EventTypePage, ExchangeAppleAuthData, ExchangeAppleAuthResponse, ExchangeAppleAuthResponses, ExchangeApplicationInvitationData, ExchangeApplicationInvitationError, ExchangeApplicationInvitationErrors, ExchangeApplicationInvitationResponse, ExchangeApplicationInvitationResponses, ExchangeDelegation, ExchangeDelegationData, ExchangeDelegationResponse, ExchangeDelegationResponses, ExchangeGoogleAuthData, ExchangeGoogleAuthResponse, ExchangeGoogleAuthResponses, ExchangeInvitation, ExchangeInvitationWritable, ExchangeOidcTokenData, ExchangeOidcTokenErrors, ExchangeOidcTokenResponse, ExchangeOidcTokenResponses, ExportMyAccountData, ExportMyAccountResponse, ExportMyAccountResponses, ExternalAuthExchange, ExternalAuthStart, ExternalAuthStartRequest, ExternalIdentity, ExternalIdentityPage, Feature, FeaturePage, FeatureValue, FinishWebAuthnAuthenticationData, FinishWebAuthnAuthenticationError, FinishWebAuthnAuthenticationErrors, FinishWebAuthnAuthenticationResponse, FinishWebAuthnAuthenticationResponses, FinishWebAuthnCeremony, FinishWebAuthnRegistrationData, FinishWebAuthnRegistrationResponse, FinishWebAuthnRegistrationResponses, ForceDelete, GetApplicationData, GetApplicationInvitationControlData, GetApplicationInvitationControlResponse, GetApplicationInvitationControlResponses, GetApplicationInvitationData, GetApplicationInvitationResponse, GetApplicationInvitationResponses, GetApplicationResponse, GetApplicationResponses, GetApplicationStatisticsData, GetApplicationStatisticsResponse, GetApplicationStatisticsResponses, GetApplicationStorageObjectData, GetApplicationStorageObjectResponse, GetApplicationStorageObjectResponses, GetApplicationStorageProviderData, GetApplicationStorageProviderResponse, GetApplicationStorageProviderResponses, GetAuditExportData, GetAuditExportResponse, GetAuditExportResponses, GetAuditLogData, GetAuditLogResponse, GetAuditLogResponses, GetBillingProviderData, GetBillingProviderResponse, GetBillingProviderResponses, GetBillingReconciliationRunData, GetBillingReconciliationRunResponse, GetBillingReconciliationRunResponses, GetBillingStatisticsData, GetBillingStatisticsResponse, GetBillingStatisticsResponses, GetCheckoutSessionData, GetCheckoutSessionResponse, GetCheckoutSessionResponses, GetClientData, GetClientResponse, GetClientResponses, GetControlApplicationStorageObjectData, GetControlApplicationStorageObjectResponse, GetControlApplicationStorageObjectResponses, GetControlAuthMethodsData, GetControlAuthMethodsResponse, GetControlAuthMethodsResponses, GetControlAuthPolicyData, GetControlAuthPolicyResponse, GetControlAuthPolicyResponses, GetControlEffectiveAccessData, GetControlEffectiveAccessResponse, GetControlEffectiveAccessResponses, GetControlPermissionGrantData, GetControlPermissionGrantResponse, GetControlPermissionGrantResponses, GetControlUserAccountData, GetControlUserAccountResponse, GetControlUserAccountResponses, GetCurrentUserData, GetCurrentUserResponse, GetCurrentUserResponses, GetDelegationData, GetDelegationResponse, GetDelegationResponses, GetDisputeData, GetDisputeResponse, GetDisputeResponses, GetEffectiveAccessData, GetEffectiveAccessError, GetEffectiveAccessErrors, GetEffectiveAccessResponse, GetEffectiveAccessResponses, GetEntitlementData, GetEntitlementResponse, GetEntitlementResponses, GetEventData, GetEventResponse, GetEventResponses, GetEventTypeData, GetEventTypeResponse, GetEventTypeResponses, GetInstallationBillingProviderData, GetInstallationBillingProviderResponse, GetInstallationBillingProviderResponses, GetInstallationNotificationProviderData, GetInstallationNotificationProviderError, GetInstallationNotificationProviderErrors, GetInstallationNotificationProviderResponse, GetInstallationNotificationProviderResponses, GetInstallationNotificationTemplateData, GetInstallationNotificationTemplateResponse, GetInstallationNotificationTemplateResponses, GetInstallationStorageObjectData, GetInstallationStorageObjectResponse, GetInstallationStorageObjectResponses, GetInstallationStorageProviderData, GetInstallationStorageProviderResponse, GetInstallationStorageProviderResponses, GetInvoiceData, GetInvoiceResponse, GetInvoiceResponses, GetLocalEntitlementRequestData, GetLocalEntitlementRequestResponse, GetLocalEntitlementRequestResponses, GetManagementApiStatusData, GetManagementApiStatusResponse, GetManagementApiStatusResponses, GetMyBillingProfileData, GetMyBillingProfileResponse, GetMyBillingProfileResponses, GetMyBillingSummaryData, GetMyBillingSummaryResponse, GetMyBillingSummaryResponses, GetMyLocalEntitlementRequestData, GetMyLocalEntitlementRequestResponse, GetMyLocalEntitlementRequestResponses, GetMyStorageObjectData, GetMyStorageObjectResponse, GetMyStorageObjectResponses, GetMyWorkspaceData, GetMyWorkspaceResponse, GetMyWorkspaceResponses, GetNotificationData, GetNotificationProviderData, GetNotificationProviderResponse, GetNotificationProviderResponses, GetNotificationResponse, GetNotificationResponses, GetNotificationStatisticsData, GetNotificationStatisticsResponse, GetNotificationStatisticsResponses, GetNotificationTemplateData, GetNotificationTemplateResponse, GetNotificationTemplateResponses, GetOrganizationBillingProviderData, GetOrganizationBillingProviderResponse, GetOrganizationBillingProviderResponses, GetOrganizationData, GetOrganizationNotificationProviderData, GetOrganizationNotificationProviderResponse, GetOrganizationNotificationProviderResponses, GetOrganizationPolicyData, GetOrganizationPolicyResponse, GetOrganizationPolicyResponses, GetOrganizationResponse, GetOrganizationResponses, GetOrganizationStorageObjectData, GetOrganizationStorageObjectResponse, GetOrganizationStorageObjectResponses, GetOrganizationStorageProviderData, GetOrganizationStorageProviderResponse, GetOrganizationStorageProviderResponses, GetPaymentData, GetPaymentResponse, GetPaymentResponses, GetPermissionGrantData, GetPermissionGrantResponse, GetPermissionGrantResponses, GetProductData, GetProductResponse, GetProductResponses, GetRefundData, GetRefundResponse, GetRefundResponses, GetRoleData, GetRoleError, GetRoleErrors, GetRoleResponse, GetRoleResponses, GetSubscriptionData, GetSubscriptionResponse, GetSubscriptionResponses, GetUserData, GetUserResponse, GetUserResponses, GetWebhookData, GetWebhookDeliveryData, GetWebhookDeliveryError, GetWebhookDeliveryErrors, GetWebhookDeliveryResponse, GetWebhookDeliveryResponses, GetWebhookError, GetWebhookErrors, GetWebhookResponse, GetWebhookResponses, GetWorkspaceBillingProfileData, GetWorkspaceBillingProfileResponse, GetWorkspaceBillingProfileResponses, GetWorkspaceData, GetWorkspacePermissionGrantData, GetWorkspacePermissionGrantResponse, GetWorkspacePermissionGrantResponses, GetWorkspaceResponse, GetWorkspaceResponses, GetWorkspaceStorageObjectData, GetWorkspaceStorageObjectResponse, GetWorkspaceStorageObjectResponses, GoogleAuthCallbackData, HealthData, HealthResponse, HealthResponses, HealthStatus, IdempotencyKey, IfMatch, IncludeRetired, InternalApplicationConfig, IntrospectOidcTokenData, IntrospectOidcTokenResponse, IntrospectOidcTokenResponses, InvitationExchangeResult, InvitationExchangeResultWritable, InvitationResent, Invoice, InvoicePage, Jwks, LeaveWorkspaceData, LeaveWorkspaceResponse, LeaveWorkspaceResponses, LinkControlExternalIdentityData, LinkControlExternalIdentityResponse, LinkControlExternalIdentityResponses, ListApplicationAuthProvidersData, ListApplicationAuthProvidersResponse, ListApplicationAuthProvidersResponses, ListApplicationDomainsData, ListApplicationDomainsResponse, ListApplicationDomainsResponses, ListApplicationInvitationsControlData, ListApplicationInvitationsControlResponse, ListApplicationInvitationsControlResponses, ListApplicationInvitationsData, ListApplicationInvitationsResponse, ListApplicationInvitationsResponses, ListApplicationsData, ListApplicationsResponse, ListApplicationsResponses, ListApplicationStorageObjectsData, ListApplicationStorageObjectsResponse, ListApplicationStorageObjectsResponses, ListApplicationStorageProvidersData, ListApplicationStorageProvidersResponse, ListApplicationStorageProvidersResponses, ListAuditLogsData, ListAuditLogsResponse, ListAuditLogsResponses, ListAuthProvidersData, ListAuthProvidersResponse, ListAuthProvidersResponses, ListBillingProviderEventsData, ListBillingProviderEventsResponse, ListBillingProviderEventsResponses, ListBillingProvidersData, ListBillingProvidersResponse, ListBillingProvidersResponses, ListBillingReconciliationRunsData, ListBillingReconciliationRunsResponse, ListBillingReconciliationRunsResponses, ListClientsData, ListClientsResponse, ListClientsResponses, ListControlApplicationStorageObjectsData, ListControlApplicationStorageObjectsResponse, ListControlApplicationStorageObjectsResponses, ListControlPermissionGrantsData, ListControlPermissionGrantsResponse, ListControlPermissionGrantsResponses, ListControlUserSessionsData, ListControlUserSessionsResponse, ListControlUserSessionsResponses, ListDelegationsData, ListDelegationsResponse, ListDelegationsResponses, ListDisputesData, ListDisputesResponse, ListDisputesResponses, ListEntitlementsData, ListEntitlementsResponse, ListEntitlementsResponses, ListEventsData, ListEventsResponse, ListEventsResponses, ListEventTypesData, ListEventTypesResponse, ListEventTypesResponses, ListFeaturesData, ListFeaturesResponse, ListFeaturesResponses, ListInstallationAuthProvidersData, ListInstallationAuthProvidersResponse, ListInstallationAuthProvidersResponses, ListInstallationBillingProvidersData, ListInstallationBillingProvidersResponse, ListInstallationBillingProvidersResponses, ListInstallationControlUserInvitationsData, ListInstallationControlUserInvitationsResponse, ListInstallationControlUserInvitationsResponses, ListInstallationControlUsersData, ListInstallationControlUsersResponse, ListInstallationControlUsersResponses, ListInstallationNotificationProvidersData, ListInstallationNotificationProvidersResponse, ListInstallationNotificationProvidersResponses, ListInstallationNotificationTemplatesData, ListInstallationNotificationTemplatesResponse, ListInstallationNotificationTemplatesResponses, ListInstallationNotificationTemplateVariablesData, ListInstallationNotificationTemplateVariablesResponse, ListInstallationNotificationTemplateVariablesResponses, ListInstallationStorageObjectsData, ListInstallationStorageObjectsResponse, ListInstallationStorageObjectsResponses, ListInstallationStorageProvidersData, ListInstallationStorageProvidersResponse, ListInstallationStorageProvidersResponses, ListInvoicesData, ListInvoicesResponse, ListInvoicesResponses, ListLocalEntitlementRequestsData, ListLocalEntitlementRequestsResponse, ListLocalEntitlementRequestsResponses, ListManagementClientsData, ListManagementClientsResponse, ListManagementClientsResponses, ListMyAddressesData, ListMyAddressesResponse, ListMyAddressesResponses, ListMyEntitlementsData, ListMyEntitlementsResponse, ListMyEntitlementsResponses, ListMyIdentitiesData, ListMyIdentitiesResponse, ListMyIdentitiesResponses, ListMyInvoicesData, ListMyInvoicesResponse, ListMyInvoicesResponses, ListMyLocalEntitlementRequestsData, ListMyLocalEntitlementRequestsResponse, ListMyLocalEntitlementRequestsResponses, ListMyMfaMethodsData, ListMyMfaMethodsResponse, ListMyMfaMethodsResponses, ListMyNotificationPreferencesData, ListMyNotificationPreferencesResponse, ListMyNotificationPreferencesResponses, ListMyOAuthConsentsData, ListMyOAuthConsentsResponse, ListMyOAuthConsentsResponses, ListMyPaymentsData, ListMyPaymentsResponse, ListMyPaymentsResponses, ListMyPendingInvitationsData, ListMyPendingInvitationsResponse, ListMyPendingInvitationsResponses, ListMySessionsData, ListMySessionsResponse, ListMySessionsResponses, ListMyStorageObjectsData, ListMyStorageObjectsResponse, ListMyStorageObjectsResponses, ListMySubscriptionsData, ListMySubscriptionsResponse, ListMySubscriptionsResponses, ListMyWorkspaceAccessData, ListMyWorkspaceAccessResponse, ListMyWorkspaceAccessResponses, ListMyWorkspaceInvitationsData, ListMyWorkspaceInvitationsResponse, ListMyWorkspaceInvitationsResponses, ListMyWorkspaceMembersData, ListMyWorkspaceMembersResponse, ListMyWorkspaceMembersResponses, ListMyWorkspacesData, ListMyWorkspacesResponse, ListMyWorkspacesResponses, ListNotificationProvidersData, ListNotificationProvidersResponse, ListNotificationProvidersResponses, ListNotificationsData, ListNotificationsResponse, ListNotificationsResponses, ListNotificationTemplatesData, ListNotificationTemplatesResponse, ListNotificationTemplatesResponses, ListNotificationTemplateVariablesData, ListNotificationTemplateVariablesResponse, ListNotificationTemplateVariablesResponses, ListOAuthConsentsData, ListOAuthConsentsResponse, ListOAuthConsentsResponses, ListOrganizationAuditLogsData, ListOrganizationAuditLogsResponse, ListOrganizationAuditLogsResponses, ListOrganizationAuthProvidersData, ListOrganizationAuthProvidersResponse, ListOrganizationAuthProvidersResponses, ListOrganizationBillingProvidersData, ListOrganizationBillingProvidersResponse, ListOrganizationBillingProvidersResponses, ListOrganizationInvitationsData, ListOrganizationInvitationsResponse, ListOrganizationInvitationsResponses, ListOrganizationMembersData, ListOrganizationMembersResponse, ListOrganizationMembersResponses, ListOrganizationNotificationProvidersData, ListOrganizationNotificationProvidersResponse, ListOrganizationNotificationProvidersResponses, ListOrganizationsData, ListOrganizationsResponse, ListOrganizationsResponses, ListOrganizationStorageObjectsData, ListOrganizationStorageObjectsResponse, ListOrganizationStorageObjectsResponses, ListOrganizationStorageProvidersData, ListOrganizationStorageProvidersResponse, ListOrganizationStorageProvidersResponses, ListPaymentsData, ListPaymentsResponse, ListPaymentsResponses, ListPermissionGrantsData, ListPermissionGrantsError, ListPermissionGrantsErrors, ListPermissionGrantsResponse, ListPermissionGrantsResponses, ListPersonalApiKeysData, ListPersonalApiKeysError, ListPersonalApiKeysErrors, ListPersonalApiKeysResponse, ListPersonalApiKeysResponses, ListPricesData, ListPricesResponse, ListPricesResponses, ListProductsData, ListProductsResponse, ListProductsResponses, ListRefundsData, ListRefundsResponse, ListRefundsResponses, ListRoleAssignmentsData, ListRoleAssignmentsResponse, ListRoleAssignmentsResponses, ListRolesData, ListRolesResponse, ListRolesResponses, ListSenderIdentitiesData, ListSenderIdentitiesResponse, ListSenderIdentitiesResponses, ListSigningKeysData, ListSigningKeysResponse, ListSigningKeysResponses, ListSubscriptionsData, ListSubscriptionsResponse, ListSubscriptionsResponses, ListUserAddressesData, ListUserAddressesResponse, ListUserAddressesResponses, ListUsersData, ListUserSessionsData, ListUserSessionsResponse, ListUserSessionsResponses, ListUsersResponse, ListUsersResponses, ListWebhookDeliveriesData, ListWebhookDeliveriesResponse, ListWebhookDeliveriesResponses, ListWebhooksData, ListWebhooksResponse, ListWebhooksResponses, ListWorkspaceAddressesData, ListWorkspaceAddressesResponse, ListWorkspaceAddressesResponses, ListWorkspaceMembersData, ListWorkspaceMembersResponse, ListWorkspaceMembersResponses, ListWorkspacePermissionGrantsData, ListWorkspacePermissionGrantsError, ListWorkspacePermissionGrantsErrors, ListWorkspacePermissionGrantsResponse, ListWorkspacePermissionGrantsResponses, ListWorkspacesData, ListWorkspacesResponse, ListWorkspacesResponses, ListWorkspaceStorageObjectsData, ListWorkspaceStorageObjectsResponse, ListWorkspaceStorageObjectsResponses, LocalCheckout, Locale, LocalEntitlementApproval, LocalEntitlementCheckoutData, LocalEntitlementCheckoutResponse, LocalEntitlementCheckoutResponses, LocalEntitlementRequest, LocalEntitlementRequestPage, LoginControlUserWithPasswordData, LoginControlUserWithPasswordError, LoginControlUserWithPasswordErrors, LoginControlUserWithPasswordResponse, LoginControlUserWithPasswordResponses, LogoutAllControlUserSessionsData, LogoutAllControlUserSessionsResponse, LogoutAllControlUserSessionsResponses, LogoutAllData, LogoutAllResponse, LogoutAllResponses, LogoutControlUserData, LogoutControlUserResponse, LogoutControlUserResponses, LogoutCurrentSessionData, LogoutCurrentSessionResponse, LogoutCurrentSessionResponses, ManagementApiStatus, ManagementClient, ManagementClientPage, ManagementCreateApplicationData, ManagementCreateApplicationError, ManagementCreateApplicationErrors, ManagementCreateApplicationResponse, ManagementCreateApplicationResponses, ManagementCreateOrganizationData, ManagementCreateOrganizationResponse, ManagementCreateOrganizationResponses, ManagementGetOrganizationData, ManagementGetOrganizationPolicyData, ManagementGetOrganizationPolicyResponse, ManagementGetOrganizationPolicyResponses, ManagementGetOrganizationResponse, ManagementGetOrganizationResponses, ManagementListApplicationsData, ManagementListApplicationsResponse, ManagementListApplicationsResponses, ManagementListOrganizationsData, ManagementListOrganizationsResponse, ManagementListOrganizationsResponses, ManagementRestoreApplicationData, ManagementRestoreApplicationResponse, ManagementRestoreApplicationResponses, ManagementRestoreOrganizationData, ManagementRestoreOrganizationResponse, ManagementRestoreOrganizationResponses, ManagementRetireApplicationData, ManagementRetireApplicationResponse, ManagementRetireApplicationResponses, ManagementRetireOrganizationData, ManagementRetireOrganizationResponse, ManagementRetireOrganizationResponses, ManagementUpdateApplicationData, ManagementUpdateApplicationResponse, ManagementUpdateApplicationResponses, ManagementUpdateOrganizationData, ManagementUpdateOrganizationPolicyData, ManagementUpdateOrganizationPolicyResponse, ManagementUpdateOrganizationPolicyResponses, ManagementUpdateOrganizationResponse, ManagementUpdateOrganizationResponses, MembershipRole, MfaActivation, MfaActivationWritable, MfaEnrollment, MfaEnrollmentWritable, MfaMethod, MfaMethodPage, Named, Notification, NotificationPage, NotificationPreference, NotificationPreferencePage, NotificationProvider, NotificationProviderPage, NotificationQueued, NotificationStatistics, NotificationTemplate, NotificationTemplatePage, NotificationTemplatePreview, OAuthAuthorizationDecision, OAuthClient, OAuthClientId, OAuthClientPage, OAuthClientPageWritable, OAuthClientWritable, OAuthCodeChallenge, OAuthCodeChallengeMethod, OAuthConsent, OAuthConsentPage, OAuthRedirectUri, OAuthResponseType, OAuthScope, OAuthState, OAuthToken, OAuthTokenCredential, ObjectId, OidcDiscovery, OidcDiscoveryData, OidcDiscoveryResponse, OidcDiscoveryResponses, OidcJwksData, OidcJwksResponse, OidcJwksResponses, OidcUserinfoData, OidcUserinfoError, OidcUserinfoErrors, OidcUserinfoResponse, OidcUserinfoResponses, OptionalPermissionSubjectId, OptionalPermissionSubjectType, Organization, OrganizationEnabledSettings, OrganizationId, OrganizationMember, OrganizationMemberPage, OrganizationPage, OrganizationPolicy, OwnershipTransfer, OwnershipTransfer2, OwnershipTransferResult, PasswordChange, PasswordChangeData, PasswordChangeResponse, PasswordChangeResponses, PasswordResetStart, PasswordResetStartData, PasswordResetStartResponse, PasswordResetStartResponses, PasswordResetVerify, PasswordResetVerifyData, PasswordResetVerifyResponse, PasswordResetVerifyResponses, PasswordResetVerifyWritable, PasswordSignIn, PasswordSignInData, PasswordSignInError, PasswordSignInErrors, PasswordSignInResponse, PasswordSignInResponses, PasswordSignInWritable, PasswordSignUp, PasswordSignUpData, PasswordSignUpError, PasswordSignUpErrors, PasswordSignUpResponse, PasswordSignUpResponses, PasswordSignUpWritable, Payment, PaymentId, PaymentPage, PermissionCheck, PermissionCheckResult, PermissionGrant, PermissionGrantBody, PermissionGrantPage, PermissionGrantStatus, PermissionKey, PermissionSubjectId, PermissionSubjectType, PersonalApiKey, PersonalApiKeyCreated, PersonalApiKeyCreatedWritable, PersonalApiKeyPage, PortalSession, PreviewInstallationNotificationTemplateData, PreviewInstallationNotificationTemplateResponse, PreviewInstallationNotificationTemplateResponses, PreviewNotificationTemplate, PreviewNotificationTemplateData, PreviewNotificationTemplateResponse, PreviewNotificationTemplateResponses, Price, PricePage, Problem, Product, ProductPage, ProviderId, ProviderInheritance, PublicApplicationConfig, PublicCatalogData, PublicCatalogResponse, PublicCatalogResponses, PublicConfigData, PublicConfigResponse, PublicConfigResponses, PublishCustomEvent, PublishCustomEventData, PublishCustomEventError, PublishCustomEventErrors, PublishCustomEventResponse, PublishCustomEventResponses, PublishInstallationNotificationTemplateData, PublishInstallationNotificationTemplateResponse, PublishInstallationNotificationTemplateResponses, PublishNotificationTemplateData, PublishNotificationTemplateResponse, PublishNotificationTemplateResponses, QueuedNotification, QueueNotification, ReadinessData, ReadinessError, ReadinessErrors, ReadinessResponse, ReadinessResponses, ReconciliationAccepted, ReconciliationRun, ReconciliationRunPage, RecoverWorkspaceOwnershipData, RecoverWorkspaceOwnershipResponse, RecoverWorkspaceOwnershipResponses, RecoveryCodes, RecoveryCodesWritable, RedeemApplicationInvitationData, RedeemApplicationInvitationError, RedeemApplicationInvitationErrors, RedeemApplicationInvitationResponse, RedeemApplicationInvitationResponses, RedeemInvitation, RefreshControlUserSessionData, RefreshControlUserSessionResponse, RefreshControlUserSessionResponses, RefreshData, RefreshResponse, RefreshResponses, RefreshToken, Refund, RefundPage, RegenerateRecoveryCodesData, RegenerateRecoveryCodesResponse, RegenerateRecoveryCodesResponses, RejectLocalEntitlementRequestData, RejectLocalEntitlementRequestResponse, RejectLocalEntitlementRequestResponses, RemoveMyWorkspaceMemberData, RemoveMyWorkspaceMemberResponse, RemoveMyWorkspaceMemberResponses, Rename, ReopenLocalEntitlementRequestData, ReopenLocalEntitlementRequestResponse, ReopenLocalEntitlementRequestResponses, ReplaceMyWorkspaceMemberRolesData, ReplaceMyWorkspaceMemberRolesResponse, ReplaceMyWorkspaceMemberRolesResponses, ReplaceWorkspaceMemberRoles, ReplaceWorkspaceMemberRolesData, ReplaceWorkspaceMemberRolesResponse, ReplaceWorkspaceMemberRolesResponses, ReplayBillingProviderEventData, ReplayBillingProviderEventResponse, ReplayBillingProviderEventResponses, ReplayWebhookDeliveryData, ReplayWebhookDeliveryResponse, ReplayWebhookDeliveryResponses, RequestId, RequiredIdempotencyKey, ResendApplicationInvitationControlData, ResendApplicationInvitationControlError, ResendApplicationInvitationControlErrors, ResendApplicationInvitationControlResponse, ResendApplicationInvitationControlResponses, ResendApplicationInvitationData, ResendApplicationInvitationError, ResendApplicationInvitationErrors, ResendApplicationInvitationResponse, ResendApplicationInvitationResponses, ResendInstallationControlUserInvitationData, ResendInstallationControlUserInvitationResponse, ResendInstallationControlUserInvitationResponses, ResendMyWorkspaceInvitationData, ResendMyWorkspaceInvitationError, ResendMyWorkspaceInvitationErrors, ResendMyWorkspaceInvitationResponse, ResendMyWorkspaceInvitationResponses, ResendOrganizationInvitationData, ResendOrganizationInvitationResponse, ResendOrganizationInvitationResponses, RestoreApplicationData, RestoreApplicationResponse, RestoreApplicationResponses, RestoreEntitlementData, RestoreEntitlementResponse, RestoreEntitlementResponses, RestoreOrganizationData, RestoreOrganizationResponse, RestoreOrganizationResponses, RestoreUserData, RestoreUserResponse, RestoreUserResponses, ResumeSubscriptionData, ResumeSubscriptionResponse, ResumeSubscriptionResponses, RetireApplicationData, RetireApplicationResponse, RetireApplicationResponses, RetireOrganizationData, RetireOrganizationResponse, RetireOrganizationResponses, RetryNotificationData, RetryNotificationResponse, RetryNotificationResponses, RevokeApplicationInvitationControlData, RevokeApplicationInvitationControlResponse, RevokeApplicationInvitationControlResponses, RevokeApplicationInvitationData, RevokeApplicationInvitationResponse, RevokeApplicationInvitationResponses, RevokeControlPermissionGrantData, RevokeControlPermissionGrantError, RevokeControlPermissionGrantErrors, RevokeControlPermissionGrantResponse, RevokeControlPermissionGrantResponses, RevokeControlUserSessionData, RevokeControlUserSessionResponse, RevokeControlUserSessionResponses, RevokeDelegationData, RevokeDelegationResponse, RevokeDelegationResponses, RevokedSessionCount, RevokeEntitlementData, RevokeEntitlementResponse, RevokeEntitlementResponses, RevokeInstallationControlUserInvitationData, RevokeInstallationControlUserInvitationResponse, RevokeInstallationControlUserInvitationResponses, RevokeMyOAuthConsentData, RevokeMyOAuthConsentResponse, RevokeMyOAuthConsentResponses, RevokeMySessionData, RevokeMySessionResponse, RevokeMySessionResponses, RevokeMyWorkspaceInvitationData, RevokeMyWorkspaceInvitationResponse, RevokeMyWorkspaceInvitationResponses, RevokeOAuthConsentData, RevokeOAuthConsentResponse, RevokeOAuthConsentResponses, RevokeOidcTokenData, RevokeOidcTokenResponse, RevokeOidcTokenResponses, RevokeOrganizationInvitationData, RevokeOrganizationInvitationResponse, RevokeOrganizationInvitationResponses, RevokePermissionGrantData, RevokePermissionGrantError, RevokePermissionGrantErrors, RevokePermissionGrantResponse, RevokePermissionGrantResponses, RevokePersonalApiKeyData, RevokePersonalApiKeyResponse, RevokePersonalApiKeyResponses, RevokeUserSessionsData, RevokeUserSessionsResponse, RevokeUserSessionsResponses, RevokeWorkspacePermissionGrantData, RevokeWorkspacePermissionGrantError, RevokeWorkspacePermissionGrantErrors, RevokeWorkspacePermissionGrantResponse, RevokeWorkspacePermissionGrantResponses, Role, RoleAssignment, RoleAssignment2, RoleAssignmentPage, RoleAssignmentRecord, RoleKey, RolePage, RotateClientSecretData, RotateClientSecretResponse, RotateClientSecretResponses, RotateManagementClientSecretData, RotateManagementClientSecretResponse, RotateManagementClientSecretResponses, RotateSigningKeyData, RotateSigningKeyResponse, RotateSigningKeyResponses, RotateWebhookSecretData, RotateWebhookSecretResponse, RotateWebhookSecretResponses, RuntimeAuthConfig, RuntimeConfig, RuntimeStorageConfig, SecretCredential, SecretCredentialWritable, SenderIdentity, SenderIdentityPage, SendMachineNotificationData, SendMachineNotificationError, SendMachineNotificationErrors, SendMachineNotificationResponse, SendMachineNotificationResponses, ServiceGetApplicationUserData, ServiceGetApplicationUserError, ServiceGetApplicationUserErrors, ServiceGetApplicationUserResponse, ServiceGetApplicationUserResponses, ServiceGetApplicationWorkspaceData, ServiceGetApplicationWorkspaceError, ServiceGetApplicationWorkspaceErrors, ServiceGetApplicationWorkspaceResponse, ServiceGetApplicationWorkspaceResponses, ServiceGetSubjectBillingData, ServiceGetSubjectBillingError, ServiceGetSubjectBillingErrors, ServiceGetSubjectBillingResponse, ServiceGetSubjectBillingResponses, ServiceGetSubjectEntitlementsData, ServiceGetSubjectEntitlementsError, ServiceGetSubjectEntitlementsErrors, ServiceGetSubjectEntitlementsResponse, ServiceGetSubjectEntitlementsResponses, ServiceListApplicationUsersData, ServiceListApplicationUsersError, ServiceListApplicationUsersErrors, ServiceListApplicationUsersResponse, ServiceListApplicationUsersResponses, ServiceListApplicationWorkspaceAccessData, ServiceListApplicationWorkspaceAccessError, ServiceListApplicationWorkspaceAccessErrors, ServiceListApplicationWorkspaceAccessResponse, ServiceListApplicationWorkspaceAccessResponses, ServiceListApplicationWorkspacesData, ServiceListApplicationWorkspacesError, ServiceListApplicationWorkspacesErrors, ServiceListApplicationWorkspacesResponse, ServiceListApplicationWorkspacesResponses, Session, SessionId, SessionPage, SetDefaultSenderIdentityData, SetDefaultSenderIdentityResponse, SetDefaultSenderIdentityResponses, SetupCompletion, SetupCompletionWritable, SetupSession, SetupSessionWritable, SetupStatus, SetupStatusData, SetupStatusResponse, SetupStatusResponses, SigningKey, SigningKeyPage, SmtpProvider, StartAppleAuthData, StartAppleAuthResponse, StartAppleAuthResponses, StartAppleLinkData, StartAppleLinkResponse, StartAppleLinkResponses, StartControlExternalLoginData, StartControlExternalLoginResponse, StartControlExternalLoginResponses, StartControlInvitationExternalLoginData, StartControlInvitationExternalLoginResponse, StartControlInvitationExternalLoginResponses, StartControlUserEmailLoginData, StartControlUserEmailLoginResponse, StartControlUserEmailLoginResponses, StartGoogleAuthData, StartGoogleAuthResponse, StartGoogleAuthResponses, StartGoogleLinkData, StartGoogleLinkResponse, StartGoogleLinkResponses, StartTotp, StartTotpEnrollmentData, StartTotpEnrollmentResponse, StartTotpEnrollmentResponses, StorageDownload, StorageObject, StorageObjectPage, StorageProvider, StorageProviderBody, StorageProviderPage, StorageProviderStatus, StorageUpload, StorageUploadAuthorization, StorageUploadAuthorizationWritable, StripeWebhookData, StripeWebhookError, StripeWebhookErrors, StripeWebhookResponse, StripeWebhookResponses, StructuredRoles, Subscription, SubscriptionId, SubscriptionPage, SuspendUserData, SuspendUserResponse, SuspendUserResponses, TemplateVariables, TestInstallationNotificationProviderData, TestInstallationNotificationProviderError, TestInstallationNotificationProviderErrors, TestInstallationNotificationProviderResponse, TestInstallationNotificationProviderResponses, TestNotificationProvider, TestNotificationProviderData, TestNotificationProviderResponse, TestNotificationProviderResponses, TestOrganizationNotificationProviderData, TestOrganizationNotificationProviderResponse, TestOrganizationNotificationProviderResponses, TestWebhookData, TestWebhookError, TestWebhookErrors, TestWebhookResponse, TestWebhookResponses, TokenIntrospection, TokenResponse, TokenResponseWritable, TransferMyWorkspaceOwnershipData, TransferMyWorkspaceOwnershipResponse, TransferMyWorkspaceOwnershipResponses, UnlinkControlExternalIdentityData, UnlinkControlExternalIdentityError, UnlinkControlExternalIdentityErrors, UnlinkControlExternalIdentityResponse, UnlinkControlExternalIdentityResponses, UnlinkMyIdentityData, UnlinkMyIdentityResponse, UnlinkMyIdentityResponses, UnverifyUserEmailData, UnverifyUserEmailResponse, UnverifyUserEmailResponses, UnverifyUserOrganizationData, UnverifyUserOrganizationResponse, UnverifyUserOrganizationResponses, UpdateAddress, UpdateApplicationData, UpdateApplicationError, UpdateApplicationErrors, UpdateApplicationResponse, UpdateApplicationResponses, UpdateApplicationStorageProviderData, UpdateApplicationStorageProviderResponse, UpdateApplicationStorageProviderResponses, UpdateAuthConfigData, UpdateAuthConfigResponse, UpdateAuthConfigResponses, UpdateBillingProfile, UpdateBillingProvider, UpdateBillingProviderData, UpdateBillingProviderResponse, UpdateBillingProviderResponses, UpdateBillingProviderWritable, UpdateClient, UpdateClientData, UpdateClientResponse, UpdateClientResponses, UpdateControlAuthPolicy, UpdateControlAuthPolicyData, UpdateControlAuthPolicyError, UpdateControlAuthPolicyErrors, UpdateControlAuthPolicyResponse, UpdateControlAuthPolicyResponses, UpdateControlInvitationMethod, UpdateControlUserAccount, UpdateControlUserAccountData, UpdateControlUserAccountResponse, UpdateControlUserAccountResponses, UpdateCurrentUserData, UpdateCurrentUserResponse, UpdateCurrentUserResponses, UpdateEventType, UpdateEventTypeData, UpdateEventTypeError, UpdateEventTypeErrors, UpdateEventTypeResponse, UpdateEventTypeResponses, UpdateInstallationAuthProvider, UpdateInstallationAuthProviderData, UpdateInstallationAuthProviderError, UpdateInstallationAuthProviderErrors, UpdateInstallationAuthProviderResponse, UpdateInstallationAuthProviderResponses, UpdateInstallationBillingProviderData, UpdateInstallationBillingProviderResponse, UpdateInstallationBillingProviderResponses, UpdateInstallationControlUserData, UpdateInstallationControlUserResponse, UpdateInstallationControlUserResponses, UpdateInstallationNotificationProviderData, UpdateInstallationNotificationProviderError, UpdateInstallationNotificationProviderErrors, UpdateInstallationNotificationProviderResponse, UpdateInstallationNotificationProviderResponses, UpdateInstallationNotificationTemplateData, UpdateInstallationNotificationTemplateResponse, UpdateInstallationNotificationTemplateResponses, UpdateInstallationStorageProviderData, UpdateInstallationStorageProviderResponse, UpdateInstallationStorageProviderResponses, UpdateInternalApplicationConfigData, UpdateInternalApplicationConfigError, UpdateInternalApplicationConfigErrors, UpdateInternalApplicationConfigResponse, UpdateInternalApplicationConfigResponses, UpdateManagementApi, UpdateManagementApiStatusData, UpdateManagementApiStatusResponse, UpdateManagementApiStatusResponses, UpdateMyAddressData, UpdateMyAddressResponse, UpdateMyAddressResponses, UpdateMyBillingProfileData, UpdateMyBillingProfileResponse, UpdateMyBillingProfileResponses, UpdateMyNotificationPreferenceData, UpdateMyNotificationPreferenceResponse, UpdateMyNotificationPreferenceResponses, UpdateMyWorkspaceData, UpdateMyWorkspaceResponse, UpdateMyWorkspaceResponses, UpdateNotificationPreference, UpdateNotificationProviderData, UpdateNotificationProviderResponse, UpdateNotificationProviderResponses, UpdateNotificationTemplate, UpdateNotificationTemplateData, UpdateNotificationTemplateResponse, UpdateNotificationTemplateResponses, UpdateOrganizationAuthProviderData, UpdateOrganizationAuthProviderError, UpdateOrganizationAuthProviderErrors, UpdateOrganizationAuthProviderResponse, UpdateOrganizationAuthProviderResponses, UpdateOrganizationBillingProviderData, UpdateOrganizationBillingProviderResponse, UpdateOrganizationBillingProviderResponses, UpdateOrganizationData, UpdateOrganizationError, UpdateOrganizationErrors, UpdateOrganizationMemberData, UpdateOrganizationMemberResponse, UpdateOrganizationMemberResponses, UpdateOrganizationNotificationProviderData, UpdateOrganizationNotificationProviderResponse, UpdateOrganizationNotificationProviderResponses, UpdateOrganizationPolicy, UpdateOrganizationPolicyData, UpdateOrganizationPolicyError, UpdateOrganizationPolicyErrors, UpdateOrganizationPolicyResponse, UpdateOrganizationPolicyResponses, UpdateOrganizationResponse, UpdateOrganizationResponses, UpdateOrganizationStorageProviderData, UpdateOrganizationStorageProviderResponse, UpdateOrganizationStorageProviderResponses, UpdateProduct, UpdateProductData, UpdateProductResponse, UpdateProductResponses, UpdatePublicApplicationConfigData, UpdatePublicApplicationConfigError, UpdatePublicApplicationConfigErrors, UpdatePublicApplicationConfigResponse, UpdatePublicApplicationConfigResponses, UpdateRole, UpdateRoleData, UpdateRoleError, UpdateRoleErrors, UpdateRoleResponse, UpdateRoleResponses, UpdateSmtpProvider, UpdateSmtpProviderWritable, UpdateStorageProvider, UpdateStorageProviderWritable, UpdateUser, UpdateUserData, UpdateUserProfile, UpdateUserResponse, UpdateUserResponses, UpdateWebhook, UpdateWebhookData, UpdateWebhookError, UpdateWebhookErrors, UpdateWebhookResponse, UpdateWebhookResponses, UpdateWorkspace, UpdateWorkspaceAddressData, UpdateWorkspaceAddressResponse, UpdateWorkspaceAddressResponses, UpdateWorkspaceBillingProfileData, UpdateWorkspaceBillingProfileResponse, UpdateWorkspaceBillingProfileResponses, UpdateWorkspaceData, UpdateWorkspaceResponse, UpdateWorkspaceResponses, User, UserInfo, UserPage, Uuid, VerifyApplicationDomainData, VerifyApplicationDomainResponse, VerifyApplicationDomainResponses, VerifyApplicationStorageProviderData, VerifyApplicationStorageProviderResponse, VerifyApplicationStorageProviderResponses, VerifyBillingProviderData, VerifyBillingProviderResponse, VerifyBillingProviderResponses, VerifyControlUserEmailLoginData, VerifyControlUserEmailLoginResponse, VerifyControlUserEmailLoginResponses, VerifyInstallationBillingProviderData, VerifyInstallationBillingProviderResponse, VerifyInstallationBillingProviderResponses, VerifyInstallationNotificationProviderData, VerifyInstallationNotificationProviderError, VerifyInstallationNotificationProviderErrors, VerifyInstallationNotificationProviderResponse, VerifyInstallationNotificationProviderResponses, VerifyInstallationStorageProviderData, VerifyInstallationStorageProviderError, VerifyInstallationStorageProviderErrors, VerifyInstallationStorageProviderResponse, VerifyInstallationStorageProviderResponses, VerifyMfa, VerifyMfaData, VerifyMfaError, VerifyMfaErrors, VerifyMfaResponse, VerifyMfaResponses, VerifyMfaWritable, VerifyNotificationProviderData, VerifyNotificationProviderError, VerifyNotificationProviderErrors, VerifyNotificationProviderResponse, VerifyNotificationProviderResponses, VerifyOrganizationBillingProviderData, VerifyOrganizationBillingProviderResponse, VerifyOrganizationBillingProviderResponses, VerifyOrganizationNotificationProviderData, VerifyOrganizationNotificationProviderResponse, VerifyOrganizationNotificationProviderResponses, VerifyOrganizationStorageProviderData, VerifyOrganizationStorageProviderResponse, VerifyOrganizationStorageProviderResponses, VerifyUserEmailData, VerifyUserEmailResponse, VerifyUserEmailResponses, VerifyUserOrganizationData, VerifyUserOrganizationResponse, VerifyUserOrganizationResponses, VersionData, VersionInfo, VersionResponse, VersionResponses, WebAuthnChallenge, Webhook, WebhookAcknowledgement, WebhookDelivery, WebhookDeliveryPage, WebhookPage, WebhookPageWritable, WebhookTestAccepted, WebhookWritable, Workspace, WorkspaceAccessEntry, WorkspaceAccessPage, WorkspaceId, WorkspaceIdQuery, WorkspaceMember, WorkspaceMemberPage, WorkspacePage } from './types.gen.js'; diff --git a/sdk/typescript/sdk/src/generated/sdk.gen.ts b/sdk/typescript/sdk/src/generated/sdk.gen.ts index 737adb2..28325c2 100644 --- a/sdk/typescript/sdk/src/generated/sdk.gen.ts +++ b/sdk/typescript/sdk/src/generated/sdk.gen.ts @@ -2,7 +2,7 @@ import { client } from './client.gen.js'; import { type Client, type ClientMeta, type Options as Options2, type RequestResult, type TDataShape, urlSearchParamsBodySerializer } from './client/index.js'; -import type { AcceptMyWorkspaceInvitationData, AcceptMyWorkspaceInvitationResponses, AcceptOrganizationInvitationData, AcceptOrganizationInvitationErrors, AcceptOrganizationInvitationResponses, ActivateMyAddressData, ActivateMyAddressResponses, ActivateTotpEnrollmentData, ActivateTotpEnrollmentResponses, ActivateWorkspaceAddressData, ActivateWorkspaceAddressResponses, AnonymizeMyAccountData, AnonymizeMyAccountResponses, AppleAuthCallbackData, ApproveLocalEntitlementRequestData, ApproveLocalEntitlementRequestResponses, ArchiveEventTypeData, ArchiveEventTypeResponses, ArchiveInstallationNotificationTemplateData, ArchiveInstallationNotificationTemplateResponses, ArchiveMyWorkspaceData, ArchiveMyWorkspaceResponses, ArchiveNotificationTemplateData, ArchiveNotificationTemplateResponses, AuthMethodsData, AuthMethodsResponses, BeginOidcAuthorizationData, BeginOidcAuthorizationResponses, BeginWebAuthnAuthenticationData, BeginWebAuthnAuthenticationResponses, BeginWebAuthnRegistrationData, BeginWebAuthnRegistrationResponses, BootstrapData, BootstrapErrors, BootstrapResponses, CancelMyLocalEntitlementRequestData, CancelMyLocalEntitlementRequestResponses, CancelSubscriptionData, CancelSubscriptionResponses, ChangeOperatorPasswordData, ChangeOperatorPasswordErrors, ChangeOperatorPasswordResponses, ChangeSubscriptionPriceData, ChangeSubscriptionPriceResponses, CheckMyPermissionsData, CheckMyPermissionsResponses, CompleteApplicationStorageUploadData, CompleteApplicationStorageUploadResponses, CompleteControlApplicationStorageUploadData, CompleteControlApplicationStorageUploadResponses, CompleteInstallationStorageUploadData, CompleteInstallationStorageUploadResponses, CompleteMyStorageUploadData, CompleteMyStorageUploadResponses, CompleteSetupData, CompleteSetupErrors, CompleteSetupResponses, CompleteWorkspaceStorageUploadData, CompleteWorkspaceStorageUploadResponses, ConfigureAppleProviderData, ConfigureAppleProviderResponses, ConfigureGoogleProviderData, ConfigureGoogleProviderResponses, ConfigureInstallationAuthProviderData, ConfigureInstallationAuthProviderResponses, ConfigureOrganizationAuthProviderData, ConfigureOrganizationAuthProviderResponses, CreateApplicationData, CreateApplicationDomainData, CreateApplicationDomainResponses, CreateApplicationResponses, CreateApplicationStorageProviderData, CreateApplicationStorageProviderResponses, CreateApplicationStorageUploadData, CreateApplicationStorageUploadResponses, CreateAuditExportData, CreateAuditExportResponses, CreateBillingPortalSessionData, CreateBillingPortalSessionResponses, CreateBillingProviderData, CreateBillingProviderResponses, CreateBillingReconciliationRunData, CreateBillingReconciliationRunResponses, CreateCheckoutSessionData, CreateCheckoutSessionResponses, CreateClientData, CreateClientResponses, CreateControlApplicationStorageUploadData, CreateControlApplicationStorageUploadResponses, CreateDelegationData, CreateDelegationResponses, CreateEntitlementData, CreateEntitlementResponses, CreateEventTypeData, CreateEventTypeErrors, CreateEventTypeResponses, CreateFeatureData, CreateFeatureErrors, CreateFeatureResponses, CreateInstallationBillingProviderData, CreateInstallationBillingProviderResponses, CreateInstallationNotificationProviderData, CreateInstallationNotificationProviderResponses, CreateInstallationNotificationTemplateData, CreateInstallationNotificationTemplateResponses, CreateInstallationOperatorData, CreateInstallationOperatorResponses, CreateInstallationStorageProviderData, CreateInstallationStorageProviderResponses, CreateInstallationStorageUploadData, CreateInstallationStorageUploadResponses, CreateManagementClientData, CreateManagementClientErrors, CreateManagementClientResponses, CreateMyAddressData, CreateMyAddressResponses, CreateMyStorageUploadData, CreateMyStorageUploadResponses, CreateMyWorkspaceData, CreateMyWorkspaceInvitationData, CreateMyWorkspaceInvitationResponses, CreateMyWorkspaceResponses, CreateNotificationProviderData, CreateNotificationProviderResponses, CreateNotificationTemplateData, CreateNotificationTemplateResponses, CreateOrganizationBillingProviderData, CreateOrganizationBillingProviderResponses, CreateOrganizationData, CreateOrganizationErrors, CreateOrganizationInvitationData, CreateOrganizationInvitationResponses, CreateOrganizationNotificationProviderData, CreateOrganizationNotificationProviderResponses, CreateOrganizationResponses, CreateOrganizationStorageProviderData, CreateOrganizationStorageProviderResponses, CreatePersonalApiKeyData, CreatePersonalApiKeyResponses, CreatePriceData, CreatePriceResponses, CreateProductData, CreateProductResponses, CreateRefundData, CreateRefundResponses, CreateRoleAssignmentData, CreateRoleAssignmentResponses, CreateRoleData, CreateRoleResponses, CreateSenderIdentityData, CreateSenderIdentityResponses, CreateSetupNotificationProviderData, CreateSetupNotificationProviderResponses, CreateUserData, CreateUserResponses, CreateWebhookData, CreateWebhookResponses, CreateWorkspaceAddressData, CreateWorkspaceAddressResponses, CreateWorkspaceData, CreateWorkspaceInvitationData, CreateWorkspaceInvitationResponses, CreateWorkspaceResponses, CreateWorkspaceStorageUploadData, CreateWorkspaceStorageUploadResponses, DecideOidcAuthorizationData, DecideOidcAuthorizationResponses, DeleteApplicationDomainData, DeleteApplicationDomainResponses, DeleteApplicationStorageObjectData, DeleteApplicationStorageObjectResponses, DeleteControlApplicationStorageObjectData, DeleteControlApplicationStorageObjectResponses, DeleteInstallationOperatorData, DeleteInstallationOperatorResponses, DeleteInstallationStorageObjectData, DeleteInstallationStorageObjectResponses, DeleteMyAccountData, DeleteMyAccountResponses, DeleteMyAddressData, DeleteMyAddressResponses, DeleteMyStorageObjectData, DeleteMyStorageObjectResponses, DeleteOrganizationMemberData, DeleteOrganizationMemberResponses, DeleteOrganizationStorageObjectData, DeleteOrganizationStorageObjectResponses, DeleteRoleAssignmentData, DeleteRoleAssignmentResponses, DeleteRoleData, DeleteRoleErrors, DeleteRoleResponses, DeleteWorkspaceAddressData, DeleteWorkspaceAddressResponses, DeleteWorkspaceData, DeleteWorkspaceErrors, DeleteWorkspaceMemberData, DeleteWorkspaceMemberResponses, DeleteWorkspaceResponses, DeleteWorkspaceStorageObjectData, DeleteWorkspaceStorageObjectResponses, DisableApplicationAuthProviderData, DisableApplicationAuthProviderResponses, DisableApplicationStorageProviderData, DisableApplicationStorageProviderErrors, DisableApplicationStorageProviderResponses, DisableBillingProviderData, DisableBillingProviderErrors, DisableBillingProviderResponses, DisableClientData, DisableClientResponses, DisableInstallationAuthProviderData, DisableInstallationAuthProviderResponses, DisableInstallationBillingProviderData, DisableInstallationBillingProviderResponses, DisableInstallationNotificationProviderData, DisableInstallationNotificationProviderErrors, DisableInstallationNotificationProviderResponses, DisableInstallationStorageProviderData, DisableInstallationStorageProviderErrors, DisableInstallationStorageProviderResponses, DisableManagementClientData, DisableManagementClientResponses, DisableMfaMethodData, DisableMfaMethodResponses, DisableNotificationProviderData, DisableNotificationProviderResponses, DisableOrganizationAuthProviderData, DisableOrganizationAuthProviderResponses, DisableOrganizationBillingProviderData, DisableOrganizationBillingProviderResponses, DisableOrganizationNotificationProviderData, DisableOrganizationNotificationProviderResponses, DisableOrganizationStorageProviderData, DisableOrganizationStorageProviderErrors, DisableOrganizationStorageProviderResponses, DisableWebhookData, DisableWebhookResponses, DownloadApplicationStorageObjectData, DownloadApplicationStorageObjectResponses, DownloadControlApplicationStorageObjectData, DownloadControlApplicationStorageObjectResponses, DownloadInstallationStorageObjectData, DownloadInstallationStorageObjectResponses, DownloadMyStorageObjectData, DownloadMyStorageObjectResponses, DownloadOrganizationStorageObjectData, DownloadOrganizationStorageObjectResponses, DownloadWorkspaceStorageObjectData, DownloadWorkspaceStorageObjectResponses, EmailChangeStartData, EmailChangeStartResponses, EmailChangeVerifyData, EmailChangeVerifyResponses, EmailStartData, EmailStartResponses, EmailVerificationStartData, EmailVerificationStartResponses, EmailVerificationVerifyData, EmailVerificationVerifyResponses, EmailVerifyData, EmailVerifyResponses, EnableApplicationStorageProviderData, EnableApplicationStorageProviderResponses, EnableInstallationStorageProviderData, EnableInstallationStorageProviderResponses, EnableOrganizationStorageProviderData, EnableOrganizationStorageProviderResponses, ExchangeAppleAuthData, ExchangeAppleAuthResponses, ExchangeDelegationData, ExchangeDelegationResponses, ExchangeGoogleAuthData, ExchangeGoogleAuthResponses, ExchangeOidcTokenData, ExchangeOidcTokenErrors, ExchangeOidcTokenResponses, ExportMyAccountData, ExportMyAccountResponses, FinishWebAuthnAuthenticationData, FinishWebAuthnAuthenticationErrors, FinishWebAuthnAuthenticationResponses, FinishWebAuthnRegistrationData, FinishWebAuthnRegistrationResponses, GetApplicationData, GetApplicationResponses, GetApplicationStatisticsData, GetApplicationStatisticsResponses, GetApplicationStorageObjectData, GetApplicationStorageObjectResponses, GetApplicationStorageProviderData, GetApplicationStorageProviderResponses, GetAuditExportData, GetAuditExportResponses, GetAuditLogData, GetAuditLogResponses, GetBillingProviderData, GetBillingProviderResponses, GetBillingReconciliationRunData, GetBillingReconciliationRunResponses, GetBillingStatisticsData, GetBillingStatisticsResponses, GetCheckoutSessionData, GetCheckoutSessionResponses, GetControlApplicationStorageObjectData, GetControlApplicationStorageObjectResponses, GetCurrentUserData, GetCurrentUserResponses, GetDelegationData, GetDelegationResponses, GetDisputeData, GetDisputeResponses, GetEntitlementData, GetEntitlementResponses, GetEventData, GetEventResponses, GetEventTypeData, GetEventTypeResponses, GetInstallationBillingProviderData, GetInstallationBillingProviderResponses, GetInstallationNotificationProviderData, GetInstallationNotificationProviderErrors, GetInstallationNotificationProviderResponses, GetInstallationNotificationTemplateData, GetInstallationNotificationTemplateResponses, GetInstallationStorageObjectData, GetInstallationStorageObjectResponses, GetInstallationStorageProviderData, GetInstallationStorageProviderResponses, GetInvoiceData, GetInvoiceResponses, GetLocalEntitlementRequestData, GetLocalEntitlementRequestResponses, GetManagementApiStatusData, GetManagementApiStatusResponses, GetMyBillingProfileData, GetMyBillingProfileResponses, GetMyBillingSummaryData, GetMyBillingSummaryResponses, GetMyLocalEntitlementRequestData, GetMyLocalEntitlementRequestResponses, GetMyStorageObjectData, GetMyStorageObjectResponses, GetMyWorkspaceData, GetMyWorkspaceResponses, GetNotificationData, GetNotificationProviderData, GetNotificationProviderResponses, GetNotificationResponses, GetNotificationStatisticsData, GetNotificationStatisticsResponses, GetNotificationTemplateData, GetNotificationTemplateResponses, GetOperatorAccountData, GetOperatorAccountResponses, GetOrganizationBillingProviderData, GetOrganizationBillingProviderResponses, GetOrganizationData, GetOrganizationNotificationProviderData, GetOrganizationNotificationProviderResponses, GetOrganizationPolicyData, GetOrganizationPolicyResponses, GetOrganizationResponses, GetOrganizationStorageObjectData, GetOrganizationStorageObjectResponses, GetOrganizationStorageProviderData, GetOrganizationStorageProviderResponses, GetPaymentData, GetPaymentResponses, GetProductData, GetProductResponses, GetRefundData, GetRefundResponses, GetRoleData, GetRoleErrors, GetRoleResponses, GetSubscriptionData, GetSubscriptionResponses, GetUserData, GetUserResponses, GetWebhookData, GetWebhookDeliveryData, GetWebhookDeliveryErrors, GetWebhookDeliveryResponses, GetWebhookErrors, GetWebhookResponses, GetWorkspaceBillingProfileData, GetWorkspaceBillingProfileResponses, GetWorkspaceData, GetWorkspaceResponses, GetWorkspaceStorageObjectData, GetWorkspaceStorageObjectResponses, GoogleAuthCallbackData, HealthData, HealthResponses, IntrospectOidcTokenData, IntrospectOidcTokenResponses, LeaveWorkspaceData, LeaveWorkspaceResponses, ListApplicationAuthProvidersData, ListApplicationAuthProvidersResponses, ListApplicationDomainsData, ListApplicationDomainsResponses, ListApplicationsData, ListApplicationsResponses, ListApplicationStorageObjectsData, ListApplicationStorageObjectsResponses, ListApplicationStorageProvidersData, ListApplicationStorageProvidersResponses, ListAuditLogsData, ListAuditLogsResponses, ListAuthProvidersData, ListAuthProvidersResponses, ListBillingProviderEventsData, ListBillingProviderEventsResponses, ListBillingProvidersData, ListBillingProvidersResponses, ListBillingReconciliationRunsData, ListBillingReconciliationRunsResponses, ListClientsData, ListClientsResponses, ListControlApplicationStorageObjectsData, ListControlApplicationStorageObjectsResponses, ListDelegationsData, ListDelegationsResponses, ListDisputesData, ListDisputesResponses, ListEntitlementsData, ListEntitlementsResponses, ListEventsData, ListEventsResponses, ListEventTypesData, ListEventTypesResponses, ListFeaturesData, ListFeaturesResponses, ListInstallationAuthProvidersData, ListInstallationAuthProvidersResponses, ListInstallationBillingProvidersData, ListInstallationBillingProvidersResponses, ListInstallationNotificationProvidersData, ListInstallationNotificationProvidersResponses, ListInstallationNotificationTemplatesData, ListInstallationNotificationTemplatesResponses, ListInstallationNotificationTemplateVariablesData, ListInstallationNotificationTemplateVariablesResponses, ListInstallationOperatorsData, ListInstallationOperatorsResponses, ListInstallationStorageObjectsData, ListInstallationStorageObjectsResponses, ListInstallationStorageProvidersData, ListInstallationStorageProvidersResponses, ListInvoicesData, ListInvoicesResponses, ListLocalEntitlementRequestsData, ListLocalEntitlementRequestsResponses, ListManagementClientsData, ListManagementClientsResponses, ListMyAddressesData, ListMyAddressesResponses, ListMyEntitlementsData, ListMyEntitlementsResponses, ListMyIdentitiesData, ListMyIdentitiesResponses, ListMyInvoicesData, ListMyInvoicesResponses, ListMyLocalEntitlementRequestsData, ListMyLocalEntitlementRequestsResponses, ListMyMfaMethodsData, ListMyMfaMethodsResponses, ListMyNotificationPreferencesData, ListMyNotificationPreferencesResponses, ListMyOAuthConsentsData, ListMyOAuthConsentsResponses, ListMyPaymentsData, ListMyPaymentsResponses, ListMySessionsData, ListMySessionsResponses, ListMyStorageObjectsData, ListMyStorageObjectsResponses, ListMySubscriptionsData, ListMySubscriptionsResponses, ListMyWorkspaceInvitationsData, ListMyWorkspaceInvitationsResponses, ListMyWorkspaceMembersData, ListMyWorkspaceMembersResponses, ListMyWorkspacesData, ListMyWorkspacesResponses, ListNotificationProvidersData, ListNotificationProvidersResponses, ListNotificationsData, ListNotificationsResponses, ListNotificationTemplatesData, ListNotificationTemplatesResponses, ListNotificationTemplateVariablesData, ListNotificationTemplateVariablesResponses, ListOAuthConsentsData, ListOAuthConsentsResponses, ListOperatorSessionsData, ListOperatorSessionsResponses, ListOrganizationAuditLogsData, ListOrganizationAuditLogsResponses, ListOrganizationAuthProvidersData, ListOrganizationAuthProvidersResponses, ListOrganizationBillingProvidersData, ListOrganizationBillingProvidersResponses, ListOrganizationInvitationsData, ListOrganizationInvitationsResponses, ListOrganizationMembersData, ListOrganizationMembersResponses, ListOrganizationNotificationProvidersData, ListOrganizationNotificationProvidersResponses, ListOrganizationsData, ListOrganizationsResponses, ListOrganizationStorageObjectsData, ListOrganizationStorageObjectsResponses, ListOrganizationStorageProvidersData, ListOrganizationStorageProvidersResponses, ListPaymentsData, ListPaymentsResponses, ListPersonalApiKeysData, ListPersonalApiKeysErrors, ListPersonalApiKeysResponses, ListPricesData, ListPricesResponses, ListProductsData, ListProductsResponses, ListRefundsData, ListRefundsResponses, ListRoleAssignmentsData, ListRoleAssignmentsResponses, ListRolesData, ListRolesResponses, ListSenderIdentitiesData, ListSenderIdentitiesResponses, ListSigningKeysData, ListSigningKeysResponses, ListSubscriptionsData, ListSubscriptionsResponses, ListUserAddressesData, ListUserAddressesResponses, ListUsersData, ListUserSessionsData, ListUserSessionsResponses, ListUsersResponses, ListWebhookDeliveriesData, ListWebhookDeliveriesResponses, ListWebhooksData, ListWebhooksResponses, ListWorkspaceAddressesData, ListWorkspaceAddressesResponses, ListWorkspaceInvitationsData, ListWorkspaceInvitationsResponses, ListWorkspaceMembersData, ListWorkspaceMembersResponses, ListWorkspacesData, ListWorkspacesResponses, ListWorkspaceStorageObjectsData, ListWorkspaceStorageObjectsResponses, LocalEntitlementCheckoutData, LocalEntitlementCheckoutResponses, LoginOperatorWithPasswordData, LoginOperatorWithPasswordErrors, LoginOperatorWithPasswordResponses, LogoutAllData, LogoutAllOperatorSessionsData, LogoutAllOperatorSessionsResponses, LogoutAllResponses, LogoutCurrentSessionData, LogoutCurrentSessionResponses, LogoutOperatorData, LogoutOperatorResponses, ManagementCreateApplicationData, ManagementCreateApplicationErrors, ManagementCreateApplicationResponses, ManagementCreateOrganizationData, ManagementCreateOrganizationResponses, ManagementGetOrganizationData, ManagementGetOrganizationPolicyData, ManagementGetOrganizationPolicyResponses, ManagementGetOrganizationResponses, ManagementListApplicationsData, ManagementListApplicationsResponses, ManagementListOrganizationsData, ManagementListOrganizationsResponses, ManagementRestoreApplicationData, ManagementRestoreApplicationResponses, ManagementRestoreOrganizationData, ManagementRestoreOrganizationResponses, ManagementRetireApplicationData, ManagementRetireApplicationResponses, ManagementRetireOrganizationData, ManagementRetireOrganizationResponses, ManagementUpdateApplicationData, ManagementUpdateApplicationResponses, ManagementUpdateOrganizationData, ManagementUpdateOrganizationPolicyData, ManagementUpdateOrganizationPolicyResponses, ManagementUpdateOrganizationResponses, OidcDiscoveryData, OidcDiscoveryResponses, OidcJwksData, OidcJwksResponses, OidcUserinfoData, OidcUserinfoErrors, OidcUserinfoResponses, PasswordChangeData, PasswordChangeResponses, PasswordResetStartData, PasswordResetStartResponses, PasswordResetVerifyData, PasswordResetVerifyResponses, PasswordSignInData, PasswordSignInErrors, PasswordSignInResponses, PasswordSignUpData, PasswordSignUpErrors, PasswordSignUpResponses, PreviewInstallationNotificationTemplateData, PreviewInstallationNotificationTemplateResponses, PreviewNotificationTemplateData, PreviewNotificationTemplateResponses, PublicCatalogData, PublicCatalogResponses, PublicConfigData, PublicConfigResponses, PublishCustomEventData, PublishCustomEventErrors, PublishCustomEventResponses, PublishInstallationNotificationTemplateData, PublishInstallationNotificationTemplateResponses, PublishNotificationTemplateData, PublishNotificationTemplateResponses, QueueNotificationData, QueueNotificationResponses, ReadinessData, ReadinessErrors, ReadinessResponses, RecoverWorkspaceOwnershipData, RecoverWorkspaceOwnershipResponses, RefreshData, RefreshOperatorSessionData, RefreshOperatorSessionResponses, RefreshResponses, RegenerateRecoveryCodesData, RegenerateRecoveryCodesResponses, RejectLocalEntitlementRequestData, RejectLocalEntitlementRequestResponses, RemoveMyWorkspaceMemberData, RemoveMyWorkspaceMemberResponses, ReopenLocalEntitlementRequestData, ReopenLocalEntitlementRequestResponses, ReplaceMyWorkspaceMemberRolesData, ReplaceMyWorkspaceMemberRolesResponses, ReplaceWorkspaceMemberRolesData, ReplaceWorkspaceMemberRolesResponses, ReplayBillingProviderEventData, ReplayBillingProviderEventResponses, ReplayWebhookDeliveryData, ReplayWebhookDeliveryResponses, ResendOrganizationInvitationData, ResendOrganizationInvitationResponses, RestoreApplicationData, RestoreApplicationResponses, RestoreEntitlementData, RestoreEntitlementResponses, RestoreOrganizationData, RestoreOrganizationResponses, RestoreUserData, RestoreUserResponses, ResumeSubscriptionData, ResumeSubscriptionResponses, RetireApplicationData, RetireApplicationResponses, RetireOrganizationData, RetireOrganizationResponses, RetryNotificationData, RetryNotificationResponses, RevokeDelegationData, RevokeDelegationResponses, RevokeEntitlementData, RevokeEntitlementResponses, RevokeMyOAuthConsentData, RevokeMyOAuthConsentResponses, RevokeMySessionData, RevokeMySessionResponses, RevokeOAuthConsentData, RevokeOAuthConsentResponses, RevokeOidcTokenData, RevokeOidcTokenResponses, RevokeOperatorSessionData, RevokeOperatorSessionResponses, RevokeOrganizationInvitationData, RevokeOrganizationInvitationResponses, RevokePersonalApiKeyData, RevokePersonalApiKeyResponses, RevokeUserSessionsData, RevokeUserSessionsResponses, RevokeWorkspaceInvitationData, RevokeWorkspaceInvitationResponses, RotateClientSecretData, RotateClientSecretResponses, RotateManagementClientSecretData, RotateManagementClientSecretResponses, RotateSigningKeyData, RotateSigningKeyResponses, RotateWebhookSecretData, RotateWebhookSecretResponses, SetDefaultSenderIdentityData, SetDefaultSenderIdentityResponses, SetupStatusData, SetupStatusResponses, StartAppleAuthData, StartAppleAuthResponses, StartAppleLinkData, StartAppleLinkResponses, StartGoogleAuthData, StartGoogleAuthResponses, StartGoogleLinkData, StartGoogleLinkResponses, StartOperatorEmailLoginData, StartOperatorEmailLoginResponses, StartTotpEnrollmentData, StartTotpEnrollmentResponses, StripeWebhookData, StripeWebhookErrors, StripeWebhookResponses, SuspendUserData, SuspendUserResponses, TestInstallationNotificationProviderData, TestInstallationNotificationProviderErrors, TestInstallationNotificationProviderResponses, TestNotificationProviderData, TestNotificationProviderResponses, TestOrganizationNotificationProviderData, TestOrganizationNotificationProviderResponses, TestWebhookData, TestWebhookErrors, TestWebhookResponses, TransferMyWorkspaceOwnershipData, TransferMyWorkspaceOwnershipResponses, UnlinkMyIdentityData, UnlinkMyIdentityResponses, UnverifyUserEmailData, UnverifyUserEmailResponses, UnverifyUserOrganizationData, UnverifyUserOrganizationResponses, UpdateApplicationData, UpdateApplicationErrors, UpdateApplicationResponses, UpdateApplicationStorageProviderData, UpdateApplicationStorageProviderResponses, UpdateAuthConfigData, UpdateAuthConfigResponses, UpdateBillingProviderData, UpdateBillingProviderResponses, UpdateClientData, UpdateClientResponses, UpdateCurrentUserData, UpdateCurrentUserResponses, UpdateEventTypeData, UpdateEventTypeErrors, UpdateEventTypeResponses, UpdateInstallationAuthProviderData, UpdateInstallationAuthProviderErrors, UpdateInstallationAuthProviderResponses, UpdateInstallationBillingProviderData, UpdateInstallationBillingProviderResponses, UpdateInstallationNotificationProviderData, UpdateInstallationNotificationProviderErrors, UpdateInstallationNotificationProviderResponses, UpdateInstallationNotificationTemplateData, UpdateInstallationNotificationTemplateResponses, UpdateInstallationOperatorData, UpdateInstallationOperatorResponses, UpdateInstallationStorageProviderData, UpdateInstallationStorageProviderResponses, UpdateInternalApplicationConfigData, UpdateInternalApplicationConfigErrors, UpdateInternalApplicationConfigResponses, UpdateManagementApiStatusData, UpdateManagementApiStatusResponses, UpdateMyAddressData, UpdateMyAddressResponses, UpdateMyBillingProfileData, UpdateMyBillingProfileResponses, UpdateMyNotificationPreferenceData, UpdateMyNotificationPreferenceResponses, UpdateMyWorkspaceData, UpdateMyWorkspaceResponses, UpdateNotificationProviderData, UpdateNotificationProviderResponses, UpdateNotificationTemplateData, UpdateNotificationTemplateResponses, UpdateOperatorAccountData, UpdateOperatorAccountResponses, UpdateOrganizationAuthProviderData, UpdateOrganizationAuthProviderErrors, UpdateOrganizationAuthProviderResponses, UpdateOrganizationBillingProviderData, UpdateOrganizationBillingProviderResponses, UpdateOrganizationData, UpdateOrganizationErrors, UpdateOrganizationMemberData, UpdateOrganizationMemberResponses, UpdateOrganizationNotificationProviderData, UpdateOrganizationNotificationProviderResponses, UpdateOrganizationPolicyData, UpdateOrganizationPolicyErrors, UpdateOrganizationPolicyResponses, UpdateOrganizationResponses, UpdateOrganizationStorageProviderData, UpdateOrganizationStorageProviderResponses, UpdateProductData, UpdateProductResponses, UpdatePublicApplicationConfigData, UpdatePublicApplicationConfigErrors, UpdatePublicApplicationConfigResponses, UpdateRoleData, UpdateRoleErrors, UpdateRoleResponses, UpdateUserData, UpdateUserResponses, UpdateWebhookData, UpdateWebhookErrors, UpdateWebhookResponses, UpdateWorkspaceAddressData, UpdateWorkspaceAddressResponses, UpdateWorkspaceBillingProfileData, UpdateWorkspaceBillingProfileResponses, UpdateWorkspaceData, UpdateWorkspaceResponses, VerifyApplicationDomainData, VerifyApplicationDomainResponses, VerifyApplicationStorageProviderData, VerifyApplicationStorageProviderResponses, VerifyBillingProviderData, VerifyBillingProviderResponses, VerifyInstallationBillingProviderData, VerifyInstallationBillingProviderResponses, VerifyInstallationNotificationProviderData, VerifyInstallationNotificationProviderErrors, VerifyInstallationNotificationProviderResponses, VerifyInstallationStorageProviderData, VerifyInstallationStorageProviderErrors, VerifyInstallationStorageProviderResponses, VerifyMfaData, VerifyMfaErrors, VerifyMfaResponses, VerifyNotificationProviderData, VerifyNotificationProviderErrors, VerifyNotificationProviderResponses, VerifyOperatorEmailLoginData, VerifyOperatorEmailLoginResponses, VerifyOrganizationBillingProviderData, VerifyOrganizationBillingProviderResponses, VerifyOrganizationNotificationProviderData, VerifyOrganizationNotificationProviderResponses, VerifyOrganizationStorageProviderData, VerifyOrganizationStorageProviderResponses, VerifyUserEmailData, VerifyUserEmailResponses, VerifyUserOrganizationData, VerifyUserOrganizationResponses, VersionData, VersionResponses } from './types.gen.js'; +import type { AcceptControlUserInvitationData, AcceptControlUserInvitationErrors, AcceptControlUserInvitationResponses, ActivateMyAddressData, ActivateMyAddressResponses, ActivateTotpEnrollmentData, ActivateTotpEnrollmentResponses, ActivateWorkspaceAddressData, ActivateWorkspaceAddressResponses, AdjustEntitlementData, AdjustEntitlementResponses, AnonymizeMyAccountData, AnonymizeMyAccountResponses, AppleAuthCallbackData, ApproveLocalEntitlementRequestData, ApproveLocalEntitlementRequestResponses, ArchiveEventTypeData, ArchiveEventTypeResponses, ArchiveInstallationNotificationTemplateData, ArchiveInstallationNotificationTemplateResponses, ArchiveMyWorkspaceData, ArchiveMyWorkspaceResponses, ArchiveNotificationTemplateData, ArchiveNotificationTemplateResponses, AuthMethodsData, AuthMethodsResponses, BeginOidcAuthorizationData, BeginOidcAuthorizationResponses, BeginWebAuthnAuthenticationData, BeginWebAuthnAuthenticationResponses, BeginWebAuthnRegistrationData, BeginWebAuthnRegistrationResponses, BootstrapData, BootstrapErrors, BootstrapResponses, CancelMyLocalEntitlementRequestData, CancelMyLocalEntitlementRequestResponses, CancelSubscriptionData, CancelSubscriptionResponses, ChangeControlUserPasswordData, ChangeControlUserPasswordErrors, ChangeControlUserPasswordResponses, ChangeSubscriptionPriceData, ChangeSubscriptionPriceResponses, CheckMyPermissionsData, CheckMyPermissionsResponses, CompleteApplicationStorageUploadData, CompleteApplicationStorageUploadResponses, CompleteControlApplicationStorageUploadData, CompleteControlApplicationStorageUploadResponses, CompleteInstallationStorageUploadData, CompleteInstallationStorageUploadResponses, CompleteMyStorageUploadData, CompleteMyStorageUploadResponses, CompleteSetupData, CompleteSetupErrors, CompleteSetupResponses, CompleteWorkspaceStorageUploadData, CompleteWorkspaceStorageUploadResponses, ConfigureAppleProviderData, ConfigureAppleProviderResponses, ConfigureGoogleProviderData, ConfigureGoogleProviderResponses, ConfigureInstallationAuthProviderData, ConfigureInstallationAuthProviderResponses, ConfigureOrganizationAuthProviderData, ConfigureOrganizationAuthProviderResponses, CreateApplicationData, CreateApplicationDomainData, CreateApplicationDomainResponses, CreateApplicationInvitationControlData, CreateApplicationInvitationControlResponses, CreateApplicationInvitationMachineData, CreateApplicationInvitationMachineResponses, CreateApplicationResponses, CreateApplicationStorageProviderData, CreateApplicationStorageProviderResponses, CreateApplicationStorageUploadData, CreateApplicationStorageUploadResponses, CreateAuditExportData, CreateAuditExportResponses, CreateBillingPortalSessionData, CreateBillingPortalSessionResponses, CreateBillingProviderData, CreateBillingProviderResponses, CreateBillingReconciliationRunData, CreateBillingReconciliationRunResponses, CreateCheckoutSessionData, CreateCheckoutSessionResponses, CreateClientData, CreateClientResponses, CreateControlApplicationStorageUploadData, CreateControlApplicationStorageUploadResponses, CreateControlPermissionGrantData, CreateControlPermissionGrantErrors, CreateControlPermissionGrantResponses, CreateDelegationData, CreateDelegationResponses, CreateEntitlementData, CreateEntitlementResponses, CreateEventTypeData, CreateEventTypeErrors, CreateEventTypeResponses, CreateFeatureData, CreateFeatureErrors, CreateFeatureResponses, CreateInstallationBillingProviderData, CreateInstallationBillingProviderResponses, CreateInstallationControlUserInvitationData, CreateInstallationControlUserInvitationResponses, CreateInstallationNotificationProviderData, CreateInstallationNotificationProviderResponses, CreateInstallationNotificationTemplateData, CreateInstallationNotificationTemplateResponses, CreateInstallationStorageProviderData, CreateInstallationStorageProviderResponses, CreateInstallationStorageUploadData, CreateInstallationStorageUploadResponses, CreateManagementClientData, CreateManagementClientErrors, CreateManagementClientResponses, CreateMyAddressData, CreateMyAddressResponses, CreateMyStorageUploadData, CreateMyStorageUploadResponses, CreateMyWorkspaceData, CreateMyWorkspaceInvitationData, CreateMyWorkspaceInvitationResponses, CreateMyWorkspaceResponses, CreateNotificationProviderData, CreateNotificationProviderResponses, CreateNotificationTemplateData, CreateNotificationTemplateResponses, CreateOrganizationBillingProviderData, CreateOrganizationBillingProviderResponses, CreateOrganizationData, CreateOrganizationErrors, CreateOrganizationInvitationData, CreateOrganizationInvitationResponses, CreateOrganizationNotificationProviderData, CreateOrganizationNotificationProviderResponses, CreateOrganizationResponses, CreateOrganizationStorageProviderData, CreateOrganizationStorageProviderResponses, CreatePermissionGrantData, CreatePermissionGrantErrors, CreatePermissionGrantResponses, CreatePersonalApiKeyData, CreatePersonalApiKeyResponses, CreatePriceData, CreatePriceResponses, CreateProductData, CreateProductResponses, CreateRefundData, CreateRefundResponses, CreateRoleAssignmentData, CreateRoleAssignmentResponses, CreateRoleData, CreateRoleErrors, CreateRoleResponses, CreateSenderIdentityData, CreateSenderIdentityResponses, CreateSetupNotificationProviderData, CreateSetupNotificationProviderResponses, CreateUserData, CreateUserResponses, CreateWebhookData, CreateWebhookResponses, CreateWorkspaceAddressData, CreateWorkspaceAddressResponses, CreateWorkspaceData, CreateWorkspacePermissionGrantData, CreateWorkspacePermissionGrantErrors, CreateWorkspacePermissionGrantResponses, CreateWorkspaceResponses, CreateWorkspaceStorageUploadData, CreateWorkspaceStorageUploadResponses, DecideOidcAuthorizationData, DecideOidcAuthorizationResponses, DeleteApplicationDomainData, DeleteApplicationDomainResponses, DeleteApplicationStorageObjectData, DeleteApplicationStorageObjectResponses, DeleteControlApplicationStorageObjectData, DeleteControlApplicationStorageObjectResponses, DeleteInstallationControlUserData, DeleteInstallationControlUserResponses, DeleteInstallationStorageObjectData, DeleteInstallationStorageObjectResponses, DeleteMyAccountData, DeleteMyAccountResponses, DeleteMyAddressData, DeleteMyAddressResponses, DeleteMyStorageObjectData, DeleteMyStorageObjectResponses, DeleteOrganizationMemberData, DeleteOrganizationMemberResponses, DeleteOrganizationStorageObjectData, DeleteOrganizationStorageObjectResponses, DeleteRoleAssignmentData, DeleteRoleAssignmentResponses, DeleteRoleData, DeleteRoleErrors, DeleteRoleResponses, DeleteWorkspaceAddressData, DeleteWorkspaceAddressResponses, DeleteWorkspaceData, DeleteWorkspaceErrors, DeleteWorkspaceMemberData, DeleteWorkspaceMemberResponses, DeleteWorkspaceResponses, DeleteWorkspaceStorageObjectData, DeleteWorkspaceStorageObjectResponses, DisableApplicationAuthProviderData, DisableApplicationAuthProviderResponses, DisableApplicationStorageProviderData, DisableApplicationStorageProviderErrors, DisableApplicationStorageProviderResponses, DisableBillingProviderData, DisableBillingProviderErrors, DisableBillingProviderResponses, DisableClientData, DisableClientResponses, DisableInstallationAuthProviderData, DisableInstallationAuthProviderResponses, DisableInstallationBillingProviderData, DisableInstallationBillingProviderResponses, DisableInstallationNotificationProviderData, DisableInstallationNotificationProviderErrors, DisableInstallationNotificationProviderResponses, DisableInstallationStorageProviderData, DisableInstallationStorageProviderErrors, DisableInstallationStorageProviderResponses, DisableManagementClientData, DisableManagementClientResponses, DisableMfaMethodData, DisableMfaMethodResponses, DisableNotificationProviderData, DisableNotificationProviderResponses, DisableOrganizationAuthProviderData, DisableOrganizationAuthProviderResponses, DisableOrganizationBillingProviderData, DisableOrganizationBillingProviderResponses, DisableOrganizationNotificationProviderData, DisableOrganizationNotificationProviderResponses, DisableOrganizationStorageProviderData, DisableOrganizationStorageProviderErrors, DisableOrganizationStorageProviderResponses, DisableWebhookData, DisableWebhookResponses, DownloadApplicationStorageObjectData, DownloadApplicationStorageObjectResponses, DownloadControlApplicationStorageObjectData, DownloadControlApplicationStorageObjectResponses, DownloadInstallationStorageObjectData, DownloadInstallationStorageObjectResponses, DownloadMyStorageObjectData, DownloadMyStorageObjectResponses, DownloadOrganizationStorageObjectData, DownloadOrganizationStorageObjectResponses, DownloadWorkspaceStorageObjectData, DownloadWorkspaceStorageObjectResponses, EmailChangeStartData, EmailChangeStartResponses, EmailChangeVerifyData, EmailChangeVerifyResponses, EmailStartData, EmailStartResponses, EmailVerificationStartData, EmailVerificationStartResponses, EmailVerificationVerifyData, EmailVerificationVerifyResponses, EmailVerifyData, EmailVerifyResponses, EnableApplicationStorageProviderData, EnableApplicationStorageProviderResponses, EnableInstallationStorageProviderData, EnableInstallationStorageProviderResponses, EnableOrganizationStorageProviderData, EnableOrganizationStorageProviderResponses, ExchangeAppleAuthData, ExchangeAppleAuthResponses, ExchangeApplicationInvitationData, ExchangeApplicationInvitationErrors, ExchangeApplicationInvitationResponses, ExchangeDelegationData, ExchangeDelegationResponses, ExchangeGoogleAuthData, ExchangeGoogleAuthResponses, ExchangeOidcTokenData, ExchangeOidcTokenErrors, ExchangeOidcTokenResponses, ExportMyAccountData, ExportMyAccountResponses, FinishWebAuthnAuthenticationData, FinishWebAuthnAuthenticationErrors, FinishWebAuthnAuthenticationResponses, FinishWebAuthnRegistrationData, FinishWebAuthnRegistrationResponses, GetApplicationData, GetApplicationInvitationControlData, GetApplicationInvitationControlResponses, GetApplicationInvitationData, GetApplicationInvitationResponses, GetApplicationResponses, GetApplicationStatisticsData, GetApplicationStatisticsResponses, GetApplicationStorageObjectData, GetApplicationStorageObjectResponses, GetApplicationStorageProviderData, GetApplicationStorageProviderResponses, GetAuditExportData, GetAuditExportResponses, GetAuditLogData, GetAuditLogResponses, GetBillingProviderData, GetBillingProviderResponses, GetBillingReconciliationRunData, GetBillingReconciliationRunResponses, GetBillingStatisticsData, GetBillingStatisticsResponses, GetCheckoutSessionData, GetCheckoutSessionResponses, GetClientData, GetClientResponses, GetControlApplicationStorageObjectData, GetControlApplicationStorageObjectResponses, GetControlAuthMethodsData, GetControlAuthMethodsResponses, GetControlAuthPolicyData, GetControlAuthPolicyResponses, GetControlEffectiveAccessData, GetControlEffectiveAccessResponses, GetControlPermissionGrantData, GetControlPermissionGrantResponses, GetControlUserAccountData, GetControlUserAccountResponses, GetCurrentUserData, GetCurrentUserResponses, GetDelegationData, GetDelegationResponses, GetDisputeData, GetDisputeResponses, GetEffectiveAccessData, GetEffectiveAccessErrors, GetEffectiveAccessResponses, GetEntitlementData, GetEntitlementResponses, GetEventData, GetEventResponses, GetEventTypeData, GetEventTypeResponses, GetInstallationBillingProviderData, GetInstallationBillingProviderResponses, GetInstallationNotificationProviderData, GetInstallationNotificationProviderErrors, GetInstallationNotificationProviderResponses, GetInstallationNotificationTemplateData, GetInstallationNotificationTemplateResponses, GetInstallationStorageObjectData, GetInstallationStorageObjectResponses, GetInstallationStorageProviderData, GetInstallationStorageProviderResponses, GetInvoiceData, GetInvoiceResponses, GetLocalEntitlementRequestData, GetLocalEntitlementRequestResponses, GetManagementApiStatusData, GetManagementApiStatusResponses, GetMyBillingProfileData, GetMyBillingProfileResponses, GetMyBillingSummaryData, GetMyBillingSummaryResponses, GetMyLocalEntitlementRequestData, GetMyLocalEntitlementRequestResponses, GetMyStorageObjectData, GetMyStorageObjectResponses, GetMyWorkspaceData, GetMyWorkspaceResponses, GetNotificationData, GetNotificationProviderData, GetNotificationProviderResponses, GetNotificationResponses, GetNotificationStatisticsData, GetNotificationStatisticsResponses, GetNotificationTemplateData, GetNotificationTemplateResponses, GetOrganizationBillingProviderData, GetOrganizationBillingProviderResponses, GetOrganizationData, GetOrganizationNotificationProviderData, GetOrganizationNotificationProviderResponses, GetOrganizationPolicyData, GetOrganizationPolicyResponses, GetOrganizationResponses, GetOrganizationStorageObjectData, GetOrganizationStorageObjectResponses, GetOrganizationStorageProviderData, GetOrganizationStorageProviderResponses, GetPaymentData, GetPaymentResponses, GetPermissionGrantData, GetPermissionGrantResponses, GetProductData, GetProductResponses, GetRefundData, GetRefundResponses, GetRoleData, GetRoleErrors, GetRoleResponses, GetSubscriptionData, GetSubscriptionResponses, GetUserData, GetUserResponses, GetWebhookData, GetWebhookDeliveryData, GetWebhookDeliveryErrors, GetWebhookDeliveryResponses, GetWebhookErrors, GetWebhookResponses, GetWorkspaceBillingProfileData, GetWorkspaceBillingProfileResponses, GetWorkspaceData, GetWorkspacePermissionGrantData, GetWorkspacePermissionGrantResponses, GetWorkspaceResponses, GetWorkspaceStorageObjectData, GetWorkspaceStorageObjectResponses, GoogleAuthCallbackData, HealthData, HealthResponses, IntrospectOidcTokenData, IntrospectOidcTokenResponses, LeaveWorkspaceData, LeaveWorkspaceResponses, LinkControlExternalIdentityData, LinkControlExternalIdentityResponses, ListApplicationAuthProvidersData, ListApplicationAuthProvidersResponses, ListApplicationDomainsData, ListApplicationDomainsResponses, ListApplicationInvitationsControlData, ListApplicationInvitationsControlResponses, ListApplicationInvitationsData, ListApplicationInvitationsResponses, ListApplicationsData, ListApplicationsResponses, ListApplicationStorageObjectsData, ListApplicationStorageObjectsResponses, ListApplicationStorageProvidersData, ListApplicationStorageProvidersResponses, ListAuditLogsData, ListAuditLogsResponses, ListAuthProvidersData, ListAuthProvidersResponses, ListBillingProviderEventsData, ListBillingProviderEventsResponses, ListBillingProvidersData, ListBillingProvidersResponses, ListBillingReconciliationRunsData, ListBillingReconciliationRunsResponses, ListClientsData, ListClientsResponses, ListControlApplicationStorageObjectsData, ListControlApplicationStorageObjectsResponses, ListControlPermissionGrantsData, ListControlPermissionGrantsResponses, ListControlUserSessionsData, ListControlUserSessionsResponses, ListDelegationsData, ListDelegationsResponses, ListDisputesData, ListDisputesResponses, ListEntitlementsData, ListEntitlementsResponses, ListEventsData, ListEventsResponses, ListEventTypesData, ListEventTypesResponses, ListFeaturesData, ListFeaturesResponses, ListInstallationAuthProvidersData, ListInstallationAuthProvidersResponses, ListInstallationBillingProvidersData, ListInstallationBillingProvidersResponses, ListInstallationControlUserInvitationsData, ListInstallationControlUserInvitationsResponses, ListInstallationControlUsersData, ListInstallationControlUsersResponses, ListInstallationNotificationProvidersData, ListInstallationNotificationProvidersResponses, ListInstallationNotificationTemplatesData, ListInstallationNotificationTemplatesResponses, ListInstallationNotificationTemplateVariablesData, ListInstallationNotificationTemplateVariablesResponses, ListInstallationStorageObjectsData, ListInstallationStorageObjectsResponses, ListInstallationStorageProvidersData, ListInstallationStorageProvidersResponses, ListInvoicesData, ListInvoicesResponses, ListLocalEntitlementRequestsData, ListLocalEntitlementRequestsResponses, ListManagementClientsData, ListManagementClientsResponses, ListMyAddressesData, ListMyAddressesResponses, ListMyEntitlementsData, ListMyEntitlementsResponses, ListMyIdentitiesData, ListMyIdentitiesResponses, ListMyInvoicesData, ListMyInvoicesResponses, ListMyLocalEntitlementRequestsData, ListMyLocalEntitlementRequestsResponses, ListMyMfaMethodsData, ListMyMfaMethodsResponses, ListMyNotificationPreferencesData, ListMyNotificationPreferencesResponses, ListMyOAuthConsentsData, ListMyOAuthConsentsResponses, ListMyPaymentsData, ListMyPaymentsResponses, ListMyPendingInvitationsData, ListMyPendingInvitationsResponses, ListMySessionsData, ListMySessionsResponses, ListMyStorageObjectsData, ListMyStorageObjectsResponses, ListMySubscriptionsData, ListMySubscriptionsResponses, ListMyWorkspaceAccessData, ListMyWorkspaceAccessResponses, ListMyWorkspaceInvitationsData, ListMyWorkspaceInvitationsResponses, ListMyWorkspaceMembersData, ListMyWorkspaceMembersResponses, ListMyWorkspacesData, ListMyWorkspacesResponses, ListNotificationProvidersData, ListNotificationProvidersResponses, ListNotificationsData, ListNotificationsResponses, ListNotificationTemplatesData, ListNotificationTemplatesResponses, ListNotificationTemplateVariablesData, ListNotificationTemplateVariablesResponses, ListOAuthConsentsData, ListOAuthConsentsResponses, ListOrganizationAuditLogsData, ListOrganizationAuditLogsResponses, ListOrganizationAuthProvidersData, ListOrganizationAuthProvidersResponses, ListOrganizationBillingProvidersData, ListOrganizationBillingProvidersResponses, ListOrganizationInvitationsData, ListOrganizationInvitationsResponses, ListOrganizationMembersData, ListOrganizationMembersResponses, ListOrganizationNotificationProvidersData, ListOrganizationNotificationProvidersResponses, ListOrganizationsData, ListOrganizationsResponses, ListOrganizationStorageObjectsData, ListOrganizationStorageObjectsResponses, ListOrganizationStorageProvidersData, ListOrganizationStorageProvidersResponses, ListPaymentsData, ListPaymentsResponses, ListPermissionGrantsData, ListPermissionGrantsErrors, ListPermissionGrantsResponses, ListPersonalApiKeysData, ListPersonalApiKeysErrors, ListPersonalApiKeysResponses, ListPricesData, ListPricesResponses, ListProductsData, ListProductsResponses, ListRefundsData, ListRefundsResponses, ListRoleAssignmentsData, ListRoleAssignmentsResponses, ListRolesData, ListRolesResponses, ListSenderIdentitiesData, ListSenderIdentitiesResponses, ListSigningKeysData, ListSigningKeysResponses, ListSubscriptionsData, ListSubscriptionsResponses, ListUserAddressesData, ListUserAddressesResponses, ListUsersData, ListUserSessionsData, ListUserSessionsResponses, ListUsersResponses, ListWebhookDeliveriesData, ListWebhookDeliveriesResponses, ListWebhooksData, ListWebhooksResponses, ListWorkspaceAddressesData, ListWorkspaceAddressesResponses, ListWorkspaceMembersData, ListWorkspaceMembersResponses, ListWorkspacePermissionGrantsData, ListWorkspacePermissionGrantsErrors, ListWorkspacePermissionGrantsResponses, ListWorkspacesData, ListWorkspacesResponses, ListWorkspaceStorageObjectsData, ListWorkspaceStorageObjectsResponses, LocalEntitlementCheckoutData, LocalEntitlementCheckoutResponses, LoginControlUserWithPasswordData, LoginControlUserWithPasswordErrors, LoginControlUserWithPasswordResponses, LogoutAllControlUserSessionsData, LogoutAllControlUserSessionsResponses, LogoutAllData, LogoutAllResponses, LogoutControlUserData, LogoutControlUserResponses, LogoutCurrentSessionData, LogoutCurrentSessionResponses, ManagementCreateApplicationData, ManagementCreateApplicationErrors, ManagementCreateApplicationResponses, ManagementCreateOrganizationData, ManagementCreateOrganizationResponses, ManagementGetOrganizationData, ManagementGetOrganizationPolicyData, ManagementGetOrganizationPolicyResponses, ManagementGetOrganizationResponses, ManagementListApplicationsData, ManagementListApplicationsResponses, ManagementListOrganizationsData, ManagementListOrganizationsResponses, ManagementRestoreApplicationData, ManagementRestoreApplicationResponses, ManagementRestoreOrganizationData, ManagementRestoreOrganizationResponses, ManagementRetireApplicationData, ManagementRetireApplicationResponses, ManagementRetireOrganizationData, ManagementRetireOrganizationResponses, ManagementUpdateApplicationData, ManagementUpdateApplicationResponses, ManagementUpdateOrganizationData, ManagementUpdateOrganizationPolicyData, ManagementUpdateOrganizationPolicyResponses, ManagementUpdateOrganizationResponses, OidcDiscoveryData, OidcDiscoveryResponses, OidcJwksData, OidcJwksResponses, OidcUserinfoData, OidcUserinfoErrors, OidcUserinfoResponses, PasswordChangeData, PasswordChangeResponses, PasswordResetStartData, PasswordResetStartResponses, PasswordResetVerifyData, PasswordResetVerifyResponses, PasswordSignInData, PasswordSignInErrors, PasswordSignInResponses, PasswordSignUpData, PasswordSignUpErrors, PasswordSignUpResponses, PreviewInstallationNotificationTemplateData, PreviewInstallationNotificationTemplateResponses, PreviewNotificationTemplateData, PreviewNotificationTemplateResponses, PublicCatalogData, PublicCatalogResponses, PublicConfigData, PublicConfigResponses, PublishCustomEventData, PublishCustomEventErrors, PublishCustomEventResponses, PublishInstallationNotificationTemplateData, PublishInstallationNotificationTemplateResponses, PublishNotificationTemplateData, PublishNotificationTemplateResponses, ReadinessData, ReadinessErrors, ReadinessResponses, RecoverWorkspaceOwnershipData, RecoverWorkspaceOwnershipResponses, RedeemApplicationInvitationData, RedeemApplicationInvitationErrors, RedeemApplicationInvitationResponses, RefreshControlUserSessionData, RefreshControlUserSessionResponses, RefreshData, RefreshResponses, RegenerateRecoveryCodesData, RegenerateRecoveryCodesResponses, RejectLocalEntitlementRequestData, RejectLocalEntitlementRequestResponses, RemoveMyWorkspaceMemberData, RemoveMyWorkspaceMemberResponses, ReopenLocalEntitlementRequestData, ReopenLocalEntitlementRequestResponses, ReplaceMyWorkspaceMemberRolesData, ReplaceMyWorkspaceMemberRolesResponses, ReplaceWorkspaceMemberRolesData, ReplaceWorkspaceMemberRolesResponses, ReplayBillingProviderEventData, ReplayBillingProviderEventResponses, ReplayWebhookDeliveryData, ReplayWebhookDeliveryResponses, ResendApplicationInvitationControlData, ResendApplicationInvitationControlErrors, ResendApplicationInvitationControlResponses, ResendApplicationInvitationData, ResendApplicationInvitationErrors, ResendApplicationInvitationResponses, ResendInstallationControlUserInvitationData, ResendInstallationControlUserInvitationResponses, ResendMyWorkspaceInvitationData, ResendMyWorkspaceInvitationErrors, ResendMyWorkspaceInvitationResponses, ResendOrganizationInvitationData, ResendOrganizationInvitationResponses, RestoreApplicationData, RestoreApplicationResponses, RestoreEntitlementData, RestoreEntitlementResponses, RestoreOrganizationData, RestoreOrganizationResponses, RestoreUserData, RestoreUserResponses, ResumeSubscriptionData, ResumeSubscriptionResponses, RetireApplicationData, RetireApplicationResponses, RetireOrganizationData, RetireOrganizationResponses, RetryNotificationData, RetryNotificationResponses, RevokeApplicationInvitationControlData, RevokeApplicationInvitationControlResponses, RevokeApplicationInvitationData, RevokeApplicationInvitationResponses, RevokeControlPermissionGrantData, RevokeControlPermissionGrantErrors, RevokeControlPermissionGrantResponses, RevokeControlUserSessionData, RevokeControlUserSessionResponses, RevokeDelegationData, RevokeDelegationResponses, RevokeEntitlementData, RevokeEntitlementResponses, RevokeInstallationControlUserInvitationData, RevokeInstallationControlUserInvitationResponses, RevokeMyOAuthConsentData, RevokeMyOAuthConsentResponses, RevokeMySessionData, RevokeMySessionResponses, RevokeMyWorkspaceInvitationData, RevokeMyWorkspaceInvitationResponses, RevokeOAuthConsentData, RevokeOAuthConsentResponses, RevokeOidcTokenData, RevokeOidcTokenResponses, RevokeOrganizationInvitationData, RevokeOrganizationInvitationResponses, RevokePermissionGrantData, RevokePermissionGrantErrors, RevokePermissionGrantResponses, RevokePersonalApiKeyData, RevokePersonalApiKeyResponses, RevokeUserSessionsData, RevokeUserSessionsResponses, RevokeWorkspacePermissionGrantData, RevokeWorkspacePermissionGrantErrors, RevokeWorkspacePermissionGrantResponses, RotateClientSecretData, RotateClientSecretResponses, RotateManagementClientSecretData, RotateManagementClientSecretResponses, RotateSigningKeyData, RotateSigningKeyResponses, RotateWebhookSecretData, RotateWebhookSecretResponses, SendMachineNotificationData, SendMachineNotificationErrors, SendMachineNotificationResponses, ServiceGetApplicationUserData, ServiceGetApplicationUserErrors, ServiceGetApplicationUserResponses, ServiceGetApplicationWorkspaceData, ServiceGetApplicationWorkspaceErrors, ServiceGetApplicationWorkspaceResponses, ServiceGetSubjectBillingData, ServiceGetSubjectBillingErrors, ServiceGetSubjectBillingResponses, ServiceGetSubjectEntitlementsData, ServiceGetSubjectEntitlementsErrors, ServiceGetSubjectEntitlementsResponses, ServiceListApplicationUsersData, ServiceListApplicationUsersErrors, ServiceListApplicationUsersResponses, ServiceListApplicationWorkspaceAccessData, ServiceListApplicationWorkspaceAccessErrors, ServiceListApplicationWorkspaceAccessResponses, ServiceListApplicationWorkspacesData, ServiceListApplicationWorkspacesErrors, ServiceListApplicationWorkspacesResponses, SetDefaultSenderIdentityData, SetDefaultSenderIdentityResponses, SetupStatusData, SetupStatusResponses, StartAppleAuthData, StartAppleAuthResponses, StartAppleLinkData, StartAppleLinkResponses, StartControlExternalLoginData, StartControlExternalLoginResponses, StartControlInvitationExternalLoginData, StartControlInvitationExternalLoginResponses, StartControlUserEmailLoginData, StartControlUserEmailLoginResponses, StartGoogleAuthData, StartGoogleAuthResponses, StartGoogleLinkData, StartGoogleLinkResponses, StartTotpEnrollmentData, StartTotpEnrollmentResponses, StripeWebhookData, StripeWebhookErrors, StripeWebhookResponses, SuspendUserData, SuspendUserResponses, TestInstallationNotificationProviderData, TestInstallationNotificationProviderErrors, TestInstallationNotificationProviderResponses, TestNotificationProviderData, TestNotificationProviderResponses, TestOrganizationNotificationProviderData, TestOrganizationNotificationProviderResponses, TestWebhookData, TestWebhookErrors, TestWebhookResponses, TransferMyWorkspaceOwnershipData, TransferMyWorkspaceOwnershipResponses, UnlinkControlExternalIdentityData, UnlinkControlExternalIdentityErrors, UnlinkControlExternalIdentityResponses, UnlinkMyIdentityData, UnlinkMyIdentityResponses, UnverifyUserEmailData, UnverifyUserEmailResponses, UnverifyUserOrganizationData, UnverifyUserOrganizationResponses, UpdateApplicationData, UpdateApplicationErrors, UpdateApplicationResponses, UpdateApplicationStorageProviderData, UpdateApplicationStorageProviderResponses, UpdateAuthConfigData, UpdateAuthConfigResponses, UpdateBillingProviderData, UpdateBillingProviderResponses, UpdateClientData, UpdateClientResponses, UpdateControlAuthPolicyData, UpdateControlAuthPolicyErrors, UpdateControlAuthPolicyResponses, UpdateControlUserAccountData, UpdateControlUserAccountResponses, UpdateCurrentUserData, UpdateCurrentUserResponses, UpdateEventTypeData, UpdateEventTypeErrors, UpdateEventTypeResponses, UpdateInstallationAuthProviderData, UpdateInstallationAuthProviderErrors, UpdateInstallationAuthProviderResponses, UpdateInstallationBillingProviderData, UpdateInstallationBillingProviderResponses, UpdateInstallationControlUserData, UpdateInstallationControlUserResponses, UpdateInstallationNotificationProviderData, UpdateInstallationNotificationProviderErrors, UpdateInstallationNotificationProviderResponses, UpdateInstallationNotificationTemplateData, UpdateInstallationNotificationTemplateResponses, UpdateInstallationStorageProviderData, UpdateInstallationStorageProviderResponses, UpdateInternalApplicationConfigData, UpdateInternalApplicationConfigErrors, UpdateInternalApplicationConfigResponses, UpdateManagementApiStatusData, UpdateManagementApiStatusResponses, UpdateMyAddressData, UpdateMyAddressResponses, UpdateMyBillingProfileData, UpdateMyBillingProfileResponses, UpdateMyNotificationPreferenceData, UpdateMyNotificationPreferenceResponses, UpdateMyWorkspaceData, UpdateMyWorkspaceResponses, UpdateNotificationProviderData, UpdateNotificationProviderResponses, UpdateNotificationTemplateData, UpdateNotificationTemplateResponses, UpdateOrganizationAuthProviderData, UpdateOrganizationAuthProviderErrors, UpdateOrganizationAuthProviderResponses, UpdateOrganizationBillingProviderData, UpdateOrganizationBillingProviderResponses, UpdateOrganizationData, UpdateOrganizationErrors, UpdateOrganizationMemberData, UpdateOrganizationMemberResponses, UpdateOrganizationNotificationProviderData, UpdateOrganizationNotificationProviderResponses, UpdateOrganizationPolicyData, UpdateOrganizationPolicyErrors, UpdateOrganizationPolicyResponses, UpdateOrganizationResponses, UpdateOrganizationStorageProviderData, UpdateOrganizationStorageProviderResponses, UpdateProductData, UpdateProductResponses, UpdatePublicApplicationConfigData, UpdatePublicApplicationConfigErrors, UpdatePublicApplicationConfigResponses, UpdateRoleData, UpdateRoleErrors, UpdateRoleResponses, UpdateUserData, UpdateUserResponses, UpdateWebhookData, UpdateWebhookErrors, UpdateWebhookResponses, UpdateWorkspaceAddressData, UpdateWorkspaceAddressResponses, UpdateWorkspaceBillingProfileData, UpdateWorkspaceBillingProfileResponses, UpdateWorkspaceData, UpdateWorkspaceResponses, VerifyApplicationDomainData, VerifyApplicationDomainResponses, VerifyApplicationStorageProviderData, VerifyApplicationStorageProviderResponses, VerifyBillingProviderData, VerifyBillingProviderResponses, VerifyControlUserEmailLoginData, VerifyControlUserEmailLoginResponses, VerifyInstallationBillingProviderData, VerifyInstallationBillingProviderResponses, VerifyInstallationNotificationProviderData, VerifyInstallationNotificationProviderErrors, VerifyInstallationNotificationProviderResponses, VerifyInstallationStorageProviderData, VerifyInstallationStorageProviderErrors, VerifyInstallationStorageProviderResponses, VerifyMfaData, VerifyMfaErrors, VerifyMfaResponses, VerifyNotificationProviderData, VerifyNotificationProviderErrors, VerifyNotificationProviderResponses, VerifyOrganizationBillingProviderData, VerifyOrganizationBillingProviderResponses, VerifyOrganizationNotificationProviderData, VerifyOrganizationNotificationProviderResponses, VerifyOrganizationStorageProviderData, VerifyOrganizationStorageProviderResponses, VerifyUserEmailData, VerifyUserEmailResponses, VerifyUserOrganizationData, VerifyUserOrganizationResponses, VersionData, VersionResponses } from './types.gen.js'; export type Options = Options2 & { /** @@ -37,26 +37,30 @@ export const bootstrap = (options: Options export const completeSetup = (options?: Options): RequestResult => (options?.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/setup/complete', - ...options + ...options, + headers: { + 'Content-Type': 'application/json', + ...options?.headers + } }); export const createSetupNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/setup/notification-providers', @@ -67,7 +71,7 @@ export const createSetupNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ +export const startControlUserEmailLogin = (options: Options): RequestResult => (options.client ?? client).post({ url: '/v1/control/auth/email/start', ...options, headers: { @@ -76,7 +80,7 @@ export const startOperatorEmailLogin = (op } }); -export const verifyOperatorEmailLogin = (options: Options): RequestResult => (options.client ?? client).post({ +export const verifyControlUserEmailLogin = (options: Options): RequestResult => (options.client ?? client).post({ url: '/v1/control/auth/email/verify', ...options, headers: { @@ -85,7 +89,7 @@ export const verifyOperatorEmailLogin = (o } }); -export const loginOperatorWithPassword = (options: Options): RequestResult => (options.client ?? client).post({ +export const loginControlUserWithPassword = (options: Options): RequestResult => (options.client ?? client).post({ url: '/v1/control/auth/password', ...options, headers: { @@ -94,14 +98,14 @@ export const loginOperatorWithPassword = ( } }); -export const changeOperatorPassword = (options: Options): RequestResult => (options.client ?? client).put({ +export const changeControlUserPassword = (options: Options): RequestResult => (options.client ?? client).put({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/password', @@ -112,28 +116,28 @@ export const changeOperatorPassword = (opt } }); -export const getOperatorAccount = (options?: Options): RequestResult => (options?.client ?? client).get({ +export const getControlUserAccount = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/me', ...options }); -export const updateOperatorAccount = (options: Options): RequestResult => (options.client ?? client).patch({ +export const updateControlUserAccount = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/me', @@ -144,78 +148,119 @@ export const updateOperatorAccount = (opti } }); -export const logoutOperator = (options?: Options): RequestResult => (options?.client ?? client).post({ +export const logoutControlUser = (options?: Options): RequestResult => (options?.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/logout', ...options }); -export const refreshOperatorSession = (options?: Options): RequestResult => (options?.client ?? client).post({ +export const refreshControlUserSession = (options?: Options): RequestResult => (options?.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/token/refresh', ...options }); -export const listOperatorSessions = (options?: Options): RequestResult => (options?.client ?? client).get({ +export const listControlUserSessions = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/sessions', ...options }); -export const revokeOperatorSession = (options: Options): RequestResult => (options.client ?? client).delete({ +export const revokeControlUserSession = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/sessions/{session_id}', ...options }); -export const logoutAllOperatorSessions = (options?: Options): RequestResult => (options?.client ?? client).post({ +export const logoutAllControlUserSessions = (options?: Options): RequestResult => (options?.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/auth/logout-all', ...options }); -export const acceptOrganizationInvitation = (options: Options): RequestResult => (options.client ?? client).post({ - url: '/v1/control/organization-invitations/accept', +export const getControlAuthMethods = (options?: Options): RequestResult => (options?.client ?? client).get({ url: '/v1/control/auth/methods', ...options }); + +export const startControlExternalLogin = (options: Options): RequestResult => (options.client ?? client).post({ url: '/v1/control/auth/providers/{provider}/start', ...options }); + +export const linkControlExternalIdentity = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/auth/providers/{provider}/link', + ...options +}); + +export const unlinkControlExternalIdentity = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/auth/identities/{identity_id}', + ...options +}); + +export const acceptControlUserInvitation = (options: Options): RequestResult => (options.client ?? client).post({ + url: '/v1/control/invitations/accept', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const startControlInvitationExternalLogin = (options: Options): RequestResult => (options.client ?? client).post({ + url: '/v1/control/invitations/providers/{provider}/start', ...options, headers: { 'Content-Type': 'application/json', @@ -225,12 +270,12 @@ export const acceptOrganizationInvitation = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-providers', @@ -239,12 +284,12 @@ export const listInstallationNotificationProviders = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-providers', @@ -257,12 +302,12 @@ export const createInstallationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-providers/{provider_id}', @@ -271,12 +316,12 @@ export const disableInstallationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-providers/{provider_id}', @@ -285,12 +330,12 @@ export const getInstallationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-providers/{provider_id}', @@ -303,12 +348,12 @@ export const updateInstallationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-providers/{provider_id}/verify', @@ -317,12 +362,12 @@ export const verifyInstallationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-providers/{provider_id}/test', @@ -335,12 +380,12 @@ export const testInstallationNotificationProvider = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/auth/providers', @@ -349,12 +394,12 @@ export const listInstallationAuthProviders = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/auth/providers/{provider}', @@ -363,12 +408,12 @@ export const disableInstallationAuthProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/auth/providers/{provider}', @@ -381,12 +426,12 @@ export const updateInstallationAuthProvider = (options: Options): RequestResult => (options.client ?? client).put({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/auth/providers/{provider}', @@ -399,12 +444,12 @@ export const configureInstallationAuthProvider = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/billing/providers', @@ -413,12 +458,12 @@ export const listInstallationBillingProviders = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/billing/providers', @@ -431,12 +476,12 @@ export const createInstallationBillingProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/billing/providers/{provider_id}', @@ -445,12 +490,12 @@ export const disableInstallationBillingProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/billing/providers/{provider_id}', @@ -459,12 +504,12 @@ export const getInstallationBillingProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/billing/providers/{provider_id}', @@ -477,43 +522,57 @@ export const updateInstallationBillingProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/billing/providers/{provider_id}/verify', ...options }); -export const listInstallationOperators = (options?: Options): RequestResult => (options?.client ?? client).get({ +export const listInstallationControlUsers = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], - url: '/v1/control/installation/operators', + url: '/v1/control/installation/users', ...options }); -export const createInstallationOperator = (options: Options): RequestResult => (options.client ?? client).post({ +export const deleteInstallationControlUser = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], - url: '/v1/control/installation/operators', + url: '/v1/control/installation/users/{control_user_id}', + ...options +}); + +export const updateInstallationControlUser = (options: Options): RequestResult => (options.client ?? client).patch({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/installation/users/{control_user_id}', ...options, headers: { 'Content-Type': 'application/json', @@ -521,31 +580,95 @@ export const createInstallationOperator = } }); -export const deleteInstallationOperator = (options: Options): RequestResult => (options.client ?? client).delete({ +export const listInstallationControlUserInvitations = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], - url: '/v1/control/installation/operators/{operator_id}', + url: '/v1/control/installation/invitations', ...options }); -export const updateInstallationOperator = (options: Options): RequestResult => (options.client ?? client).patch({ +export const createInstallationControlUserInvitation = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], - url: '/v1/control/installation/operators/{operator_id}', + url: '/v1/control/installation/invitations', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const resendInstallationControlUserInvitation = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/installation/invitations/{invitation_id}/resend', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const revokeInstallationControlUserInvitation = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/installation/invitations/{invitation_id}', + ...options +}); + +export const getControlAuthPolicy = (options?: Options): RequestResult => (options?.client ?? client).get({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/installation/auth-policy', + ...options +}); + +export const updateControlAuthPolicy = (options: Options): RequestResult => (options.client ?? client).patch({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/installation/auth-policy', ...options, headers: { 'Content-Type': 'application/json', @@ -555,12 +678,12 @@ export const updateInstallationOperator = export const listSigningKeys = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/signing-keys', @@ -569,12 +692,12 @@ export const listSigningKeys = (options?: export const rotateSigningKey = (options?: Options): RequestResult => (options?.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/signing-keys/rotate', @@ -583,12 +706,12 @@ export const rotateSigningKey = (options?: export const getManagementApiStatus = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/management-api', @@ -597,12 +720,12 @@ export const getManagementApiStatus = (opt export const updateManagementApiStatus = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/management-api', @@ -615,12 +738,12 @@ export const updateManagementApiStatus = ( export const listManagementClients = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/management-clients', @@ -629,12 +752,12 @@ export const listManagementClients = (opti export const createManagementClient = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/management-clients', @@ -647,12 +770,12 @@ export const createManagementClient = (opt export const rotateManagementClientSecret = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/management-clients/{management_client_id}/rotate-secret', @@ -661,12 +784,12 @@ export const rotateManagementClientSecret = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/management-clients/{management_client_id}', @@ -675,12 +798,12 @@ export const disableManagementClient = (op export const updateOrganizationPolicy = (options: Options): RequestResult => (options.client ?? client).put({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/organizations/{organization_id}/policy', @@ -693,12 +816,12 @@ export const updateOrganizationPolicy = (o export const listOrganizations = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations', @@ -707,12 +830,12 @@ export const listOrganizations = (options? export const createOrganization = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations', @@ -725,12 +848,12 @@ export const createOrganization = (options export const listApplications = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/applications', @@ -739,12 +862,12 @@ export const listApplications = (options: export const createApplication = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/applications', @@ -757,12 +880,12 @@ export const createApplication = (options: export const retireApplication = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}', @@ -771,12 +894,12 @@ export const retireApplication = (options: export const updateApplication = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}', @@ -789,12 +912,12 @@ export const updateApplication = (options: export const restoreApplication = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}/restore', @@ -803,12 +926,12 @@ export const restoreApplication = (options export const retireOrganization = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}', @@ -817,12 +940,12 @@ export const retireOrganization = (options export const getOrganization = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}', @@ -831,12 +954,12 @@ export const getOrganization = (options: O export const updateOrganization = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}', @@ -849,12 +972,12 @@ export const updateOrganization = (options export const getOrganizationPolicy = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/policy', @@ -863,12 +986,12 @@ export const getOrganizationPolicy = (opti export const restoreOrganization = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/restore', @@ -877,12 +1000,12 @@ export const restoreOrganization = (option export const listOrganizationMembers = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/members', @@ -891,12 +1014,12 @@ export const listOrganizationMembers = (op export const deleteOrganizationMember = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/members/{member_id}', @@ -905,12 +1028,12 @@ export const deleteOrganizationMember = (o export const updateOrganizationMember = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/members/{member_id}', @@ -923,12 +1046,12 @@ export const updateOrganizationMember = (o export const listOrganizationInvitations = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/invitations', @@ -937,12 +1060,12 @@ export const listOrganizationInvitations = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/invitations', @@ -955,12 +1078,12 @@ export const createOrganizationInvitation = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/invitations/{invitation_id}/resend', @@ -969,12 +1092,12 @@ export const resendOrganizationInvitation = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/invitations/{invitation_id}', @@ -983,12 +1106,12 @@ export const revokeOrganizationInvitation = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/audit-logs', @@ -997,12 +1120,12 @@ export const listOrganizationAuditLogs = ( export const listOrganizationAuthProviders = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/auth/providers', @@ -1011,12 +1134,12 @@ export const listOrganizationAuthProviders = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}', @@ -1025,12 +1148,12 @@ export const disableOrganizationAuthProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}', @@ -1043,12 +1166,12 @@ export const updateOrganizationAuthProvider = (options: Options): RequestResult => (options.client ?? client).put({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}', @@ -1061,12 +1184,12 @@ export const configureOrganizationAuthProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/notification-providers', @@ -1075,12 +1198,12 @@ export const listOrganizationNotificationProviders = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/notification-providers', @@ -1093,12 +1216,12 @@ export const createOrganizationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}', @@ -1107,12 +1230,12 @@ export const disableOrganizationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}', @@ -1121,12 +1244,12 @@ export const getOrganizationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}', @@ -1139,12 +1262,12 @@ export const updateOrganizationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}/verify', @@ -1153,12 +1276,12 @@ export const verifyOrganizationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}/test', @@ -1171,12 +1294,12 @@ export const testOrganizationNotificationProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/billing/providers', @@ -1185,12 +1308,12 @@ export const listOrganizationBillingProviders = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/billing/providers', @@ -1203,12 +1326,12 @@ export const createOrganizationBillingProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}', @@ -1217,12 +1340,12 @@ export const disableOrganizationBillingProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}', @@ -1231,12 +1354,12 @@ export const getOrganizationBillingProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}', @@ -1249,12 +1372,12 @@ export const updateOrganizationBillingProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}/verify', @@ -1265,12 +1388,12 @@ export const publicConfig = (options: Opti export const getApplication = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}', @@ -1279,12 +1402,12 @@ export const getApplication = (options: Op export const getApplicationStatistics = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/statistics', @@ -1293,12 +1416,12 @@ export const getApplicationStatistics = (o export const updatePublicApplicationConfig = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/public-config', @@ -1311,12 +1434,12 @@ export const updatePublicApplicationConfig = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/internal-config', @@ -1329,12 +1452,12 @@ export const updateInternalApplicationConfig = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/auth-config', @@ -1347,12 +1470,12 @@ export const updateAuthConfig = (options: export const configureGoogleProvider = (options: Options): RequestResult => (options.client ?? client).put({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/auth/providers/google', @@ -1365,12 +1488,12 @@ export const configureGoogleProvider = (op export const configureAppleProvider = (options: Options): RequestResult => (options.client ?? client).put({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/auth/providers/apple', @@ -1383,12 +1506,12 @@ export const configureAppleProvider = (opt export const listApplicationAuthProviders = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/auth/providers', @@ -1397,12 +1520,12 @@ export const listApplicationAuthProviders = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/auth/providers/{provider}', @@ -1411,12 +1534,12 @@ export const disableApplicationAuthProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/domains', @@ -1425,12 +1548,12 @@ export const listApplicationDomains = (opt export const createApplicationDomain = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/domains', @@ -1443,12 +1566,12 @@ export const createApplicationDomain = (op export const deleteApplicationDomain = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/domains/{domain_id}', @@ -1457,12 +1580,12 @@ export const deleteApplicationDomain = (op export const verifyApplicationDomain = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/domains/{domain_id}/verify', @@ -1471,12 +1594,12 @@ export const verifyApplicationDomain = (op export const listClients = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/clients', @@ -1485,12 +1608,12 @@ export const listClients = (options: Optio export const createClient = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/clients', @@ -1503,12 +1626,26 @@ export const createClient = (options: Opti export const disableClient = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/clients/{client_id}', + ...options +}); + +export const getClient = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/clients/{client_id}', @@ -1517,12 +1654,12 @@ export const disableClient = (options: Opt export const updateClient = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/clients/{client_id}', @@ -1535,12 +1672,12 @@ export const updateClient = (options: Opti export const rotateClientSecret = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/clients/{client_id}/rotate-secret', @@ -1549,26 +1686,26 @@ export const rotateClientSecret = (options export const listRoles = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/roles', ...options }); -export const createRole = (options: Options): RequestResult => (options.client ?? client).post({ +export const createRole = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/roles', @@ -1581,12 +1718,12 @@ export const createRole = (options: Option export const deleteRole = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/roles/{role_id}', @@ -1595,12 +1732,12 @@ export const deleteRole = (options: Option export const getRole = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/roles/{role_id}', @@ -1609,12 +1746,12 @@ export const getRole = (options: Options(options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/roles/{role_id}', @@ -1627,12 +1764,12 @@ export const updateRole = (options: Option export const listWorkspaces = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces', @@ -1641,12 +1778,12 @@ export const listWorkspaces = (options: Op export const createWorkspace = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces', @@ -1659,12 +1796,12 @@ export const createWorkspace = (options: O export const deleteWorkspace = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}', @@ -1673,12 +1810,12 @@ export const deleteWorkspace = (options: O export const getWorkspace = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}', @@ -1687,12 +1824,12 @@ export const getWorkspace = (options: Opti export const updateWorkspace = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}', @@ -1705,12 +1842,12 @@ export const updateWorkspace = (options: O export const recoverWorkspaceOwnership = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/owner-transfer', @@ -1723,12 +1860,12 @@ export const recoverWorkspaceOwnership = ( export const listWorkspaceMembers = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members', @@ -1737,12 +1874,12 @@ export const listWorkspaceMembers = (optio export const deleteWorkspaceMember = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}', @@ -1751,12 +1888,12 @@ export const deleteWorkspaceMember = (opti export const replaceWorkspaceMemberRoles = (options: Options): RequestResult => (options.client ?? client).put({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}', @@ -1769,12 +1906,12 @@ export const replaceWorkspaceMemberRoles = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/role-assignments', @@ -1783,12 +1920,12 @@ export const listRoleAssignments = (option export const createRoleAssignment = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/role-assignments', @@ -1801,26 +1938,100 @@ export const createRoleAssignment = (optio export const deleteRoleAssignment = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/role-assignments/{assignment_id}', ...options }); +export const listControlPermissionGrants = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/permission-grants', + ...options +}); + +export const createControlPermissionGrant = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/permission-grants', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const getControlEffectiveAccess = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/permission-grants/effective', + ...options +}); + +export const revokeControlPermissionGrant = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/permission-grants/{grant_id}', + ...options +}); + +export const getControlPermissionGrant = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/permission-grants/{grant_id}', + ...options +}); + export const listDelegations = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/delegations', @@ -1829,12 +2040,12 @@ export const listDelegations = (options: O export const createDelegation = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/delegations', @@ -1847,12 +2058,12 @@ export const createDelegation = (options: export const getDelegation = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/delegations/{delegation_id}', @@ -1868,45 +2079,240 @@ export const exchangeDelegation = (options } }); +/** + * Machine-client-only template notification delivery. + */ +export const sendMachineNotification = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/notifications', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const listPermissionGrants = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/permission-grants', + ...options +}); + +export const createPermissionGrant = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/permission-grants', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const getEffectiveAccess = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/permission-grants/effective', + ...options +}); + +export const revokePermissionGrant = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/permission-grants/{grant_id}', + ...options +}); + +export const getPermissionGrant = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/permission-grants/{grant_id}', + ...options +}); + +export const listApplicationInvitations = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/invitations', + ...options +}); + +export const createApplicationInvitationMachine = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/invitations', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const revokeApplicationInvitation = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/invitations/{invitation_id}', + ...options +}); + +export const getApplicationInvitation = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/invitations/{invitation_id}', + ...options +}); + +export const resendApplicationInvitation = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/invitations/{invitation_id}/resend', + ...options +}); + +export const serviceListApplicationUsers = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/users', + ...options +}); + +export const serviceGetApplicationUser = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/users/{user_id}', + ...options +}); + +export const serviceListApplicationWorkspaces = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces', + ...options +}); + +export const serviceGetApplicationWorkspace = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/service/workspaces/{workspace_id}', + ...options +}); + +export const serviceListApplicationWorkspaceAccess = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/service/workspaces/{workspace_id}/access', + ...options +}); + +export const serviceGetSubjectEntitlements = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements', + ...options +}); + +export const serviceGetSubjectBilling = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing', + ...options +}); + export const revokeDelegation = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/delegations/{delegation_id}/revoke', ...options }); -export const listWorkspaceInvitations = (options: Options): RequestResult => (options.client ?? client).get({ +export const listApplicationInvitationsControl = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], - url: '/v1/control/applications/{application_id}/workspace-invitations', + url: '/v1/control/applications/{application_id}/invitations', ...options }); -export const createWorkspaceInvitation = (options: Options): RequestResult => (options.client ?? client).post({ +export const createApplicationInvitationControl = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], - url: '/v1/control/applications/{application_id}/workspace-invitations', + url: '/v1/control/applications/{application_id}/invitations', ...options, headers: { 'Content-Type': 'application/json', @@ -1914,28 +2320,56 @@ export const createWorkspaceInvitation = ( } }); -export const revokeWorkspaceInvitation = (options: Options): RequestResult => (options.client ?? client).delete({ +export const revokeApplicationInvitationControl = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/invitations/{invitation_id}', + ...options +}); + +export const getApplicationInvitationControl = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], - url: '/v1/control/applications/{application_id}/workspace-invitations/{invitation_id}', + url: '/v1/control/applications/{application_id}/invitations/{invitation_id}', + ...options +}); + +export const resendApplicationInvitationControl = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/invitations/{invitation_id}/resend', ...options }); export const listUsers = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users', @@ -1944,12 +2378,12 @@ export const listUsers = (options: Options export const createUser = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users', @@ -1962,12 +2396,12 @@ export const createUser = (options: Option export const getUser = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}', @@ -1976,12 +2410,12 @@ export const getUser = (options: Options(options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}', @@ -1994,12 +2428,12 @@ export const updateUser = (options: Option export const suspendUser = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/suspend', @@ -2012,12 +2446,12 @@ export const suspendUser = (options: Optio export const restoreUser = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/restore', @@ -2030,12 +2464,12 @@ export const restoreUser = (options: Optio export const verifyUserEmail = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/verify-email', @@ -2048,12 +2482,12 @@ export const verifyUserEmail = (options: O export const unverifyUserEmail = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/unverify-email', @@ -2066,12 +2500,12 @@ export const unverifyUserEmail = (options: export const verifyUserOrganization = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/verify-organization', @@ -2084,12 +2518,12 @@ export const verifyUserOrganization = (opt export const unverifyUserOrganization = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/unverify-organization', @@ -2102,12 +2536,12 @@ export const unverifyUserOrganization = (o export const listUserSessions = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/sessions', @@ -2116,12 +2550,12 @@ export const listUserSessions = (options: export const revokeUserSessions = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/sessions/revoke', @@ -2130,12 +2564,12 @@ export const revokeUserSessions = (options export const listUserAddresses = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/users/{user_id}/addresses', @@ -2144,12 +2578,12 @@ export const listUserAddresses = (options: export const listOAuthConsents = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/oauth-consents', @@ -2158,12 +2592,12 @@ export const listOAuthConsents = (options: export const revokeOAuthConsent = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/oauth-consents/{user_id}/{client_id}/revoke', @@ -2172,12 +2606,12 @@ export const revokeOAuthConsent = (options export const listFeatures = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/features', @@ -2186,12 +2620,12 @@ export const listFeatures = (options: Opti export const createFeature = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/features', @@ -2220,14 +2654,7 @@ export const passwordSignIn = (options: Op } }); -export const authMethods = (options: Options): RequestResult => (options.client ?? client).post({ - url: '/v1/applications/{application_id}/auth/methods', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } -}); +export const authMethods = (options: Options): RequestResult => (options.client ?? client).post({ url: '/v1/applications/{application_id}/auth/methods', ...options }); export const emailStart = (options: Options): RequestResult => (options.client ?? client).post({ url: '/v1/applications/{application_id}/auth/email/start', @@ -2285,7 +2712,7 @@ export const startGoogleAuth = (options: O } }); -export const googleAuthCallback = (options: Options): RequestResult => (options.client ?? client).get({ url: '/v1/applications/{application_id}/auth/providers/google/callback', ...options }); +export const googleAuthCallback = (options?: Options): RequestResult => (options?.client ?? client).get({ url: '/v1/auth/providers/google/callback', ...options }); export const exchangeGoogleAuth = (options: Options): RequestResult => (options.client ?? client).post({ url: '/v1/applications/{application_id}/auth/providers/google/exchange', @@ -2305,13 +2732,13 @@ export const startAppleAuth = (options: Op } }); -export const appleAuthCallback = (options: Options): RequestResult => (options.client ?? client).post({ +export const appleAuthCallback = (options?: Options): RequestResult => (options?.client ?? client).post({ ...urlSearchParamsBodySerializer, - url: '/v1/applications/{application_id}/auth/providers/apple/callback', + url: '/v1/auth/providers/apple/callback', ...options, headers: { 'Content-Type': 'application/x-www-form-urlencoded', - ...options.headers + ...options?.headers } }); @@ -2351,6 +2778,24 @@ export const finishWebAuthnAuthentication = (options: Options): RequestResult => (options.client ?? client).post({ + url: '/v1/applications/{application_id}/auth/invitations/exchange', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const redeemApplicationInvitation = (options: Options): RequestResult => (options.client ?? client).post({ + url: '/v1/applications/{application_id}/auth/invitations/token', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + export const deleteMyAccount = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ key: 'bearerAuth', @@ -2423,12 +2868,12 @@ export const publicCatalog = (options: Opt export const listProducts = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/products', @@ -2437,12 +2882,12 @@ export const listProducts = (options: Opti export const createProduct = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/products', @@ -2455,12 +2900,12 @@ export const createProduct = (options: Opt export const listPrices = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/products/{product_id}/prices', @@ -2469,12 +2914,12 @@ export const listPrices = (options: Option export const createPrice = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/products/{product_id}/prices', @@ -2487,12 +2932,12 @@ export const createPrice = (options: Optio export const getProduct = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/products/{product_id}', @@ -2501,12 +2946,12 @@ export const getProduct = (options: Option export const updateProduct = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/products/{product_id}', @@ -2519,12 +2964,12 @@ export const updateProduct = (options: Opt export const listEntitlements = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/entitlements', @@ -2533,12 +2978,12 @@ export const listEntitlements = (options: export const createEntitlement = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/entitlements', @@ -2551,12 +2996,12 @@ export const createEntitlement = (options: export const getEntitlement = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/entitlements/{entitlement_id}', @@ -2565,12 +3010,12 @@ export const getEntitlement = (options: Op export const revokeEntitlement = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/entitlements/{entitlement_id}/revoke', @@ -2581,14 +3026,32 @@ export const revokeEntitlement = (options: } }); +export const adjustEntitlement = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'controlBearer', + scheme: 'bearer', + type: 'http' + }, { + in: 'cookie', + name: 'p93_control_access', + type: 'apiKey' + }], + url: '/v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + export const restoreEntitlement = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/entitlements/{entitlement_id}/restore', @@ -2601,12 +3064,12 @@ export const restoreEntitlement = (options export const listLocalEntitlementRequests = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/local-entitlement-requests', @@ -2615,12 +3078,12 @@ export const listLocalEntitlementRequests = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/local-entitlement-requests/{request_id}', @@ -2629,12 +3092,12 @@ export const getLocalEntitlementRequest = export const approveLocalEntitlementRequest = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/approve', @@ -2647,12 +3110,12 @@ export const approveLocalEntitlementRequest = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/reject', @@ -2665,12 +3128,12 @@ export const rejectLocalEntitlementRequest = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/local-entitlement-requests/{request_id}/reopen', @@ -2737,12 +3200,12 @@ export const listMyEntitlements = (options export const listBillingProviders = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/providers', @@ -2751,12 +3214,12 @@ export const listBillingProviders = (optio export const createBillingProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/providers', @@ -2769,12 +3232,12 @@ export const createBillingProvider = (opti export const disableBillingProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/providers/{provider_id}', @@ -2783,12 +3246,12 @@ export const disableBillingProvider = (opt export const getBillingProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/providers/{provider_id}', @@ -2797,12 +3260,12 @@ export const getBillingProvider = (options export const updateBillingProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/providers/{provider_id}', @@ -2815,12 +3278,12 @@ export const updateBillingProvider = (opti export const verifyBillingProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/providers/{provider_id}/verify', @@ -2867,12 +3330,12 @@ export const createBillingPortalSession = export const listSubscriptions = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/subscriptions', @@ -2881,12 +3344,12 @@ export const listSubscriptions = (options: export const getSubscription = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}', @@ -2895,12 +3358,12 @@ export const getSubscription = (options: O export const cancelSubscription = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/cancel', @@ -2913,12 +3376,12 @@ export const cancelSubscription = (options export const resumeSubscription = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/resume', @@ -2927,12 +3390,12 @@ export const resumeSubscription = (options export const changeSubscriptionPrice = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/subscriptions/{subscription_id}/change-price', @@ -2945,12 +3408,12 @@ export const changeSubscriptionPrice = (op export const listInvoices = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/invoices', @@ -2959,12 +3422,12 @@ export const listInvoices = (options: Opti export const getInvoice = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/invoices/{invoice_id}', @@ -2973,12 +3436,12 @@ export const getInvoice = (options: Option export const listPayments = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/payments', @@ -2987,12 +3450,12 @@ export const listPayments = (options: Opti export const getPayment = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/payments/{payment_id}', @@ -3001,12 +3464,12 @@ export const getPayment = (options: Option export const createRefund = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/payments/{payment_id}/refunds', @@ -3019,12 +3482,12 @@ export const createRefund = (options: Opti export const listRefunds = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/refunds', @@ -3033,12 +3496,12 @@ export const listRefunds = (options: Optio export const getRefund = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/refunds/{refund_id}', @@ -3047,12 +3510,12 @@ export const getRefund = (options: Options export const listDisputes = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/disputes', @@ -3061,12 +3524,12 @@ export const listDisputes = (options: Opti export const getDispute = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/disputes/{dispute_id}', @@ -3075,12 +3538,12 @@ export const getDispute = (options: Option export const getBillingStatistics = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/statistics', @@ -3089,12 +3552,12 @@ export const getBillingStatistics = (optio export const listBillingProviderEvents = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/provider-events', @@ -3103,12 +3566,12 @@ export const listBillingProviderEvents = ( export const replayBillingProviderEvent = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/provider-events/{event_id}/replay', @@ -3117,12 +3580,12 @@ export const replayBillingProviderEvent = export const createBillingReconciliationRun = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/providers/{provider_id}/reconciliation-runs', @@ -3131,12 +3594,12 @@ export const createBillingReconciliationRun = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/reconciliation-runs', @@ -3145,12 +3608,12 @@ export const listBillingReconciliationRuns = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/billing/reconciliation-runs/{run_id}', @@ -3655,6 +4118,16 @@ export const leaveWorkspace = (options: Op ...options }); +export const listMyWorkspaceInvitations = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations', + ...options +}); + export const createMyWorkspaceInvitation = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ key: 'bearerAuth', @@ -3669,6 +4142,80 @@ export const createMyWorkspaceInvitation = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}', + ...options +}); + +export const resendMyWorkspaceInvitation = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend', + ...options +}); + +export const listMyWorkspaceAccess = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/access', + ...options +}); + +export const listWorkspacePermissionGrants = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants', + ...options +}); + +export const createWorkspacePermissionGrant = (options: Options): RequestResult => (options.client ?? client).post({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +export const revokeWorkspacePermissionGrant = (options: Options): RequestResult => (options.client ?? client).delete({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}', + ...options +}); + +export const getWorkspacePermissionGrant = (options: Options): RequestResult => (options.client ?? client).get({ + security: [{ + key: 'bearerAuth', + scheme: 'bearer', + type: 'http' + }], + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}', + ...options +}); + export const getWorkspaceBillingProfile = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ key: 'bearerAuth', @@ -3751,7 +4298,7 @@ export const activateWorkspaceAddress = (o ...options }); -export const listMyWorkspaceInvitations = (options: Options): RequestResult => (options.client ?? client).get({ +export const listMyPendingInvitations = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ key: 'bearerAuth', scheme: 'bearer', @@ -3761,20 +4308,6 @@ export const listMyWorkspaceInvitations = ...options }); -export const acceptMyWorkspaceInvitation = (options: Options): RequestResult => (options.client ?? client).post({ - security: [{ - key: 'bearerAuth', - scheme: 'bearer', - type: 'http' - }], - url: '/v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } -}); - export const checkMyPermissions = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ key: 'bearerAuth', @@ -3825,12 +4358,12 @@ export const publishCustomEvent = (options export const listEvents = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/events', @@ -3839,12 +4372,12 @@ export const listEvents = (options: Option export const getEvent = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/events/{event_id}', @@ -3853,12 +4386,12 @@ export const getEvent = (options: Options< export const listEventTypes = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/event-types', @@ -3867,12 +4400,12 @@ export const listEventTypes = (options: Op export const createEventType = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/event-types', @@ -3885,12 +4418,12 @@ export const createEventType = (options: O export const archiveEventType = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/event-types/{event_type_id}', @@ -3899,12 +4432,12 @@ export const archiveEventType = (options: export const getEventType = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/event-types/{event_type_id}', @@ -3913,12 +4446,12 @@ export const getEventType = (options: Opti export const updateEventType = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/event-types/{event_type_id}', @@ -3931,12 +4464,12 @@ export const updateEventType = (options: O export const listAuditLogs = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/audit-logs', @@ -3945,12 +4478,12 @@ export const listAuditLogs = (options: Opt export const getAuditLog = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/audit-logs/{audit_id}', @@ -3959,12 +4492,12 @@ export const getAuditLog = (options: Optio export const createAuditExport = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/audit-exports', @@ -3977,12 +4510,12 @@ export const createAuditExport = (options: export const getAuditExport = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/audit-exports/{export_id}', @@ -3991,12 +4524,12 @@ export const getAuditExport = (options: Op export const listWebhooks = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhooks', @@ -4005,12 +4538,12 @@ export const listWebhooks = (options: Opti export const createWebhook = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhooks', @@ -4023,12 +4556,12 @@ export const createWebhook = (options: Opt export const disableWebhook = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhooks/{webhook_id}', @@ -4037,12 +4570,12 @@ export const disableWebhook = (options: Op export const getWebhook = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhooks/{webhook_id}', @@ -4051,12 +4584,12 @@ export const getWebhook = (options: Option export const updateWebhook = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhooks/{webhook_id}', @@ -4069,12 +4602,12 @@ export const updateWebhook = (options: Opt export const testWebhook = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhooks/{webhook_id}/test', @@ -4083,12 +4616,12 @@ export const testWebhook = (options: Optio export const rotateWebhookSecret = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhooks/{webhook_id}/rotate-secret', @@ -4097,12 +4630,12 @@ export const rotateWebhookSecret = (option export const listWebhookDeliveries = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhook-deliveries', @@ -4111,12 +4644,12 @@ export const listWebhookDeliveries = (opti export const getWebhookDelivery = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhook-deliveries/{delivery_id}', @@ -4125,12 +4658,12 @@ export const getWebhookDelivery = (options export const replayWebhookDelivery = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/webhook-deliveries/{delivery_id}/replay', @@ -4139,12 +4672,12 @@ export const replayWebhookDelivery = (opti export const listNotificationProviders = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-providers', @@ -4153,12 +4686,12 @@ export const listNotificationProviders = ( export const createNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-providers', @@ -4171,12 +4704,12 @@ export const createNotificationProvider = export const disableNotificationProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-providers/{provider_id}', @@ -4185,12 +4718,12 @@ export const disableNotificationProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-providers/{provider_id}', @@ -4199,12 +4732,12 @@ export const getNotificationProvider = (op export const updateNotificationProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-providers/{provider_id}', @@ -4217,12 +4750,12 @@ export const updateNotificationProvider = export const verifyNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-providers/{provider_id}/verify', @@ -4231,12 +4764,12 @@ export const verifyNotificationProvider = export const testNotificationProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-providers/{provider_id}/test', @@ -4249,12 +4782,12 @@ export const testNotificationProvider = (o export const listSenderIdentities = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/sender-identities', @@ -4263,12 +4796,12 @@ export const listSenderIdentities = (optio export const createSenderIdentity = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/sender-identities', @@ -4281,12 +4814,12 @@ export const createSenderIdentity = (optio export const setDefaultSenderIdentity = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/sender-identities/{sender_id}/default', @@ -4295,12 +4828,12 @@ export const setDefaultSenderIdentity = (o export const listInstallationNotificationTemplates = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-templates', @@ -4309,12 +4842,12 @@ export const listInstallationNotificationTemplates = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-templates', @@ -4327,12 +4860,12 @@ export const createInstallationNotificationTemplate = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-template-variables', @@ -4341,12 +4874,12 @@ export const listInstallationNotificationTemplateVariables = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-templates/{template_id}', @@ -4355,12 +4888,12 @@ export const getInstallationNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-templates/{template_id}', @@ -4373,12 +4906,12 @@ export const updateInstallationNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-templates/{template_id}/preview', @@ -4391,12 +4924,12 @@ export const previewInstallationNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-templates/{template_id}/publish', @@ -4405,12 +4938,12 @@ export const publishInstallationNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/notification-templates/{template_id}/archive', @@ -4419,12 +4952,12 @@ export const archiveInstallationNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-templates', @@ -4433,12 +4966,12 @@ export const listNotificationTemplates = ( export const createNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-templates', @@ -4451,12 +4984,12 @@ export const createNotificationTemplate = export const listNotificationTemplateVariables = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-template-variables', @@ -4465,12 +4998,12 @@ export const listNotificationTemplateVariables = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-templates/{template_id}', @@ -4479,12 +5012,12 @@ export const getNotificationTemplate = (op export const updateNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-templates/{template_id}', @@ -4497,12 +5030,12 @@ export const updateNotificationTemplate = export const previewNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-templates/{template_id}/preview', @@ -4515,12 +5048,12 @@ export const previewNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-templates/{template_id}/publish', @@ -4529,12 +5062,12 @@ export const publishNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notification-templates/{template_id}/archive', @@ -4543,44 +5076,26 @@ export const archiveNotificationTemplate = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notifications', ...options }); -export const queueNotification = (options: Options): RequestResult => (options.client ?? client).post({ - security: [{ - key: 'operatorBearer', - scheme: 'bearer', - type: 'http' - }, { - in: 'cookie', - name: 'p93_operator_access', - type: 'apiKey' - }], - url: '/v1/control/applications/{application_id}/notifications', - ...options, - headers: { - 'Content-Type': 'application/json', - ...options.headers - } -}); - export const getNotificationStatistics = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notifications/statistics', @@ -4589,12 +5104,12 @@ export const getNotificationStatistics = ( export const getNotification = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notifications/{notification_id}', @@ -4603,12 +5118,12 @@ export const getNotification = (options: O export const retryNotification = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/notifications/{notification_id}/retry', @@ -4641,12 +5156,12 @@ export const updateMyNotificationPreference = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/providers', @@ -4655,12 +5170,12 @@ export const listInstallationStorageProviders = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/providers', @@ -4673,12 +5188,12 @@ export const createInstallationStorageProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/providers/{provider_id}', @@ -4687,12 +5202,12 @@ export const disableInstallationStorageProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/providers/{provider_id}', @@ -4701,12 +5216,12 @@ export const getInstallationStorageProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/providers/{provider_id}', @@ -4719,12 +5234,12 @@ export const updateInstallationStorageProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/providers/{provider_id}/verify', @@ -4733,12 +5248,12 @@ export const verifyInstallationStorageProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/providers/{provider_id}/enable', @@ -4747,12 +5262,12 @@ export const enableInstallationStorageProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/providers', @@ -4761,12 +5276,12 @@ export const listOrganizationStorageProviders = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/providers', @@ -4779,12 +5294,12 @@ export const createOrganizationStorageProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/providers/{provider_id}', @@ -4793,12 +5308,12 @@ export const disableOrganizationStorageProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/providers/{provider_id}', @@ -4807,12 +5322,12 @@ export const getOrganizationStorageProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/providers/{provider_id}', @@ -4825,12 +5340,12 @@ export const updateOrganizationStorageProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/providers/{provider_id}/verify', @@ -4839,12 +5354,12 @@ export const verifyOrganizationStorageProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/providers/{provider_id}/enable', @@ -4853,12 +5368,12 @@ export const enableOrganizationStorageProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/providers', @@ -4867,12 +5382,12 @@ export const listApplicationStorageProviders = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/providers', @@ -4885,12 +5400,12 @@ export const createApplicationStorageProvider = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/providers/{provider_id}', @@ -4899,12 +5414,12 @@ export const disableApplicationStorageProvider = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/providers/{provider_id}', @@ -4913,12 +5428,12 @@ export const getApplicationStorageProvider = (options: Options): RequestResult => (options.client ?? client).patch({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/providers/{provider_id}', @@ -4931,12 +5446,12 @@ export const updateApplicationStorageProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/providers/{provider_id}/verify', @@ -4945,12 +5460,12 @@ export const verifyApplicationStorageProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/providers/{provider_id}/enable', @@ -4959,12 +5474,12 @@ export const enableApplicationStorageProvider = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/uploads', @@ -4977,12 +5492,12 @@ export const createInstallationStorageUpload = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/uploads/{object_id}/complete', @@ -4991,12 +5506,12 @@ export const completeInstallationStorageUpload = (options?: Options): RequestResult => (options?.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/objects', @@ -5005,12 +5520,12 @@ export const listInstallationStorageObjects = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/objects/{object_id}', @@ -5019,12 +5534,12 @@ export const deleteInstallationStorageObject = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/objects/{object_id}', @@ -5033,12 +5548,12 @@ export const getInstallationStorageObject = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/installation/storage/objects/{object_id}/download', @@ -5047,12 +5562,12 @@ export const downloadInstallationStorageObject = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/objects', @@ -5061,12 +5576,12 @@ export const listOrganizationStorageObjects = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/objects/{object_id}', @@ -5075,12 +5590,12 @@ export const deleteOrganizationStorageObject = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/objects/{object_id}', @@ -5089,12 +5604,12 @@ export const getOrganizationStorageObject = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/organizations/{organization_id}/storage/objects/{object_id}/download', @@ -5103,12 +5618,12 @@ export const downloadOrganizationStorageObject = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/uploads', @@ -5121,12 +5636,12 @@ export const createControlApplicationStorageUpload = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/uploads/{object_id}/complete', @@ -5135,12 +5650,12 @@ export const completeControlApplicationStorageUpload = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/objects', @@ -5149,12 +5664,12 @@ export const listControlApplicationStorageObjects = (options: Options): RequestResult => (options.client ?? client).delete({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/objects/{object_id}', @@ -5163,12 +5678,12 @@ export const deleteControlApplicationStorageObject = (options: Options): RequestResult => (options.client ?? client).get({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/objects/{object_id}', @@ -5177,12 +5692,12 @@ export const getControlApplicationStorageObject = (options: Options): RequestResult => (options.client ?? client).post({ security: [{ - key: 'operatorBearer', + key: 'controlBearer', scheme: 'bearer', type: 'http' }, { in: 'cookie', - name: 'p93_operator_access', + name: 'p93_control_access', type: 'apiKey' }], url: '/v1/control/applications/{application_id}/storage/objects/{object_id}/download', diff --git a/sdk/typescript/sdk/src/generated/types.gen.ts b/sdk/typescript/sdk/src/generated/types.gen.ts index fb05f9a..1195a53 100644 --- a/sdk/typescript/sdk/src/generated/types.gen.ts +++ b/sdk/typescript/sdk/src/generated/types.gen.ts @@ -4,3169 +4,6140 @@ export type ClientOptions = { baseUrl: `${string}://${string}` | (string & {}); }; -export type ManagementApiStatus = { - enabled: boolean; - can_manage: boolean; - active_clients: number; - token_endpoint: string; - api_base: string; +export type HealthStatus = { + status: 'ok' | 'ready'; }; -export type CreateManagementClient = { - client_id: string; - name: string; - allowed_scopes?: Array<'/management/organizations/*'>; +export type VersionInfo = { + version: string; + commit: string; + built_at: string; + schema: string; }; -export type OrganizationEnabledSettings = { - public_registration: boolean; - password_authentication: boolean; - passwordless_authentication: boolean; - personal_api_keys: boolean; - delegation: boolean; - organization_provider_overrides: boolean; - application_provider_overrides: boolean; - custom_events: boolean; - webhooks: boolean; +export type SetupStatus = { + available: boolean; + control_user_email_login_available: boolean; + control_auth_methods: ControlAuthMethods; }; -export type UpdateOrganizationPolicy = { - /** - * Null means unlimited. - */ - max_applications: number | null; - /** - * Null means unlimited across all applications in the organization. - */ - max_users: number | null; - enabled_settings: OrganizationEnabledSettings; +export type SetupSession = { + token_type: 'Bearer'; + expires_in: number; + control_user_id: Uuid; }; -export type OrganizationPolicy = UpdateOrganizationPolicy & { - organization_id: Uuid; - usage: { - applications: number; - users: number; - }; - version: number; +export type SetupCompletion = { + token_type: 'Bearer'; + expires_in: number; + completed: true; }; -export type Uuid = string; +export type ChallengeAccepted = { + challenge_id: Uuid; + expires_in: number; +}; -export type CreateStorageProvider = unknown & { - name: string; - endpoint: string; - region: string; - force_path_style?: boolean; - public_bucket?: string; - private_bucket?: string; - public_base_url?: string; - inheritable?: boolean; - /** - * Installation-scoped opt-in for local or private-network S3 endpoints. - */ - allow_private_endpoint?: boolean; - max_object_bytes?: number; - max_email_image_bytes?: number; - max_application_bytes?: number; - max_application_objects?: number; +export type NotificationQueued = { + notification_id: Uuid; + status: 'queued'; }; -export type CreateStorageUpload = { - filename: string; - content_type: string; - size_bytes: number; - visibility: 'public' | 'private'; - purpose?: 'email_image'; - metadata?: { - [key: string]: unknown; - }; +export type InvitationResent = { + id: Uuid; + last_sent_at: string; + resend_available_at: string; + expires_at: string; }; -export type StorageObject = { +export type ReconciliationAccepted = { id: Uuid; - application_id?: string | null; provider_id: Uuid; - owner_type: 'installation' | 'application' | 'user' | 'workspace'; - owner_id?: string | null; - visibility: 'public' | 'private'; - filename: string; - content_type: string; - size_bytes: number; - etag?: string | null; - metadata: { - [key: string]: unknown; - }; - status: 'pending' | 'ready' | 'deleting' | 'failed'; - public_url?: string | null; - upload_expires_at?: string | null; - ready_at?: string | null; - last_error?: string | null; - version: number; - created_at: string; - updated_at: string; + status: 'pending'; }; -export type StorageUploadAuthorization = { - object: StorageObject; - upload_expires_at: string; - required_headers: { - [key: string]: string; - }; +export type WebhookTestAccepted = { + event_id: Uuid; + delivery_id: Uuid; + status: 'pending'; }; -export type RuntimeStorageConfig = { - public_uploads_enabled: boolean; - private_uploads_enabled: boolean; - max_public_object_bytes?: number; - max_private_object_bytes?: number; - max_email_image_bytes?: number; - public_provider_scope?: 'installation' | 'organization' | 'application'; - private_provider_scope?: 'installation' | 'organization' | 'application'; +export type ControlUserAccount = { + id: Uuid; + email: string; + display_name: string; + status: 'active' | 'suspended' | 'deleted'; + installation_role: 'owner' | 'admin' | 'auditor' | null; + organizations: Array<{ + id: Uuid; + name: string; + role: 'owner' | 'admin' | 'member' | 'auditor'; + }>; + sign_in_methods: { + email_code: boolean; + magic_link: boolean; + password: boolean; + external_identities: Array<{ + id: Uuid; + provider: 'google' | 'apple'; + metadata: { + [key: string]: unknown; + }; + available: boolean; + created_at: string; + last_used_at?: string | null; + }>; + }; + created_at: string; + updated_at: string; }; -/** - * Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. - */ -export type Locale = string; +export type Session = { + id: Uuid; + actor_type: 'control_user' | 'user' | 'client'; + user_agent?: string | null; + ip_address?: string | null; + amr?: Array; + authenticated_at?: string | null; + created_at: string; + expires_at: string; + revoked: boolean; +}; -export type Problem = { - type: string; - title: string; - status: number; - detail?: string; - code: string; - request_id?: string; +export type NotificationProvider = { + id: Uuid; + provider: 'smtp'; + scope: 'installation' | 'organization' | 'application'; + organization_id?: string | null; + application_id?: string | null; + name: string; + sender_email: string; + sender_name: string; + inheritable: boolean; + verified?: boolean; + credentials_configured?: boolean; + effective?: boolean; + verified_at?: string | null; + disabled_at?: string | null; + created_at?: string; + updated_at?: string; }; -export type Page = { - items: Array; - next_cursor: string | null; +export type AuthProvider = { + id: Uuid; + provider: 'google' | 'apple'; + scope: 'installation' | 'organization' | 'application'; + organization_id?: string | null; + application_id?: string | null; + client_id: string; + team_id?: string | null; + key_id?: string | null; + inheritable: boolean; + control_login_enabled: boolean; + configured?: boolean; + inherited?: boolean; + linked_control_users?: number; + inheriting_applications?: number; + callback_uri?: string; + created_at?: string; + updated_at?: string; }; -export type OrganizationPage = { - items: Array<{ +export type BillingProvider = { + id: Uuid; + provider: 'stripe'; + public_id: string; + api_version: string; + status: 'active' | 'disabled' | 'error'; + scope: 'installation' | 'organization' | 'application'; + inheritable: boolean; + organization_id?: string | null; + application_id?: string | null; + inherited?: boolean; + webhook_configured?: boolean; + effective?: boolean; + metadata?: { [key: string]: unknown; - }>; - next_cursor: string | null; - /** - * The current operator's installation-wide role, or null for organization-only access. - */ - installation_role: 'owner' | 'admin' | 'auditor' | null; + }; + webhook_uri: string; + created_at?: string; + updated_at?: string; }; -export type BootstrapRequest = { +export type ControlUser = { + id: Uuid; email: string; - display_name?: string; + display_name: string; + status: 'active' | 'suspended' | 'deleted'; + role: 'owner' | 'admin' | 'member' | 'auditor'; + created_at?: string; + updated_at?: string; }; -export type AcceptOrganizationInvitation = { - display_name?: string; +export type ControlUserInvitation = { + id: Uuid; + organization_id?: string | null; + email: string; + role: 'owner' | 'admin' | 'member' | 'auditor'; + onboarding_method: 'email' | 'google' | 'apple'; + status?: 'pending' | 'accepted' | 'revoked' | 'expired'; + expires_at: string; + token_returned_once?: boolean; + invited_by?: string; + accepted_by?: string | null; + accepted_at?: string | null; + revoked_at?: string | null; + created_at?: string; + updated_at?: string; }; -export type ApplicationFlowConfig = { - oauth_client_id: string; - sign_in_redirect_uri: string; - invitation_redirect_uri: string; +export type SigningKey = { + id: Uuid; + kid: string; + algorithm: 'RS256'; + status: 'active' | 'retiring' | 'retired'; + created_at: string; + retires_at?: string | null; }; -export type ApplicationAuthConfig = { - flows?: ApplicationFlowConfig; +export type SecretCredential = { + id?: Uuid; + client_id?: string; + secret_returned_once: boolean; + previous_secret_valid_for_seconds?: number; }; -export type ApplicationInternalConfig = { - registration_mode?: 'public' | 'invite_only'; - password_enabled?: boolean; - passwordless_enabled?: boolean; - personal_api_keys_enabled?: boolean; - delegation_enabled?: boolean; +export type ManagementClient = { + id: Uuid; + client_id: string; + name: string; + allowed_scopes: Array; + status: 'active' | 'disabled'; + created_at?: string; + updated_at?: string; }; -export type RuntimeAuthConfig = { - registration_mode: 'public' | 'invite_only'; - registration_enabled: boolean; - password_enabled: boolean; - passwordless_enabled: boolean; - flows?: ApplicationFlowConfig; +export type Organization = { + id: Uuid; + slug: string; + name: string; + version: number; + role?: string; + retired_at?: string | null; + created_at?: string; + updated_at?: string; }; -export type RuntimeConfig = { - schema_version: string; - api_base: string; - issuer: string; - application_id: Uuid; - public_config: { +export type Application = { + id: Uuid; + organization_id: Uuid; + slug: string; + name: string; + version: number; + issuer?: string; + audience?: string; + auth_config?: { [key: string]: unknown; }; - auth: RuntimeAuthConfig; - storage: RuntimeStorageConfig; + public_config?: { + [key: string]: unknown; + }; + internal_config?: { + [key: string]: unknown; + }; + retired_at?: string | null; + created_at?: string; + updated_at?: string; }; -export type PasswordSignIn = { - email: string; +export type ApplicationStatistics = { + users: { + total: number; + active: number; + suspended: number; + }; + workspaces: number; + active_products: number; + active_entitlements: number; + pending_local_requests: number; + live_subscriptions: number; + notification_failures: number; + webhook_failures: number; + events_last_24_hours: number; }; -export type PasswordSignUp = PasswordSignIn & { - first_name?: string; - last_name?: string; - locale?: Locale; +export type ApplicationDomain = { + id: Uuid; + hostname: string; + status: 'pending' | 'verified' | 'disabled'; + created_at?: string; }; -export type EmailStart = { - email: string; - intent: 'sign_in' | 'sign_up' | 'automatic'; - delivery: 'code' | 'link' | 'both'; - redirect_uri?: string; +export type OAuthClient = { + id: Uuid; + client_id: string; + name: string; + client_type: 'public' | 'confidential' | 'machine'; + redirect_uris?: Array; + post_logout_redirect_uris?: Array; + allowed_scopes?: Array; + allowed_grants?: Array; + secret_returned_once?: boolean; + created_at?: string; + updated_at?: string; }; -export type EmailVerify = { - challenge_id: Uuid; +export type Workspace = { + id: Uuid; + application_id?: Uuid; + owner_user_id: Uuid; + key: string; + name: string; + metadata: { + [key: string]: unknown; + }; + version: number; + created_at?: string; + updated_at?: string; }; -export type TokenResponse = { - token_type: 'Bearer'; - expires_in: number; +export type WorkspaceMember = { + workspace_id: Uuid; + user_id: Uuid; + role_keys: Array; + created_at?: string; + updated_at?: string; }; -export type User = { +export type RoleAssignmentRecord = { id: Uuid; - application_id: Uuid; - email: string; - first_name?: string; - last_name?: string; - username?: string | null; - locale: Locale; - email_verified: boolean; - is_org_verified: boolean; - status: 'active' | 'suspended' | 'pending_deletion' | 'anonymized' | 'deleted'; - custom_attributes?: { - [key: string]: unknown; - }; - version?: number; + user_id?: string | null; + client_id?: string | null; + role_id: Uuid; + workspace_id?: string | null; + created_at?: string; }; -export type UpdateUserProfile = { - first_name?: string; - last_name?: string; - username?: string | null; - locale?: Locale; +export type Delegation = { + id: Uuid; + user_id: Uuid; + workspace_id?: string | null; + scopes: Array; + reason: string; + status: 'pending' | 'exchanged' | 'revoked' | 'expired'; + expires_at: string; + created_at?: string; }; -export type QueueNotification = { - template_key: string; - /** - * Explicit locale override. When omitted - */ - locale?: Locale; - recipient?: string; - user_id?: Uuid; - variables?: { - [key: string]: unknown; - }; - attachments?: Array<{ - filename: string; - content_type: string; - content_base64: string; - }>; +export type ApplicationInvitation = { + id: Uuid; + application_id: Uuid; + workspace_id?: string | null; + email: string; + application_role_keys?: Array; + workspace_role_keys?: Array; + status: 'pending' | 'accepted' | 'revoked' | 'expired'; + link?: string; + expires_at: string; + accepted_user_id?: string | null; + created_at?: string; }; -export type QueuedNotification = { - id: Uuid; - status: 'queued' | 'suppressed'; - requested_locale: Locale; - resolved_locale: Locale; - fallback_used: boolean; +export type RevokedSessionCount = { + revoked_sessions: number; }; -export type RoleAssignment = unknown & { - user_id?: Uuid; - client_id?: Uuid; - role_id: Uuid; - workspace_id?: Uuid; +export type AuthMethods = { + methods: Array<'password' | 'email_code' | 'magic_link' | 'google' | 'apple' | 'totp' | 'webauthn'>; + registration_enabled: boolean; + registration_mode: 'public' | 'invite_only'; }; -export type OwnershipTransfer = { - new_owner_user_id: Uuid; - previous_owner_disposition?: 'member' | 'remove'; +export type WebAuthnChallenge = { + ceremony_id: Uuid; + options: { + [key: string]: unknown; + }; + expires_at: string; }; -export type OwnershipTransferResult = { - workspace_id: Uuid; - owner_user_id: Uuid; - previous_owner_user_id: Uuid; - previous_owner_disposition: 'member' | 'remove'; +export type InvitationExchangeResult = { + redirect_uri: string; + expires_in: number; + mfa_challenge_id?: string | null; }; -export type OperatorPasswordLogin = { - email: string; +export type PersonalApiKeyCreated = { + api_key: { + id: Uuid; + label: string; + token_prefix: string; + scopes: Array; + expires_at: string; + }; }; -export type OperatorPasswordChange = { - current_password?: string; - new_password: string; +export type Feature = { + id: Uuid; + key: string; + name: string; + value_type: 'boolean' | 'number' | 'string' | 'free_form'; + free_form_format?: 'text' | 'csv' | 'json' | null; + metadata: { + [key: string]: unknown; + }; + created_at?: string; + updated_at?: string; }; -export type CreateEventType = { +export type Product = { + id: Uuid; + key: string; name: string; - description?: string; - schema_version?: string; - /** - * JSON Schema 2020-12 with an object root. - */ - data_schema: { + description?: string | null; + listable: boolean; + status: 'active' | 'archived'; + metadata: { [key: string]: unknown; }; - example_subject: string; - /** - * Must validate against data_schema. - */ - example_data: { + entitlement_config: { [key: string]: unknown; }; + features: { + [key: string]: FeatureValue; + }; + version: number; + prices?: Array; + created_at?: string; + updated_at?: string; }; -export type UpdateEventType = { - description?: string; - schema_version?: string; - data_schema?: { +export type Price = { + id: Uuid; + product_id?: Uuid; + key: string; + mode: 'recurring' | 'one_time' | 'local'; + amount_minor?: number | null; + currency: string; + currency_exponent: number; + tax_behavior: 'inclusive' | 'exclusive' | 'unspecified'; + checkout_config: { [key: string]: unknown; }; - example_subject?: string; - example_data?: { + entitlement_config: { [key: string]: unknown; }; + features: { + [key: string]: FeatureValue; + }; status?: 'active' | 'archived'; + version?: number; + created_at?: string; }; -export type EventEnvelope = { - specversion: '1.0'; +export type EntitlementGrant = { id: Uuid; - source: string; - type: string; - contract_source: 'platform93' | 'application'; - time: string; - application_id: Uuid; - schema_version: string; - subject?: string | null; - actor?: { - [key: string]: unknown; - } | null; - correlation_id?: string | null; - causation_id?: string | null; - data: { + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + source_type: 'manual' | 'local_request' | 'subscription' | 'checkout'; + source_id?: string | null; + feature_values: { + [key: string]: FeatureValue; + }; + configuration: { [key: string]: unknown; }; + starts_at: string; + expires_at?: string | null; + revoked_at?: string | null; + external_reference?: string | null; + created_at?: string; }; -export type EventTypeDefinition = { +export type EffectiveEntitlements = { + workspace_id: string | null; + effective: { + [key: string]: FeatureValue; + }; + provenance: { + [key: string]: Array; + }; + sources: Array; +}; + +export type LocalEntitlementRequest = { id: Uuid; - name: string; - description: string; - schema_version: string; - data_schema: { + status: 'pending' | 'approved' | 'rejected' | 'cancelled'; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + product_snapshot: { [key: string]: unknown; }; - example_subject: string; - example_data: { + price_snapshot: { [key: string]: unknown; }; - example_event: EventEnvelope; - source: 'platform93' | 'application'; - status: 'active' | 'archived'; - version: number; - event_count?: number; - last_occurred_at?: string | null; + feature_snapshot: { + [key: string]: unknown; + }; + address_snapshot?: { + [key: string]: unknown; + } | null; + external_reference?: string | null; + entitlement_grant_id?: string | null; + reason?: string | null; created_at?: string; updated_at?: string; }; -export type PublishCustomEvent = { - type: string; - subject: string; - data: { - [key: string]: unknown; - }; - correlation_id?: Uuid; - causation_id?: Uuid; +export type LocalEntitlementApproval = { + status: 'approved'; + entitlement_grant_id: Uuid; }; -export type CreatePersonalApiKey = { - label?: string; - expires_in_days?: number; - scopes?: Array; +export type CheckoutSession = { + id: Uuid; + status: 'open' | 'complete' | 'expired'; + checkout_uri?: string | null; + provider_session_id?: string | null; + subject_type?: 'user' | 'workspace'; + subject_id?: Uuid; + external_reference?: string | null; + created_at?: string; + expires_at?: string | null; }; -export type CreateFeature = { - key: string; - name: string; - value_type: 'boolean' | 'quantity' | 'free_form'; - /** - * Required when value_type is free_form and forbidden otherwise. - */ - free_form_format?: 'text' | 'csv' | 'json'; - metadata?: { - [key: string]: unknown; - }; +export type PortalSession = { + provider_session_id: string; + portal_uri: string; }; -export type FeatureValue = { - feature_id: Uuid; - boolean_value?: boolean; - quantity_value?: number; - /** - * A string for text or CSV features, or any valid JSON value for JSON features. - */ - free_form_value?: unknown; +export type Subscription = { + id: Uuid; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + price_id: Uuid; + provider_id: Uuid; + provider_subscription_id?: string; + status: string; + current_period_start?: string | null; + current_period_end?: string | null; + cancel_at_period_end?: boolean; + external_reference?: string | null; + created_at?: string; + updated_at?: string; }; -export type CreateProduct = { - key: string; - name: string; - description?: string; - listable?: boolean; - status?: 'draft' | 'active' | 'archived'; - metadata?: { - [key: string]: unknown; - }; - entitlement_config?: { - [key: string]: unknown; - }; - features?: Array; +export type Invoice = { + id: Uuid; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + subscription_id?: string | null; + provider_invoice_id?: string; + status: string; + amount_due_minor: number; + amount_paid_minor?: number; + currency: string; + hosted_invoice_uri?: string | null; + external_reference?: string | null; + created_at?: string; }; -export type UpdateProduct = { - name?: string; - description?: string; - listable?: boolean; - status?: 'draft' | 'active' | 'archived'; - metadata?: { - [key: string]: unknown; - }; - entitlement_config?: { - [key: string]: unknown; - }; - features?: Array; +export type Payment = { + id: Uuid; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + invoice_id?: string | null; + provider_payment_id?: string; + status: string; + amount_minor: number; + currency: string; + external_reference?: string | null; + created_at?: string; }; -export type CreatePrice = { - key: string; - mode: 'recurring' | 'one_time' | 'local'; +export type Refund = { + id: Uuid; + payment_id?: Uuid; + provider_refund_id?: string; + status: string; amount_minor: number; currency: string; - currency_exponent?: number; - interval_unit?: 'day' | 'week' | 'month' | 'year'; - interval_count?: number; - validity_seconds?: number; - grace_seconds?: number; - tax_behavior?: 'inclusive' | 'exclusive' | 'unspecified'; - checkout_config?: { - [key: string]: unknown; - }; - entitlement_config?: { - [key: string]: unknown; + reason?: string | null; + external_reference?: string | null; + created_at?: string; +}; + +export type Dispute = { + id: Uuid; + payment_id?: string | null; + provider_dispute_id?: string; + status: string; + amount_minor: number; + currency: string; + reason?: string | null; + created_at?: string; +}; + +export type BillingStatistics = { + from: string; + to: string; + revenue_minor_by_currency: Array; + refunds_minor_by_currency: Array; + status_counts: { + [key: string]: { + [key: string]: number; + }; }; - features?: Array; }; -export type LocalCheckout = { - price_id: Uuid; - subject_type?: 'user' | 'workspace'; - subject_id?: Uuid; - address_id?: Uuid; - local_reference?: string; +export type CurrencyTotal = { + currency: string; + amount_minor: number; }; -export type CreateBillingProvider = { - provider: 'stripe'; - api_version?: '2026-04-22.dahlia'; - inheritable?: boolean; +export type BillingProviderEvent = { + id: Uuid; + provider_event_id: string; + event_type: string; + status: 'pending' | 'processed' | 'failed' | 'ignored'; + attempts?: number; + last_error?: string | null; + received_at: string; + processed_at?: string | null; }; -export type CreateCheckout = { +export type ReconciliationRun = { + id: Uuid; + provider_id: Uuid; + status: 'pending' | 'running' | 'completed' | 'failed'; + findings: number; + repairs: number; + last_error?: string | null; + started_at?: string | null; + completed_at?: string | null; + created_at: string; +}; + +export type BillingProfile = { + id: Uuid; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + name?: string | null; + email?: string | null; + tax_id?: string | null; + default_address_id?: string | null; + version: number; + created_at?: string; + updated_at?: string; +}; + +export type BillingSummary = { + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + billing_profile: BillingProfile | null; + subscriptions: Array; +}; + +export type Address = { + id: Uuid; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + name?: string | null; + line1: string; + line2?: string | null; + city: string; + region?: string | null; + postal_code: string; + country: string; + active: boolean; + version: number; + created_at?: string; + updated_at?: string; +}; + +export type AccountExport = { + exported_at: string; + user: User; + addresses: Array
; +}; + +export type MfaEnrollment = { + method_id: Uuid; + provisioning_uri: string; +}; + +export type MfaActivation = { + method_id: Uuid; + recovery_codes: Array; +}; + +export type RecoveryCodes = { + recovery_codes: Array; +}; + +export type MfaMethod = { + id: Uuid; + type: 'totp' | 'webauthn'; + name?: string | null; + status: 'pending' | 'active' | 'disabled'; + last_used_at?: string | null; + created_at: string; +}; + +export type ExternalIdentity = { + id: Uuid; + provider: 'google' | 'apple'; + email?: string | null; + created_at: string; + last_used_at?: string | null; +}; + +export type PermissionCheckResult = { + workspace_id: string | null; + results: { + [key: string]: boolean; + }; +}; + +export type AuditRecord = { + id: Uuid; + organization_id?: string | null; + application_id?: string | null; + actor_type: 'control_user' | 'user' | 'client' | 'system'; + actor_id?: string | null; + action: string; + target_type: string; + target_id?: string | null; + reason?: string | null; + request_id?: string | null; + changes?: { + [key: string]: unknown; + }; + created_at: string; +}; + +export type AuditExportRecord = { + id: Uuid; + record_count: number; + filters?: { + [key: string]: unknown; + }; + status?: 'pending' | 'ready' | 'expired' | 'failed'; + download_uri?: string | null; + expires_at: string; + created_at?: string; +}; + +export type Webhook = { + id: Uuid; + uri: string; + event_filters: Array; + secret_returned_once?: boolean; + disabled: boolean; + disabled_at?: string | null; + created_at?: string; + updated_at?: string; +}; + +export type WebhookDelivery = { + id: Uuid; + event_id: Uuid; + webhook_id: Uuid; + status: 'pending' | 'delivered' | 'failed' | 'dead'; + attempt_count: number; + response_status?: number | null; + last_error?: string | null; + next_attempt_at?: string | null; + created_at: string; + delivered_at?: string | null; +}; + +export type SenderIdentity = { + id: Uuid; + provider_id: Uuid; + email: string; + name: string; + is_default: boolean; + verified: boolean; + created_at?: string; +}; + +export type NotificationTemplate = { + id: Uuid; + application_id?: string | null; + key: string; + locale: Locale; + category: string; + subject_template?: string; + text_template?: string; + html_template?: string | null; + version: number; + status: 'draft' | 'active' | 'archived'; + created_at?: string; + updated_at?: string; +}; + +export type TemplateVariables = { + protected: Array; + optional: Array; +}; + +export type NotificationTemplatePreview = { + template_id: Uuid; + version: number; + subject: string; + text: string; + html: string | null; +}; + +export type NotificationStatistics = { + notification_status_counts: { + [key: string]: number; + }; + attempts_delivered: number; + attempts_failed: number; +}; + +export type Notification = { + id: Uuid; + template_key: string; + recipient: string; + locale?: Locale; + status: 'queued' | 'sending' | 'delivered' | 'failed' | 'suppressed' | 'dead'; + attempt_count?: number; + last_error?: string | null; + created_at: string; + delivered_at?: string | null; +}; + +export type NotificationPreference = { + category: string; + email_enabled: boolean; + updated_at?: string; +}; + +export type StorageProvider = { + id: Uuid; + provider: 's3'; + scope: 'installation' | 'organization' | 'application'; + organization_id?: string | null; + application_id?: string | null; + name: string; + endpoint: string; + region: string; + force_path_style: boolean; + public_bucket?: string | null; + private_bucket?: string | null; + public_base_url?: string | null; + status: 'active' | 'disabled' | 'unverified' | 'error'; + inheritable: boolean; + credentials_configured: boolean; + allow_private_endpoint: boolean; + verified_at?: string | null; + disabled_at?: string | null; + last_error?: string | null; + max_object_bytes: number; + max_email_image_bytes: number; + max_application_bytes: number; + max_application_objects: number; + version: number; + created_at?: string; + updated_at?: string; +}; + +export type StorageProviderStatus = { + id: Uuid; + status: 'active' | 'disabled' | 'unverified' | 'error'; +}; + +export type StorageDownload = { + url: string; + expires_at: string; + visibility: 'public' | 'private'; +}; + +export type OidcDiscovery = { + issuer: string; + authorization_endpoint: string; + token_endpoint: string; + userinfo_endpoint?: string; + revocation_endpoint?: string; + introspection_endpoint?: string; + jwks_uri: string; + response_types_supported: Array; + grant_types_supported?: Array; + subject_types_supported: Array; + id_token_signing_alg_values_supported: Array; + code_challenge_methods_supported?: Array; + scopes_supported?: Array; +}; + +export type Jwks = { + keys: Array<{ + kty: string; + kid: string; + use: string; + alg: string; + n: string; + e: string; + }>; +}; + +export type AuthorizationRedirect = { + redirect_to: string; +}; + +export type TokenIntrospection = { + active: boolean; + sub?: string; + aud?: string | Array; + iss?: string; + exp?: number; + iat?: number; + scope?: string; + client_id?: string; + token_type?: string; + actor_type?: 'control_user' | 'user' | 'client'; + application_id?: string; + roles?: StructuredRoles; +}; + +export type UserInfo = { + sub: string; + application_id: Uuid; + actor_type: 'user' | 'client'; + email?: string; + email_verified?: boolean; + given_name?: string; + family_name?: string; + locale?: Locale; + scope?: string; + roles?: StructuredRoles; + custom_claims?: { + [key: string]: unknown; + }; +}; + +export type WebhookAcknowledgement = { + received: boolean; +}; + +export type OrganizationMember = { + control_user_id: Uuid; + email: string; + display_name: string; + role: 'owner' | 'admin' | 'member' | 'auditor'; + status: 'active' | 'suspended' | 'deleted'; + joined_at?: string; +}; + +export type PersonalApiKey = { + id: Uuid; + label: string; + token_prefix: string; + scopes: Array; + status: 'active' | 'revoked' | 'expired'; + last_used_at?: string | null; + expires_at: string; + created_at?: string; +}; + +export type OAuthConsent = { + id: Uuid; + client_id: string; + client_name?: string; + scopes: Array; + created_at: string; + updated_at?: string; +}; + +export type WorkspaceAccessEntry = { + type: 'owner' | 'member' | 'invitation'; + workspace_id: Uuid; + user_id?: string | null; + email?: string | null; + role_keys?: Array; + invitation_id?: string | null; + status?: string; + expires_at?: string | null; +}; + +export type EmptyResponse = { + [key: string]: never; +}; + +export type SessionPage = { + items: Array; + next_cursor: string | null; +}; + +export type NotificationProviderPage = { + items: Array; + next_cursor: string | null; +}; + +export type AuthProviderPage = { + items: Array; + next_cursor: string | null; +}; + +export type BillingProviderPage = { + items: Array; + next_cursor: string | null; +}; + +export type ControlUserPage = { + items: Array; + next_cursor: string | null; +}; + +export type ControlUserInvitationPage = { + items: Array; + next_cursor: string | null; +}; + +export type SigningKeyPage = { + items: Array; + next_cursor: string | null; +}; + +export type ManagementClientPage = { + items: Array; + next_cursor: string | null; +}; + +export type ApplicationPage = { + items: Array; + next_cursor: string | null; +}; + +export type OrganizationMemberPage = { + items: Array; + next_cursor: string | null; +}; + +export type ApplicationDomainPage = { + items: Array; + next_cursor: string | null; +}; + +export type OAuthClientPage = { + items: Array; + next_cursor: string | null; +}; + +export type RolePage = { + items: Array; + next_cursor: string | null; +}; + +export type WorkspacePage = { + items: Array; + next_cursor: string | null; +}; + +export type WorkspaceMemberPage = { + items: Array; + next_cursor: string | null; +}; + +export type RoleAssignmentPage = { + items: Array; + next_cursor: string | null; +}; + +export type PermissionGrantPage = { + items: Array; + next_cursor: string | null; +}; + +export type DelegationPage = { + items: Array; + next_cursor: string | null; +}; + +export type ApplicationInvitationPage = { + items: Array; + next_cursor: string | null; +}; + +export type UserPage = { + items: Array; + next_cursor: string | null; +}; + +export type EntitlementGrantPage = { + items: Array; + next_cursor: string | null; +}; + +export type AddressPage = { + items: Array
; + next_cursor: string | null; +}; + +export type OAuthConsentPage = { + items: Array; + next_cursor: string | null; +}; + +export type FeaturePage = { + items: Array; + next_cursor: string | null; +}; + +export type ProductPage = { + items: Array; + next_cursor: string | null; +}; + +export type PricePage = { + items: Array; + next_cursor: string | null; +}; + +export type LocalEntitlementRequestPage = { + items: Array; + next_cursor: string | null; +}; + +export type SubscriptionPage = { + items: Array; + next_cursor: string | null; +}; + +export type InvoicePage = { + items: Array; + next_cursor: string | null; +}; + +export type PaymentPage = { + items: Array; + next_cursor: string | null; +}; + +export type RefundPage = { + items: Array; + next_cursor: string | null; +}; + +export type DisputePage = { + items: Array; + next_cursor: string | null; +}; + +export type BillingProviderEventPage = { + items: Array; + next_cursor: string | null; +}; + +export type ReconciliationRunPage = { + items: Array; + next_cursor: string | null; +}; + +export type MfaMethodPage = { + items: Array; + next_cursor: string | null; +}; + +export type ExternalIdentityPage = { + items: Array; + next_cursor: string | null; +}; + +export type WorkspaceAccessPage = { + items: Array; + next_cursor: string | null; +}; + +export type EventPage = { + items: Array; + next_cursor: string | null; +}; + +export type EventTypePage = { + items: Array; + next_cursor: string | null; +}; + +export type AuditRecordPage = { + items: Array; + next_cursor: string | null; +}; + +export type WebhookPage = { + items: Array; + next_cursor: string | null; +}; + +export type WebhookDeliveryPage = { + items: Array; + next_cursor: string | null; +}; + +export type SenderIdentityPage = { + items: Array; + next_cursor: string | null; +}; + +export type NotificationTemplatePage = { + items: Array; + next_cursor: string | null; +}; + +export type NotificationPage = { + items: Array; + next_cursor: string | null; +}; + +export type NotificationPreferencePage = { + items: Array; + next_cursor: string | null; +}; + +export type StorageProviderPage = { + items: Array; + next_cursor: string | null; +}; + +export type StorageObjectPage = { + items: Array; + next_cursor: string | null; +}; + +export type PersonalApiKeyPage = { + items: Array; + next_cursor: string | null; +}; + +export type CompleteSetup = { + password?: string; +}; + +export type ControlEmailStart = { + email: string; + delivery?: 'code' | 'link' | 'both'; +}; + +export type UpdateControlUserAccount = { + display_name: string; +}; + +export type ControlInvitationProviderStart = { + invitation_token: string; +}; + +export type UpdateControlInvitationMethod = { + onboarding_method?: 'email' | 'google' | 'apple'; +}; + +export type UpdateManagementApi = { + enabled: boolean; +}; + +export type RefreshToken = { + refresh_token: string; +}; + +export type ConfigureAuthProvider = { + client_id: string; + team_id?: string; + key_id?: string; + inheritable?: boolean; + control_login_enabled?: boolean; +}; + +export type UpdateSmtpProvider = { + name?: string; + host?: string; + port?: number; + username?: string; + tls_mode?: 'starttls' | 'implicit_tls'; + sender_email?: string; + sender_name?: string; + inheritable?: boolean; +}; + +export type TestNotificationProvider = { + recipient: string; +}; + +export type UpdateBillingProvider = { + metadata?: { + [key: string]: unknown; + }; + inheritable?: boolean; +}; + +export type MembershipRole = { + role: 'owner' | 'admin' | 'member' | 'auditor'; +}; + +export type CreateApplicationDomain = { + hostname: string; +}; + +export type CreateClient = { + client_id: string; + name: string; + client_type: 'public' | 'confidential'; + redirect_uris?: Array; + allowed_grants?: Array<'authorization_code' | 'refresh_token' | 'client_credentials'>; + allowed_scopes?: Array; +}; + +export type UpdateClient = { + name?: string; + redirect_uris?: Array; + allowed_grants?: Array<'authorization_code' | 'refresh_token' | 'client_credentials'>; + allowed_scopes?: Array; +}; + +export type CreateWorkspace = { + key: string; + name: string; + owner_user_id?: Uuid; + metadata?: { + [key: string]: unknown; + }; +}; + +export type UpdateWorkspace = { + name?: string; + metadata?: { + [key: string]: unknown; + }; +}; + +export type ReplaceWorkspaceMemberRoles = { + role_keys: Array; +}; + +export type CreateDelegation = { + user_id: Uuid; + workspace_id?: Uuid; + reason: string; + redirect_uri: string; + permissions: Array; + expires_in?: number; +}; + +export type ExchangeDelegation = { + exchange_code: string; +}; + +export type CreateUser = { + email: string; + first_name?: string; + last_name?: string; + username?: string | null; + locale?: Locale; + email_verified?: boolean; + is_org_verified?: boolean; + custom_attributes?: { + [key: string]: unknown; + }; +}; + +export type UpdateUser = { + first_name?: string; + last_name?: string; + username?: string | null; + locale?: Locale; + status?: 'active' | 'suspended' | 'pending_deletion'; + email_verified?: boolean; + is_org_verified?: boolean; + custom_attributes?: { + [key: string]: unknown; + }; + reason?: string; +}; + +export type AuditReason = { + reason: string; +}; + +export type PasswordResetStart = { + email: string; +}; + +export type PasswordResetVerify = { + challenge_id: Uuid; +}; + +export type ExternalAuthStartRequest = { + flow?: 'sign_in' | 'sign_up' | 'automatic' | 'link'; + redirect_uri: string; + login_hint?: string; +}; + +export type ExternalAuthExchange = { + exchange: string; +}; + +export type VerifyMfa = unknown & { + challenge_id: Uuid; +}; + +export type BeginWebAuthnAuthentication = { + challenge_id: Uuid; + origin?: string; +}; + +export type BeginWebAuthnRegistration = { + origin?: string; + label?: string; +}; + +export type FinishWebAuthnCeremony = { + ceremony_id: Uuid; + credential: { + [key: string]: unknown; + }; +}; + +export type CreateEntitlement = { + subject_type: 'user' | 'workspace'; + subject_id: Uuid; + product_id?: Uuid; + price_id?: Uuid; + feature_values?: { + [key: string]: unknown; + }; + configuration?: { + [key: string]: unknown; + }; + starts_at?: string; + expires_at?: string; + reason?: string; + external_reference?: string; +}; + +export type AdjustEntitlement = { + expires_at?: string | null; + reason?: string; +}; + +export type CreatePortalSession = { + provider_id: Uuid; + subject_type?: 'user' | 'workspace'; + subject_id?: Uuid; + return_uri: string; +}; + +export type CancelSubscription = { + at_period_end?: boolean; +}; + +export type ChangeSubscriptionPrice = { + price_id: Uuid; + proration_behavior?: 'create_prorations' | 'always_invoice' | 'none'; +}; + +export type CreateRefund = { + amount_minor?: number; + reason?: string; +}; + +export type AccountChallenge = { + challenge_id: Uuid; +}; + +export type EmailAddress = { + email: string; +}; + +export type PasswordChange = { + current_password: string; + new_password: string; +}; + +export type StartTotp = { + label?: string; +}; + +export type ActivateTotp = { + code: string; +}; + +export type CreateAddress = { + name: string; + line1: string; + line2?: string; + city: string; + region?: string; + postal_code: string; + country_code: string; + tax_id?: string | null; + active?: boolean; +}; + +export type UpdateAddress = { + name?: string; + line1?: string; + line2?: string; + city?: string; + region?: string; + postal_code?: string; + country_code?: string; + tax_id?: string | null; + version: number; +}; + +export type UpdateBillingProfile = { + name?: string; + email?: string; + tax_id?: string; + version: number; +}; + +export type PermissionCheck = { + permissions: Array; + workspace_id?: Uuid; +}; + +export type AuditExport = { + start?: string; + end?: string; + actor_type?: 'control_user' | 'user' | 'client' | 'system'; + action?: string; + target_type?: string; +}; + +export type CreateWebhook = { + uri: string; + event_filters?: Array; +}; + +export type UpdateWebhook = { + uri?: string; + event_filters?: Array; + enabled?: boolean; +}; + +export type CreateSenderIdentity = { + provider_id: Uuid; + email: string; + name?: string; + is_default?: boolean; +}; + +export type CreateNotificationTemplate = { + key: string; + locale?: Locale; + category: 'security' | 'billing' | 'transactional' | 'marketing'; + subject_template: string; + text_template: string; + html_template?: string; + variable_schema?: { + [key: string]: unknown; + }; +}; + +export type UpdateNotificationTemplate = { + category?: 'security' | 'billing' | 'transactional' | 'marketing'; + subject_template?: string; + text_template?: string; + html_template?: string; + variable_schema?: { + [key: string]: unknown; + }; +}; + +export type PreviewNotificationTemplate = { + variables: { + [key: string]: unknown; + }; + user_id?: Uuid; + recipient?: string; +}; + +export type UpdateNotificationPreference = { + email_enabled: boolean; +}; + +export type UpdateStorageProvider = { + name?: string; + endpoint?: string; + region?: string; + force_path_style?: boolean; + public_bucket?: string; + private_bucket?: string; + public_base_url?: string; + inheritable?: boolean; + allow_private_endpoint?: boolean; + max_object_bytes?: number; + max_email_image_bytes?: number; + max_application_bytes?: number; + max_application_objects?: number; +}; + +export type ManagementApiStatus = { + enabled: boolean; + can_manage: boolean; + active_clients: number; + token_endpoint: string; + api_base: string; +}; + +export type CreateManagementClient = { + client_id: string; + name: string; + allowed_scopes?: Array<'/management/organizations/*'>; +}; + +export type OrganizationEnabledSettings = { + public_registration: boolean; + password_authentication: boolean; + passwordless_authentication: boolean; + personal_api_keys: boolean; + delegation: boolean; + organization_provider_overrides: boolean; + application_provider_overrides: boolean; + custom_events: boolean; + webhooks: boolean; +}; + +export type UpdateOrganizationPolicy = { + /** + * Null means unlimited. + */ + max_applications: number | null; + /** + * Null means unlimited across all applications in the organization. + */ + max_users: number | null; + enabled_settings: OrganizationEnabledSettings; +}; + +export type OrganizationPolicy = { + /** + * Null means unlimited. + */ + max_applications: number | null; + /** + * Null means unlimited across all applications in the organization. + */ + max_users: number | null; + enabled_settings: OrganizationEnabledSettings; + organization_id: Uuid; + usage: { + applications: number; + users: number; + }; + version: number; +}; + +export type Uuid = string; + +export type CreateStorageProvider = unknown & { + name: string; + endpoint: string; + region: string; + force_path_style?: boolean; + public_bucket?: string; + private_bucket?: string; + public_base_url?: string; + inheritable?: boolean; + /** + * Installation-scoped opt-in for local or private-network S3 endpoints. + */ + allow_private_endpoint?: boolean; + max_object_bytes?: number; + max_email_image_bytes?: number; + max_application_bytes?: number; + max_application_objects?: number; +}; + +export type CreateStorageUpload = { + filename: string; + content_type: string; + size_bytes: number; + visibility: 'public' | 'private'; + purpose?: 'email_image'; + metadata?: { + [key: string]: unknown; + }; +}; + +export type StorageObject = { + id: Uuid; + application_id?: string | null; + provider_id: Uuid; + owner_type: 'installation' | 'application' | 'user' | 'workspace'; + owner_id?: string | null; + visibility: 'public' | 'private'; + filename: string; + content_type: string; + size_bytes: number; + etag?: string | null; + metadata: { + [key: string]: unknown; + }; + status: 'pending' | 'ready' | 'deleting' | 'failed'; + public_url?: string | null; + upload_expires_at?: string | null; + ready_at?: string | null; + last_error?: string | null; + version: number; + created_at: string; + updated_at: string; +}; + +export type StorageUploadAuthorization = { + object: StorageObject; + upload_expires_at: string; + required_headers: { + [key: string]: string; + }; +}; + +export type RuntimeStorageConfig = { + public_uploads_enabled: boolean; + private_uploads_enabled: boolean; + max_public_object_bytes?: number; + max_private_object_bytes?: number; + max_email_image_bytes?: number; + public_provider_scope?: 'installation' | 'organization' | 'application'; + private_provider_scope?: 'installation' | 'organization' | 'application'; +}; + +/** + * Canonical BCP 47 language tag such as en, de-CH, or pt-BR. Empty means no user preference. + */ +export type Locale = string; + +export type Problem = { + type: string; + title: string; + status: number; + detail?: string; + code: string; + request_id?: string; + affected_users?: number; +}; + +export type OrganizationPage = { + items: Array; + next_cursor: string | null; + /** + * The current Platform user's installation-wide role, or null for organization-only access. + */ + installation_role?: 'owner' | 'admin' | 'auditor' | null; +}; + +export type BootstrapRequest = { + email: string; + display_name?: string; +}; + +export type AcceptControlUserInvitation = { + display_name?: string; +}; + +export type CreateControlUserInvitation = { + email: string; + role: 'owner' | 'admin' | 'member' | 'auditor'; + onboarding_method?: 'email' | 'google' | 'apple'; + expires_in?: number; +}; + +export type ControlAuthPolicy = { + email_code_enabled: boolean; + magic_link_enabled: boolean; + password_enabled: boolean; +}; + +export type UpdateControlAuthPolicy = { + email_code_enabled: boolean; + magic_link_enabled: boolean; + password_enabled: boolean; + confirm_affected_users?: boolean; +}; + +export type ControlAuthMethods = { + email_code: boolean; + magic_link: boolean; + password: boolean; + providers: Array<'google' | 'apple'>; +}; + +export type ExternalAuthStart = { + provider: 'google' | 'apple'; + authorize_url: string; + expires_in: number; +}; + +export type UpdateInstallationAuthProvider = { + inheritable?: boolean; + control_login_enabled?: boolean; + confirm_affected_users?: boolean; +}; + +export type ApplicationFlowConfig = { + oauth_client_id: string; + /** + * Exact registered HTTPS, loopback HTTP, or public-client native application redirect URI. + */ + sign_in_redirect_uri: string; + /** + * Invitation destination using the same origin or native scheme authority as the sign-in redirect. + */ + invitation_redirect_uri: string; +}; + +export type ApplicationAuthConfig = { + flows?: ApplicationFlowConfig; +}; + +export type ApplicationInternalConfig = { + registration_mode?: 'public' | 'invite_only'; + password_enabled?: boolean; + passwordless_enabled?: boolean; + personal_api_keys_enabled?: boolean; + delegation_enabled?: boolean; + user_invitations_enabled?: boolean; + custom_token_claim_keys?: Array; +}; + +export type RuntimeAuthConfig = { + registration_mode: 'public' | 'invite_only'; + registration_enabled: boolean; + password_enabled: boolean; + passwordless_enabled: boolean; + flows?: ApplicationFlowConfig; +}; + +export type RuntimeConfig = { + schema_version: string; + api_base: string; + issuer: string; + application_id: Uuid; + public_config: { + [key: string]: unknown; + }; + auth: RuntimeAuthConfig; + storage: RuntimeStorageConfig; +}; + +export type PasswordSignIn = { + email: string; +}; + +export type PasswordSignUp = { + email: string; + first_name?: string; + last_name?: string; + locale?: Locale; +}; + +export type EmailStart = { + email: string; + intent: 'sign_in' | 'sign_up' | 'automatic'; + delivery: 'code' | 'link' | 'both'; + redirect_uri?: string; +}; + +export type EmailVerify = { + challenge_id: Uuid; +}; + +export type TokenResponse = { + token_type: 'Bearer'; + expires_in: number; +}; + +export type User = { + id: Uuid; + application_id: Uuid; + email: string; + first_name?: string; + last_name?: string; + username?: string | null; + locale: Locale; + email_verified: boolean; + is_org_verified: boolean; + status: 'active' | 'suspended' | 'pending_deletion' | 'anonymized' | 'deleted'; + custom_attributes?: { + [key: string]: unknown; + }; + version?: number; +}; + +export type UpdateUserProfile = { + first_name?: string; + last_name?: string; + username?: string | null; + locale?: Locale; +}; + +export type QueueNotification = { + template_key: string; + /** + * Explicit locale override. When omitted + */ + locale?: Locale; + recipient?: string; + user_id?: Uuid; + variables?: { + [key: string]: unknown; + }; + attachments?: Array<{ + filename: string; + content_type: string; + content_base64: string; + }>; +}; + +export type QueuedNotification = { + id: Uuid; + status: 'queued' | 'suppressed'; + requested_locale: Locale; + resolved_locale: Locale; + fallback_used: boolean; +}; + +export type CreateInvitation = { + email: string; + workspace_id?: Uuid; + application_role_keys?: Array; + workspace_role_keys?: Array; + expires_in?: number; +}; + +export type ExchangeInvitation = unknown & { + invitation_id?: Uuid; + email?: string; +}; + +export type RedeemInvitation = { + authorization_code: string; + code_verifier: string; +}; + +export type RoleAssignment = unknown & { + user_id?: Uuid; + client_id?: Uuid; + role_id: Uuid; + workspace_id?: Uuid; +}; + +export type PermissionKey = string; + +export type RoleKey = string; + +export type CreateRole = { + key: RoleKey; + name: string; + scope: 'application' | 'workspace'; + permissions: Array; +}; + +export type UpdateRole = { + name?: string; + permissions?: Array; +}; + +export type Role = { + key: RoleKey; + name: string; + scope: 'application' | 'workspace'; + permissions: Array; + id: Uuid; + built_in: boolean; + version: number; +}; + +export type StructuredRoles = { + application: Array; + workspaces: { + [key: string]: Array; + }; +}; + +export type CreatePermissionGrant = { + subject_type: 'user' | 'client'; + subject_id: Uuid; + workspace_id?: Uuid; + permission: PermissionKey; + reason?: string; +}; + +export type PermissionGrant = { + subject_type: 'user' | 'client'; + subject_id: Uuid; + workspace_id?: Uuid; + permission: PermissionKey; + reason?: string; + id: Uuid; + application_id: Uuid; + canonical_scope: string; + status: 'active' | 'revoked'; + version: number; + created_at: string; + revoked_at?: string | null; +}; + +export type EffectiveAccess = { + subject_type: 'user' | 'client'; + subject_id: Uuid; + roles: StructuredRoles; + scopes: Array; + provenance: Array<{ + scope: string; + source: 'role_marker' | 'role' | 'direct' | 'workspace_owner'; + role_key?: RoleKey; + grant_id?: Uuid; + workspace_id?: Uuid; + permission?: PermissionKey; + }>; +}; + +export type OwnershipTransfer = { + new_owner_user_id: Uuid; + previous_owner_disposition?: 'member' | 'remove'; +}; + +export type OwnershipTransferResult = { + workspace_id: Uuid; + owner_user_id: Uuid; + previous_owner_user_id: Uuid; + previous_owner_disposition: 'member' | 'remove'; +}; + +export type ControlUserPasswordLogin = { + email: string; +}; + +export type ControlUserPasswordChange = { + current_password?: string; + new_password: string; +}; + +export type CreateEventType = { + name: string; + description?: string; + schema_version?: string; + /** + * JSON Schema 2020-12 with an object root. + */ + data_schema: { + [key: string]: unknown; + }; + example_subject: string; + /** + * Must validate against data_schema. + */ + example_data: { + [key: string]: unknown; + }; +}; + +export type UpdateEventType = { + description?: string; + schema_version?: string; + data_schema?: { + [key: string]: unknown; + }; + example_subject?: string; + example_data?: { + [key: string]: unknown; + }; + status?: 'active' | 'archived'; +}; + +export type EventEnvelope = { + specversion: '1.0'; + id: Uuid; + source: string; + type: string; + contract_source: 'platform93' | 'application'; + time: string; + application_id: Uuid; + schema_version: string; + subject?: string | null; + actor?: { + [key: string]: unknown; + } | null; + correlation_id?: string | null; + causation_id?: string | null; + data: { + [key: string]: unknown; + }; +}; + +export type EventTypeDefinition = { + id: Uuid; + name: string; + description: string; + schema_version: string; + data_schema: { + [key: string]: unknown; + }; + example_subject: string; + example_data: { + [key: string]: unknown; + }; + example_event: EventEnvelope; + source: 'platform93' | 'application'; + status: 'active' | 'archived'; + version: number; + event_count?: number; + last_occurred_at?: string | null; + created_at?: string; + updated_at?: string; +}; + +export type PublishCustomEvent = { + type: string; + subject: string; + data: { + [key: string]: unknown; + }; + correlation_id?: Uuid; + causation_id?: Uuid; +}; + +export type CreatePersonalApiKey = { + label?: string; + expires_in_days?: number; + scopes?: Array; +}; + +export type CreateFeature = { + key: string; + name: string; + value_type: 'boolean' | 'quantity' | 'free_form'; + /** + * Required when value_type is free_form and forbidden otherwise. + */ + free_form_format?: 'text' | 'csv' | 'json'; + metadata?: { + [key: string]: unknown; + }; +}; + +export type FeatureValue = { + feature_id: Uuid; + boolean_value?: boolean; + quantity_value?: number; + /** + * A string for text or CSV features, or any valid JSON value for JSON features. + */ + free_form_value?: unknown; +}; + +export type CreateProduct = { + key: string; + name: string; + description?: string; + listable?: boolean; + status?: 'draft' | 'active' | 'archived'; + metadata?: { + [key: string]: unknown; + }; + entitlement_config?: { + [key: string]: unknown; + }; + features?: Array; +}; + +export type UpdateProduct = { + name?: string; + description?: string; + listable?: boolean; + status?: 'draft' | 'active' | 'archived'; + metadata?: { + [key: string]: unknown; + }; + entitlement_config?: { + [key: string]: unknown; + }; + features?: Array; +}; + +export type CreatePrice = { + key: string; + mode: 'recurring' | 'one_time' | 'local'; + amount_minor: number; + currency: string; + currency_exponent?: number; + interval_unit?: 'day' | 'week' | 'month' | 'year'; + interval_count?: number; + validity_seconds?: number; + grace_seconds?: number; + tax_behavior?: 'inclusive' | 'exclusive' | 'unspecified'; + checkout_config?: { + [key: string]: unknown; + }; + entitlement_config?: { + [key: string]: unknown; + }; + features?: Array; +}; + +export type LocalCheckout = { + price_id: Uuid; + subject_type?: 'user' | 'workspace'; + subject_id?: Uuid; + address_id?: Uuid; + external_reference?: string; +}; + +export type CreateBillingProvider = { + provider: 'stripe'; + api_version?: '2026-04-22.dahlia'; + inheritable?: boolean; +}; + +export type CreateCheckout = { price_id: Uuid; /** - * Optional provider pin; omission resolves the effective application + * Optional provider pin; omission resolves the effective application + */ + provider_id?: Uuid; + subject_type?: 'user' | 'workspace'; + subject_id?: Uuid; + payment_methods?: Array<'card' | 'twint'>; + success_uri: string; + cancel_uri: string; + external_reference?: string; +}; + +export type SetupSessionWritable = { + access_token: string; + refresh_token: string; + token_type: 'Bearer'; + expires_in: number; + control_user_id: Uuid; +}; + +export type SetupCompletionWritable = { + access_token: string; + refresh_token: string; + token_type: 'Bearer'; + expires_in: number; + completed: true; +}; + +export type ControlUserInvitationWritable = { + id: Uuid; + organization_id?: string | null; + email: string; + role: 'owner' | 'admin' | 'member' | 'auditor'; + onboarding_method: 'email' | 'google' | 'apple'; + status?: 'pending' | 'accepted' | 'revoked' | 'expired'; + expires_at: string; + invitation_token?: string; + token_returned_once?: boolean; + invited_by?: string; + accepted_by?: string | null; + accepted_at?: string | null; + revoked_at?: string | null; + created_at?: string; + updated_at?: string; +}; + +export type SecretCredentialWritable = { + id?: Uuid; + client_id?: string; + secret: string; + secret_returned_once: boolean; + previous_secret_valid_for_seconds?: number; +}; + +export type OAuthClientWritable = { + id: Uuid; + client_id: string; + name: string; + client_type: 'public' | 'confidential' | 'machine'; + redirect_uris?: Array; + post_logout_redirect_uris?: Array; + allowed_scopes?: Array; + allowed_grants?: Array; + client_secret?: string | null; + secret?: string; + secret_returned_once?: boolean; + created_at?: string; + updated_at?: string; +}; + +export type DelegationWritable = { + id: Uuid; + user_id: Uuid; + workspace_id?: string | null; + scopes: Array; + reason: string; + status: 'pending' | 'exchanged' | 'revoked' | 'expired'; + exchange_code?: string; + expires_at: string; + created_at?: string; +}; + +export type ApplicationInvitationWritable = { + id: Uuid; + application_id: Uuid; + workspace_id?: string | null; + email: string; + application_role_keys?: Array; + workspace_role_keys?: Array; + status: 'pending' | 'accepted' | 'revoked' | 'expired'; + code?: string; + link_token?: string; + link?: string; + expires_at: string; + accepted_user_id?: string | null; + created_at?: string; +}; + +export type InvitationExchangeResultWritable = { + authorization_code: string; + redirect_uri: string; + expires_in: number; + mfa_challenge_id?: string | null; +}; + +export type PersonalApiKeyCreatedWritable = { + token: string; + api_key: { + id: Uuid; + label: string; + token_prefix: string; + scopes: Array; + expires_at: string; + }; +}; + +export type MfaEnrollmentWritable = { + method_id: Uuid; + secret: string; + provisioning_uri: string; +}; + +export type MfaActivationWritable = { + method_id: Uuid; + recovery_codes: Array; +}; + +export type RecoveryCodesWritable = { + recovery_codes: Array; +}; + +export type WebhookWritable = { + id: Uuid; + uri: string; + event_filters: Array; + secret?: string; + secret_returned_once?: boolean; + disabled: boolean; + disabled_at?: string | null; + created_at?: string; + updated_at?: string; +}; + +export type ControlUserInvitationPageWritable = { + items: Array; + next_cursor: string | null; +}; + +export type OAuthClientPageWritable = { + items: Array; + next_cursor: string | null; +}; + +export type DelegationPageWritable = { + items: Array; + next_cursor: string | null; +}; + +export type ApplicationInvitationPageWritable = { + items: Array; + next_cursor: string | null; +}; + +export type WebhookPageWritable = { + items: Array; + next_cursor: string | null; +}; + +export type ConfigureAuthProviderWritable = { + client_id: string; + client_secret?: string; + team_id?: string; + key_id?: string; + private_key_pem?: string; + inheritable?: boolean; + control_login_enabled?: boolean; +}; + +export type UpdateSmtpProviderWritable = { + name?: string; + host?: string; + port?: number; + username?: string; + password?: string; + tls_mode?: 'starttls' | 'implicit_tls'; + sender_email?: string; + sender_name?: string; + inheritable?: boolean; +}; + +export type UpdateBillingProviderWritable = { + secret?: string; + webhook_secret?: string; + metadata?: { + [key: string]: unknown; + }; + inheritable?: boolean; +}; + +export type CreateUserWritable = { + email: string; + password?: string; + first_name?: string; + last_name?: string; + username?: string | null; + locale?: Locale; + email_verified?: boolean; + is_org_verified?: boolean; + custom_attributes?: { + [key: string]: unknown; + }; +}; + +export type PasswordResetVerifyWritable = { + challenge_id: Uuid; + code?: string; + link_token?: string; + password: string; +}; + +export type VerifyMfaWritable = unknown & { + challenge_id: Uuid; + code?: string; + recovery_code?: string; +}; + +export type AccountChallengeWritable = { + challenge_id: Uuid; + code?: string; + link_token?: string; +}; + +export type UpdateStorageProviderWritable = { + name?: string; + endpoint?: string; + region?: string; + access_key_id?: string; + secret_access_key?: string; + force_path_style?: boolean; + public_bucket?: string; + private_bucket?: string; + public_base_url?: string; + inheritable?: boolean; + allow_private_endpoint?: boolean; + max_object_bytes?: number; + max_email_image_bytes?: number; + max_application_bytes?: number; + max_application_objects?: number; +}; + +export type CreateStorageProviderWritable = unknown & { + name: string; + endpoint: string; + region: string; + access_key_id: string; + secret_access_key: string; + force_path_style?: boolean; + public_bucket?: string; + private_bucket?: string; + public_base_url?: string; + inheritable?: boolean; + /** + * Installation-scoped opt-in for local or private-network S3 endpoints. + */ + allow_private_endpoint?: boolean; + max_object_bytes?: number; + max_email_image_bytes?: number; + max_application_bytes?: number; + max_application_objects?: number; +}; + +export type StorageUploadAuthorizationWritable = { + object: StorageObject; + upload_url: string; + upload_expires_at: string; + required_headers: { + [key: string]: string; + }; +}; + +export type BootstrapRequestWritable = { + credential: string; + email: string; + display_name?: string; +}; + +export type AcceptControlUserInvitationWritable = { + invitation_token: string; + display_name?: string; +}; + +export type PasswordSignInWritable = { + email: string; + password: string; +}; + +export type PasswordSignUpWritable = { + email: string; + password: string; + first_name?: string; + last_name?: string; + locale?: Locale; +}; + +export type EmailVerifyWritable = { + challenge_id: Uuid; + code?: string; + link_token?: string; +}; + +export type TokenResponseWritable = { + access_token: string; + refresh_token: string; + token_type: 'Bearer'; + expires_in: number; +}; + +export type ExchangeInvitationWritable = unknown & { + invitation_id?: Uuid; + email?: string; + code?: string; + link_token?: string; + code_challenge: string; +}; + +export type ControlUserPasswordLoginWritable = { + email: string; + password: string; +}; + +export type CreateBillingProviderWritable = { + provider: 'stripe'; + secret: string; + webhook_secret?: string; + api_version?: '2026-04-22.dahlia'; + inheritable?: boolean; +}; + +export type ApplicationId = Uuid; + +export type WorkspaceId = Uuid; + +export type ObjectId = Uuid; + +/** + * Required when disabling a provider pinned by live objects. + */ +export type ConfirmAffectedObjects = boolean; + +/** + * Break managed email-template references; requires X-Audit-Reason. + */ +export type ForceDelete = boolean; + +/** + * Explicit accessible workspace whose grants are merged with the current user's grants. + */ +export type WorkspaceIdQuery = Uuid; + +export type PermissionSubjectType = 'user' | 'client'; + +export type PermissionSubjectId = Uuid; + +export type OrganizationId = Uuid; + +export type IncludeRetired = boolean; + +/** + * Current resource ETag. + */ +export type IfMatch = string; + +export type IdempotencyKey = string; + +export type RequiredIdempotencyKey = string; + +export type ProviderId = Uuid; + +export type SessionId = Uuid; + +export type SubscriptionId = Uuid; + +export type PaymentId = Uuid; + +export type RequestId = Uuid; + +export type OAuthClientId = string; + +export type OAuthRedirectUri = string; + +export type OAuthResponseType = 'code'; + +export type OAuthScope = string; + +export type OAuthState = string; + +export type OAuthCodeChallenge = string; + +export type OAuthCodeChallengeMethod = 'S256'; + +export type OptionalPermissionSubjectType = 'user' | 'client'; + +export type OptionalPermissionSubjectId = Uuid; + +export type PermissionGrantStatus = 'active' | 'revoked'; + +export type Named = { + name: string; + slug: string; +}; + +export type Rename = { + name: string; +}; + +export type ProviderInheritance = { + /** + * Allow child scopes to resolve this provider. + */ + inheritable: boolean; +}; + +export type ApplicationAuthConfig2 = ApplicationAuthConfig; + +/** + * This entire object is returned by the unauthenticated runtime-config endpoint. Secrets are forbidden. + */ +export type PublicApplicationConfig = { + [key: string]: unknown; +}; + +export type InternalApplicationConfig = ApplicationInternalConfig; + +export type RoleAssignment2 = RoleAssignment; + +export type PermissionGrantBody = CreatePermissionGrant; + +export type OwnershipTransfer2 = OwnershipTransfer; + +export type SmtpProvider = { + name: string; + host: string; + port: number; + username?: string; + password?: string; + tls_mode: 'starttls' | 'implicit_tls'; + sender_email: string; + sender_name?: string; + inheritable?: boolean; +}; + +export type StorageProviderBody = CreateStorageProviderWritable; + +export type StorageUpload = CreateStorageUpload; + +export type OAuthAuthorizationDecision = { + client_id: string; + redirect_uri: string; + response_type: 'code'; + scope: string; + state: string; + nonce?: string; + code_challenge: string; + code_challenge_method: 'S256'; + decision: 'grant' | 'deny'; +}; + +export type OAuthToken = { + grant_type: 'authorization_code' | 'refresh_token' | 'client_credentials'; + code?: string; + redirect_uri?: string; + code_verifier?: string; + refresh_token?: string; + client_id?: string; + client_secret?: string; + scope?: string; +}; + +export type OAuthTokenCredential = { + token: string; + token_type_hint?: 'access_token' | 'refresh_token'; + client_id?: string; + client_secret?: string; +}; + +export type HealthData = { + body?: never; + path?: never; + query?: never; + url: '/healthz'; +}; + +export type HealthResponses = { + /** + * Process is alive + */ + 200: HealthStatus; +}; + +export type HealthResponse = HealthResponses[keyof HealthResponses]; + +export type ReadinessData = { + body?: never; + path?: never; + query?: never; + url: '/readyz'; +}; + +export type ReadinessErrors = { + /** + * RFC 9457 problem + */ + 503: Problem; +}; + +export type ReadinessError = ReadinessErrors[keyof ReadinessErrors]; + +export type ReadinessResponses = { + /** + * Process is ready + */ + 200: HealthStatus; +}; + +export type ReadinessResponse = ReadinessResponses[keyof ReadinessResponses]; + +export type VersionData = { + body?: never; + path?: never; + query?: never; + url: '/version'; +}; + +export type VersionResponses = { + /** + * Build information + */ + 200: VersionInfo; +}; + +export type VersionResponse = VersionResponses[keyof VersionResponses]; + +export type SetupStatusData = { + body?: never; + path?: never; + query?: never; + url: '/v1/setup/status'; +}; + +export type SetupStatusResponses = { + /** + * Setup and Platform user login availability + */ + 200: SetupStatus; +}; + +export type SetupStatusResponse = SetupStatusResponses[keyof SetupStatusResponses]; + +export type BootstrapData = { + body: BootstrapRequestWritable; + path?: never; + query?: never; + url: '/v1/setup/bootstrap'; +}; + +export type BootstrapErrors = { + /** + * RFC 9457 problem + */ + 401: Problem; +}; + +export type BootstrapError = BootstrapErrors[keyof BootstrapErrors]; + +export type BootstrapResponses = { + /** + * Setup-only Platform user session + */ + 201: SetupSession; +}; + +export type BootstrapResponse = BootstrapResponses[keyof BootstrapResponses]; + +export type CompleteSetupData = { + body?: CompleteSetup; + path?: never; + query?: never; + url: '/v1/setup/complete'; +}; + +export type CompleteSetupErrors = { + /** + * RFC 9457 problem + */ + 409: Problem; + /** + * RFC 9457 problem + */ + 422: Problem; +}; + +export type CompleteSetupError = CompleteSetupErrors[keyof CompleteSetupErrors]; + +export type CompleteSetupResponses = { + /** + * Setup completed + */ + 200: SetupCompletion; +}; + +export type CompleteSetupResponse = CompleteSetupResponses[keyof CompleteSetupResponses]; + +export type CreateSetupNotificationProviderData = { + body: SmtpProvider; + path?: never; + query?: never; + url: '/v1/setup/notification-providers'; +}; + +export type CreateSetupNotificationProviderResponses = { + /** + * Installation SMTP provider stored + */ + 201: NotificationProvider; +}; + +export type CreateSetupNotificationProviderResponse = CreateSetupNotificationProviderResponses[keyof CreateSetupNotificationProviderResponses]; + +export type StartControlUserEmailLoginData = { + body: ControlEmailStart; + path?: never; + query?: never; + url: '/v1/control/auth/email/start'; +}; + +export type StartControlUserEmailLoginResponses = { + /** + * Enumeration-safe Platform user challenge accepted + */ + 202: ChallengeAccepted; +}; + +export type StartControlUserEmailLoginResponse = StartControlUserEmailLoginResponses[keyof StartControlUserEmailLoginResponses]; + +export type VerifyControlUserEmailLoginData = { + body: EmailVerifyWritable; + path?: never; + query?: never; + url: '/v1/control/auth/email/verify'; +}; + +export type VerifyControlUserEmailLoginResponses = { + /** + * Platform user cookie session created + */ + 200: TokenResponse; +}; + +export type VerifyControlUserEmailLoginResponse = VerifyControlUserEmailLoginResponses[keyof VerifyControlUserEmailLoginResponses]; + +export type LoginControlUserWithPasswordData = { + body: ControlUserPasswordLoginWritable; + path?: never; + query?: never; + url: '/v1/control/auth/password'; +}; + +export type LoginControlUserWithPasswordErrors = { + /** + * RFC 9457 problem + */ + 401: Problem; +}; + +export type LoginControlUserWithPasswordError = LoginControlUserWithPasswordErrors[keyof LoginControlUserWithPasswordErrors]; + +export type LoginControlUserWithPasswordResponses = { + /** + * Platform user cookie session created + */ + 200: TokenResponse; +}; + +export type LoginControlUserWithPasswordResponse = LoginControlUserWithPasswordResponses[keyof LoginControlUserWithPasswordResponses]; + +export type ChangeControlUserPasswordData = { + body: ControlUserPasswordChange; + path?: never; + query?: never; + url: '/v1/control/auth/password'; +}; + +export type ChangeControlUserPasswordErrors = { + /** + * RFC 9457 problem + */ + 409: Problem; +}; + +export type ChangeControlUserPasswordError = ChangeControlUserPasswordErrors[keyof ChangeControlUserPasswordErrors]; + +export type ChangeControlUserPasswordResponses = { + /** + * Password stored and other Platform user sessions revoked + */ + 204: void; +}; + +export type ChangeControlUserPasswordResponse = ChangeControlUserPasswordResponses[keyof ChangeControlUserPasswordResponses]; + +export type GetControlUserAccountData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/auth/me'; +}; + +export type GetControlUserAccountResponses = { + /** + * Current Platform user profile and sign-in methods + */ + 200: ControlUserAccount; +}; + +export type GetControlUserAccountResponse = GetControlUserAccountResponses[keyof GetControlUserAccountResponses]; + +export type UpdateControlUserAccountData = { + body: UpdateControlUserAccount; + path?: never; + query?: never; + url: '/v1/control/auth/me'; +}; + +export type UpdateControlUserAccountResponses = { + /** + * Platform user profile updated + */ + 204: void; +}; + +export type UpdateControlUserAccountResponse = UpdateControlUserAccountResponses[keyof UpdateControlUserAccountResponses]; + +export type LogoutControlUserData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/auth/logout'; +}; + +export type LogoutControlUserResponses = { + /** + * Platform user session revoked + */ + 204: void; +}; + +export type LogoutControlUserResponse = LogoutControlUserResponses[keyof LogoutControlUserResponses]; + +export type RefreshControlUserSessionData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/auth/token/refresh'; +}; + +export type RefreshControlUserSessionResponses = { + /** + * Platform user session credential rotated + */ + 200: TokenResponse; +}; + +export type RefreshControlUserSessionResponse = RefreshControlUserSessionResponses[keyof RefreshControlUserSessionResponses]; + +export type ListControlUserSessionsData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/auth/sessions'; +}; + +export type ListControlUserSessionsResponses = { + /** + * Successful listControlUserSessions response. + */ + 200: SessionPage; +}; + +export type ListControlUserSessionsResponse = ListControlUserSessionsResponses[keyof ListControlUserSessionsResponses]; + +export type RevokeControlUserSessionData = { + body?: never; + path: { + session_id: Uuid; + }; + query?: never; + url: '/v1/control/auth/sessions/{session_id}'; +}; + +export type RevokeControlUserSessionResponses = { + /** + * Platform user session revoked + */ + 204: void; +}; + +export type RevokeControlUserSessionResponse = RevokeControlUserSessionResponses[keyof RevokeControlUserSessionResponses]; + +export type LogoutAllControlUserSessionsData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/auth/logout-all'; +}; + +export type LogoutAllControlUserSessionsResponses = { + /** + * All Platform user sessions revoked + */ + 204: void; +}; + +export type LogoutAllControlUserSessionsResponse = LogoutAllControlUserSessionsResponses[keyof LogoutAllControlUserSessionsResponses]; + +export type GetControlAuthMethodsData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/auth/methods'; +}; + +export type GetControlAuthMethodsResponses = { + /** + * Available Platform user sign-in methods + */ + 200: ControlAuthMethods; +}; + +export type GetControlAuthMethodsResponse = GetControlAuthMethodsResponses[keyof GetControlAuthMethodsResponses]; + +export type StartControlExternalLoginData = { + body?: never; + path: { + provider: 'google' | 'apple'; + }; + query?: never; + url: '/v1/control/auth/providers/{provider}/start'; +}; + +export type StartControlExternalLoginResponses = { + /** + * External Platform sign-in started */ - provider_id?: Uuid; - subject_type?: 'user' | 'workspace'; - subject_id?: Uuid; - payment_methods?: Array<'card' | 'twint'>; - success_uri: string; - cancel_uri: string; + 201: ExternalAuthStart; }; -export type CreateStorageProviderWritable = unknown & { - name: string; - endpoint: string; - region: string; - access_key_id: string; - secret_access_key: string; - force_path_style?: boolean; - public_bucket?: string; - private_bucket?: string; - public_base_url?: string; - inheritable?: boolean; +export type StartControlExternalLoginResponse = StartControlExternalLoginResponses[keyof StartControlExternalLoginResponses]; + +export type LinkControlExternalIdentityData = { + body?: never; + path: { + provider: 'google' | 'apple'; + }; + query?: never; + url: '/v1/control/auth/providers/{provider}/link'; +}; + +export type LinkControlExternalIdentityResponses = { /** - * Installation-scoped opt-in for local or private-network S3 endpoints. + * External Platform identity link started */ - allow_private_endpoint?: boolean; - max_object_bytes?: number; - max_email_image_bytes?: number; - max_application_bytes?: number; - max_application_objects?: number; + 201: ExternalAuthStart; }; -export type StorageUploadAuthorizationWritable = { - object: StorageObject; - upload_url: string; - upload_expires_at: string; - required_headers: { - [key: string]: string; +export type LinkControlExternalIdentityResponse = LinkControlExternalIdentityResponses[keyof LinkControlExternalIdentityResponses]; + +export type UnlinkControlExternalIdentityData = { + body?: never; + path: { + identity_id: Uuid; }; + query?: never; + url: '/v1/control/auth/identities/{identity_id}'; }; -export type BootstrapRequestWritable = { - credential: string; - email: string; - display_name?: string; +export type UnlinkControlExternalIdentityErrors = { + /** + * RFC 9457 problem + */ + 409: Problem; }; -export type AcceptOrganizationInvitationWritable = { - invitation_token: string; - display_name?: string; +export type UnlinkControlExternalIdentityError = UnlinkControlExternalIdentityErrors[keyof UnlinkControlExternalIdentityErrors]; + +export type UnlinkControlExternalIdentityResponses = { + /** + * External Platform identity unlinked + */ + 204: void; }; -export type PasswordSignInWritable = { - email: string; - password: string; +export type UnlinkControlExternalIdentityResponse = UnlinkControlExternalIdentityResponses[keyof UnlinkControlExternalIdentityResponses]; + +export type AcceptControlUserInvitationData = { + body: AcceptControlUserInvitationWritable; + path?: never; + query?: never; + url: '/v1/control/invitations/accept'; }; -export type PasswordSignUpWritable = PasswordSignInWritable & { - first_name?: string; - last_name?: string; - locale?: Locale; +export type AcceptControlUserInvitationErrors = { + /** + * RFC 9457 problem + */ + 401: Problem; }; -export type EmailVerifyWritable = { - challenge_id: Uuid; - code?: string; - link_token?: string; +export type AcceptControlUserInvitationError = AcceptControlUserInvitationErrors[keyof AcceptControlUserInvitationErrors]; + +export type AcceptControlUserInvitationResponses = { + /** + * Invitation accepted and Platform user cookie issued + */ + 200: TokenResponse; }; -export type TokenResponseWritable = { - access_token: string; - refresh_token: string; - token_type: 'Bearer'; - expires_in: number; +export type AcceptControlUserInvitationResponse = AcceptControlUserInvitationResponses[keyof AcceptControlUserInvitationResponses]; + +export type StartControlInvitationExternalLoginData = { + body: ControlInvitationProviderStart; + path: { + provider: 'google' | 'apple'; + }; + query?: never; + url: '/v1/control/invitations/providers/{provider}/start'; }; -export type OperatorPasswordLoginWritable = { - email: string; - password: string; +export type StartControlInvitationExternalLoginResponses = { + /** + * Provider-backed invitation acceptance started + */ + 201: ExternalAuthStart; }; -export type CreateBillingProviderWritable = { - provider: 'stripe'; - secret: string; - webhook_secret?: string; - api_version?: '2026-04-22.dahlia'; - inheritable?: boolean; +export type StartControlInvitationExternalLoginResponse = StartControlInvitationExternalLoginResponses[keyof StartControlInvitationExternalLoginResponses]; + +export type ListInstallationNotificationProvidersData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/installation/notification-providers'; }; -export type ApplicationId = Uuid; +export type ListInstallationNotificationProvidersResponses = { + /** + * Successful listInstallationNotificationProviders response. + */ + 200: NotificationProviderPage; +}; -export type WorkspaceId = Uuid; +export type ListInstallationNotificationProvidersResponse = ListInstallationNotificationProvidersResponses[keyof ListInstallationNotificationProvidersResponses]; -export type ObjectId = Uuid; +export type CreateInstallationNotificationProviderData = { + body: SmtpProvider; + path?: never; + query?: never; + url: '/v1/control/installation/notification-providers'; +}; -/** - * Required when disabling a provider pinned by live objects. - */ -export type ConfirmAffectedObjects = boolean; +export type CreateInstallationNotificationProviderResponses = { + /** + * Installation SMTP provider stored + */ + 201: NotificationProvider; +}; -/** - * Break managed email-template references; requires X-Audit-Reason. - */ -export type ForceDelete = boolean; +export type CreateInstallationNotificationProviderResponse = CreateInstallationNotificationProviderResponses[keyof CreateInstallationNotificationProviderResponses]; -/** - * Explicit accessible workspace whose grants are merged with the current user's grants. - */ -export type WorkspaceIdQuery = Uuid; +export type DisableInstallationNotificationProviderData = { + body?: never; + path: { + provider_id: Uuid; + }; + query?: never; + url: '/v1/control/installation/notification-providers/{provider_id}'; +}; -export type OrganizationId = Uuid; +export type DisableInstallationNotificationProviderErrors = { + /** + * RFC 9457 problem + */ + 404: Problem; +}; -export type IncludeRetired = boolean; +export type DisableInstallationNotificationProviderError = DisableInstallationNotificationProviderErrors[keyof DisableInstallationNotificationProviderErrors]; -/** - * Current resource ETag. - */ -export type IfMatch = string; +export type DisableInstallationNotificationProviderResponses = { + /** + * Installation notification provider disabled + */ + 204: void; +}; -export type IdempotencyKey = string; +export type DisableInstallationNotificationProviderResponse = DisableInstallationNotificationProviderResponses[keyof DisableInstallationNotificationProviderResponses]; -export type RequiredIdempotencyKey = string; +export type GetInstallationNotificationProviderData = { + body?: never; + path: { + provider_id: Uuid; + }; + query?: never; + url: '/v1/control/installation/notification-providers/{provider_id}'; +}; -export type ProviderId = Uuid; +export type GetInstallationNotificationProviderErrors = { + /** + * RFC 9457 problem + */ + 404: Problem; +}; -export type SessionId = Uuid; +export type GetInstallationNotificationProviderError = GetInstallationNotificationProviderErrors[keyof GetInstallationNotificationProviderErrors]; -export type SubscriptionId = Uuid; +export type GetInstallationNotificationProviderResponses = { + /** + * Installation notification provider metadata + */ + 200: NotificationProvider; +}; -export type PaymentId = Uuid; +export type GetInstallationNotificationProviderResponse = GetInstallationNotificationProviderResponses[keyof GetInstallationNotificationProviderResponses]; -export type RequestId = Uuid; +export type UpdateInstallationNotificationProviderData = { + body: UpdateSmtpProviderWritable; + path: { + provider_id: Uuid; + }; + query?: never; + url: '/v1/control/installation/notification-providers/{provider_id}'; +}; + +export type UpdateInstallationNotificationProviderErrors = { + /** + * RFC 9457 problem + */ + 404: Problem; +}; + +export type UpdateInstallationNotificationProviderError = UpdateInstallationNotificationProviderErrors[keyof UpdateInstallationNotificationProviderErrors]; + +export type UpdateInstallationNotificationProviderResponses = { + /** + * Installation notification provider updated + */ + 200: NotificationProvider; +}; + +export type UpdateInstallationNotificationProviderResponse = UpdateInstallationNotificationProviderResponses[keyof UpdateInstallationNotificationProviderResponses]; + +export type VerifyInstallationNotificationProviderData = { + body?: never; + path: { + provider_id: Uuid; + }; + query?: never; + url: '/v1/control/installation/notification-providers/{provider_id}/verify'; +}; + +export type VerifyInstallationNotificationProviderErrors = { + /** + * RFC 9457 problem + */ + 502: Problem; +}; + +export type VerifyInstallationNotificationProviderError = VerifyInstallationNotificationProviderErrors[keyof VerifyInstallationNotificationProviderErrors]; + +export type VerifyInstallationNotificationProviderResponses = { + /** + * SMTP connectivity and credentials verified + */ + 204: void; +}; + +export type VerifyInstallationNotificationProviderResponse = VerifyInstallationNotificationProviderResponses[keyof VerifyInstallationNotificationProviderResponses]; + +export type TestInstallationNotificationProviderData = { + body: TestNotificationProvider; + headers?: { + 'Idempotency-Key'?: string; + }; + path: { + provider_id: Uuid; + }; + query?: never; + url: '/v1/control/installation/notification-providers/{provider_id}/test'; +}; -export type OAuthClientId = string; +export type TestInstallationNotificationProviderErrors = { + /** + * RFC 9457 problem + */ + 404: Problem; +}; -export type OAuthRedirectUri = string; +export type TestInstallationNotificationProviderError = TestInstallationNotificationProviderErrors[keyof TestInstallationNotificationProviderErrors]; -export type OAuthResponseType = 'code'; +export type TestInstallationNotificationProviderResponses = { + /** + * Installation SMTP test queued + */ + 202: NotificationQueued; +}; -export type OAuthScope = string; +export type TestInstallationNotificationProviderResponse = TestInstallationNotificationProviderResponses[keyof TestInstallationNotificationProviderResponses]; -export type OAuthState = string; +export type ListInstallationAuthProvidersData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/installation/auth/providers'; +}; -export type OAuthCodeChallenge = string; +export type ListInstallationAuthProvidersResponses = { + /** + * Successful listInstallationAuthProviders response. + */ + 200: AuthProviderPage; +}; -export type OAuthCodeChallengeMethod = 'S256'; +export type ListInstallationAuthProvidersResponse = ListInstallationAuthProvidersResponses[keyof ListInstallationAuthProvidersResponses]; -export type Named = { - name: string; - slug: string; +export type DisableInstallationAuthProviderData = { + body?: never; + path: { + provider: 'google' | 'apple'; + }; + query?: never; + url: '/v1/control/installation/auth/providers/{provider}'; }; -export type Rename = { - name: string; +export type DisableInstallationAuthProviderResponses = { + /** + * Installation authentication provider disabled + */ + 204: void; }; -export type Object = { - [key: string]: unknown; +export type DisableInstallationAuthProviderResponse = DisableInstallationAuthProviderResponses[keyof DisableInstallationAuthProviderResponses]; + +export type UpdateInstallationAuthProviderData = { + body: UpdateInstallationAuthProvider; + path: { + provider: 'google' | 'apple'; + }; + query?: never; + url: '/v1/control/installation/auth/providers/{provider}'; }; -export type ProviderInheritance = { +export type UpdateInstallationAuthProviderErrors = { /** - * Allow child scopes to resolve this provider. + * RFC 9457 problem */ - inheritable: boolean; + 404: Problem; }; -export type ApplicationAuthConfig2 = ApplicationAuthConfig; +export type UpdateInstallationAuthProviderError = UpdateInstallationAuthProviderErrors[keyof UpdateInstallationAuthProviderErrors]; -/** - * This entire object is returned by the unauthenticated runtime-config endpoint. Secrets are forbidden. - */ -export type PublicApplicationConfig = { - [key: string]: unknown; +export type UpdateInstallationAuthProviderResponses = { + /** + * Installation authentication provider settings updated + */ + 204: void; }; -export type InternalApplicationConfig = ApplicationInternalConfig; - -export type RoleAssignment2 = RoleAssignment; +export type UpdateInstallationAuthProviderResponse = UpdateInstallationAuthProviderResponses[keyof UpdateInstallationAuthProviderResponses]; -export type OwnershipTransfer2 = OwnershipTransfer; +export type ConfigureInstallationAuthProviderData = { + body: ConfigureAuthProviderWritable; + path: { + provider: 'google' | 'apple'; + }; + query?: never; + url: '/v1/control/installation/auth/providers/{provider}'; +}; -export type SmtpProvider = { - name: string; - host: string; - port: number; - username?: string; - password?: string; - tls_mode: 'starttls' | 'implicit_tls'; - sender_email: string; - sender_name?: string; - inheritable?: boolean; +export type ConfigureInstallationAuthProviderResponses = { + /** + * Installation authentication provider configured + */ + 200: AuthProvider; }; -export type StorageProvider = CreateStorageProviderWritable; +export type ConfigureInstallationAuthProviderResponse = ConfigureInstallationAuthProviderResponses[keyof ConfigureInstallationAuthProviderResponses]; -export type StorageUpload = CreateStorageUpload; +export type ListInstallationBillingProvidersData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/installation/billing/providers'; +}; -export type OAuthAuthorizationDecision = { - client_id: string; - redirect_uri: string; - response_type: 'code'; - scope: string; - state: string; - nonce?: string; - code_challenge: string; - code_challenge_method: 'S256'; - decision: 'grant' | 'deny'; +export type ListInstallationBillingProvidersResponses = { + /** + * Successful listInstallationBillingProviders response. + */ + 200: BillingProviderPage; }; -export type OAuthToken = { - grant_type: 'authorization_code' | 'refresh_token' | 'client_credentials'; - code?: string; - redirect_uri?: string; - code_verifier?: string; - refresh_token?: string; - client_id?: string; - client_secret?: string; - scope?: string; +export type ListInstallationBillingProvidersResponse = ListInstallationBillingProvidersResponses[keyof ListInstallationBillingProvidersResponses]; + +export type CreateInstallationBillingProviderData = { + body: CreateBillingProviderWritable; + path?: never; + query?: never; + url: '/v1/control/installation/billing/providers'; }; -export type OAuthTokenCredential = { - token: string; - token_type_hint?: 'access_token' | 'refresh_token'; - client_id?: string; - client_secret?: string; +export type CreateInstallationBillingProviderResponses = { + /** + * Installation billing provider configured + */ + 201: BillingProvider; }; -export type HealthData = { +export type CreateInstallationBillingProviderResponse = CreateInstallationBillingProviderResponses[keyof CreateInstallationBillingProviderResponses]; + +export type DisableInstallationBillingProviderData = { body?: never; - path?: never; + path: { + provider_id: Uuid; + }; query?: never; - url: '/healthz'; + url: '/v1/control/installation/billing/providers/{provider_id}'; }; -export type HealthResponses = { +export type DisableInstallationBillingProviderResponses = { /** - * Process is alive + * Installation billing provider disabled */ - 200: unknown; + 204: void; }; -export type ReadinessData = { +export type DisableInstallationBillingProviderResponse = DisableInstallationBillingProviderResponses[keyof DisableInstallationBillingProviderResponses]; + +export type GetInstallationBillingProviderData = { body?: never; - path?: never; + path: { + provider_id: Uuid; + }; query?: never; - url: '/readyz'; + url: '/v1/control/installation/billing/providers/{provider_id}'; }; -export type ReadinessErrors = { +export type GetInstallationBillingProviderResponses = { /** - * RFC 9457 problem + * Secret-free installation billing provider */ - 503: Problem; + 200: BillingProvider; }; -export type ReadinessError = ReadinessErrors[keyof ReadinessErrors]; +export type GetInstallationBillingProviderResponse = GetInstallationBillingProviderResponses[keyof GetInstallationBillingProviderResponses]; -export type ReadinessResponses = { +export type UpdateInstallationBillingProviderData = { + body: UpdateBillingProviderWritable; + path: { + provider_id: Uuid; + }; + query?: never; + url: '/v1/control/installation/billing/providers/{provider_id}'; +}; + +export type UpdateInstallationBillingProviderResponses = { /** - * Process is ready + * Installation billing provider updated */ - 200: unknown; + 204: void; }; -export type VersionData = { +export type UpdateInstallationBillingProviderResponse = UpdateInstallationBillingProviderResponses[keyof UpdateInstallationBillingProviderResponses]; + +export type VerifyInstallationBillingProviderData = { body?: never; - path?: never; + path: { + provider_id: Uuid; + }; query?: never; - url: '/version'; + url: '/v1/control/installation/billing/providers/{provider_id}/verify'; }; -export type VersionResponses = { +export type VerifyInstallationBillingProviderResponses = { /** - * Build information + * Installation billing provider credentials verified */ - 200: { - [key: string]: unknown; - }; + 204: void; }; -export type VersionResponse = VersionResponses[keyof VersionResponses]; +export type VerifyInstallationBillingProviderResponse = VerifyInstallationBillingProviderResponses[keyof VerifyInstallationBillingProviderResponses]; -export type SetupStatusData = { +export type ListInstallationControlUsersData = { body?: never; path?: never; query?: never; - url: '/v1/setup/status'; + url: '/v1/control/installation/users'; }; -export type SetupStatusResponses = { +export type ListInstallationControlUsersResponses = { /** - * Setup and operator login availability + * Successful listInstallationControlUsers response. */ - 200: { - available: boolean; - operator_email_login_available: boolean; - }; + 200: ControlUserPage; }; -export type SetupStatusResponse = SetupStatusResponses[keyof SetupStatusResponses]; +export type ListInstallationControlUsersResponse = ListInstallationControlUsersResponses[keyof ListInstallationControlUsersResponses]; -export type BootstrapData = { - body: BootstrapRequestWritable; - path?: never; +export type DeleteInstallationControlUserData = { + body?: never; + path: { + control_user_id: Uuid; + }; query?: never; - url: '/v1/setup/bootstrap'; + url: '/v1/control/installation/users/{control_user_id}'; }; -export type BootstrapErrors = { +export type DeleteInstallationControlUserResponses = { /** - * RFC 9457 problem + * Installation role removed and sessions revoked */ - 401: Problem; + 204: void; }; -export type BootstrapError = BootstrapErrors[keyof BootstrapErrors]; +export type DeleteInstallationControlUserResponse = DeleteInstallationControlUserResponses[keyof DeleteInstallationControlUserResponses]; -export type BootstrapResponses = { +export type UpdateInstallationControlUserData = { + body: MembershipRole; + path: { + control_user_id: Uuid; + }; + query?: never; + url: '/v1/control/installation/users/{control_user_id}'; +}; + +export type UpdateInstallationControlUserResponses = { /** - * Setup-only operator session + * Installation role updated */ - 201: unknown; + 204: void; }; -export type CompleteSetupData = { +export type UpdateInstallationControlUserResponse = UpdateInstallationControlUserResponses[keyof UpdateInstallationControlUserResponses]; + +export type ListInstallationControlUserInvitationsData = { body?: never; path?: never; query?: never; - url: '/v1/setup/complete'; + url: '/v1/control/installation/invitations'; }; -export type CompleteSetupErrors = { +export type ListInstallationControlUserInvitationsResponses = { /** - * RFC 9457 problem + * Successful listInstallationControlUserInvitations response. */ - 409: Problem; + 200: ControlUserInvitationPage; }; -export type CompleteSetupError = CompleteSetupErrors[keyof CompleteSetupErrors]; +export type ListInstallationControlUserInvitationsResponse = ListInstallationControlUserInvitationsResponses[keyof ListInstallationControlUserInvitationsResponses]; -export type CompleteSetupResponses = { +export type CreateInstallationControlUserInvitationData = { + body: CreateControlUserInvitation; + path?: never; + query?: never; + url: '/v1/control/installation/invitations'; +}; + +export type CreateInstallationControlUserInvitationResponses = { /** - * Setup completed + * Platform user invitation created and credential returned once */ - 200: unknown; + 201: ControlUserInvitation; }; -export type CreateSetupNotificationProviderData = { - body: SmtpProvider; - path?: never; +export type CreateInstallationControlUserInvitationResponse = CreateInstallationControlUserInvitationResponses[keyof CreateInstallationControlUserInvitationResponses]; + +export type ResendInstallationControlUserInvitationData = { + body?: UpdateControlInvitationMethod; + path: { + invitation_id: Uuid; + }; query?: never; - url: '/v1/setup/notification-providers'; + url: '/v1/control/installation/invitations/{invitation_id}/resend'; }; -export type CreateSetupNotificationProviderResponses = { +export type ResendInstallationControlUserInvitationResponses = { /** - * Installation SMTP provider stored + * Platform user invitation rotated */ - 201: unknown; + 200: ControlUserInvitation; }; -export type StartOperatorEmailLoginData = { - body: { - email: string; - delivery?: 'code' | 'link' | 'both'; +export type ResendInstallationControlUserInvitationResponse = ResendInstallationControlUserInvitationResponses[keyof ResendInstallationControlUserInvitationResponses]; + +export type RevokeInstallationControlUserInvitationData = { + body?: never; + path: { + invitation_id: Uuid; }; - path?: never; query?: never; - url: '/v1/control/auth/email/start'; + url: '/v1/control/installation/invitations/{invitation_id}'; }; -export type StartOperatorEmailLoginResponses = { +export type RevokeInstallationControlUserInvitationResponses = { /** - * Enumeration-safe operator challenge accepted + * Platform user invitation revoked */ - 202: unknown; + 204: void; }; -export type VerifyOperatorEmailLoginData = { - body: EmailVerifyWritable; +export type RevokeInstallationControlUserInvitationResponse = RevokeInstallationControlUserInvitationResponses[keyof RevokeInstallationControlUserInvitationResponses]; + +export type GetControlAuthPolicyData = { + body?: never; path?: never; query?: never; - url: '/v1/control/auth/email/verify'; + url: '/v1/control/installation/auth-policy'; }; -export type VerifyOperatorEmailLoginResponses = { +export type GetControlAuthPolicyResponses = { /** - * Operator cookie session created + * Platform authentication policy */ - 200: unknown; + 200: ControlAuthPolicy; }; -export type LoginOperatorWithPasswordData = { - body: OperatorPasswordLoginWritable; +export type GetControlAuthPolicyResponse = GetControlAuthPolicyResponses[keyof GetControlAuthPolicyResponses]; + +export type UpdateControlAuthPolicyData = { + body: UpdateControlAuthPolicy; path?: never; query?: never; - url: '/v1/control/auth/password'; + url: '/v1/control/installation/auth-policy'; }; -export type LoginOperatorWithPasswordErrors = { +export type UpdateControlAuthPolicyErrors = { /** * RFC 9457 problem */ - 401: Problem; + 409: Problem; }; -export type LoginOperatorWithPasswordError = LoginOperatorWithPasswordErrors[keyof LoginOperatorWithPasswordErrors]; +export type UpdateControlAuthPolicyError = UpdateControlAuthPolicyErrors[keyof UpdateControlAuthPolicyErrors]; -export type LoginOperatorWithPasswordResponses = { +export type UpdateControlAuthPolicyResponses = { /** - * Operator cookie session created + * Platform authentication policy updated */ - 200: unknown; + 204: void; }; -export type ChangeOperatorPasswordData = { - body: OperatorPasswordChange; +export type UpdateControlAuthPolicyResponse = UpdateControlAuthPolicyResponses[keyof UpdateControlAuthPolicyResponses]; + +export type ListSigningKeysData = { + body?: never; path?: never; query?: never; - url: '/v1/control/auth/password'; + url: '/v1/control/installation/signing-keys'; }; -export type ChangeOperatorPasswordErrors = { +export type ListSigningKeysResponses = { /** - * RFC 9457 problem + * Successful listSigningKeys response. */ - 409: Problem; + 200: SigningKeyPage; }; -export type ChangeOperatorPasswordError = ChangeOperatorPasswordErrors[keyof ChangeOperatorPasswordErrors]; +export type ListSigningKeysResponse = ListSigningKeysResponses[keyof ListSigningKeysResponses]; + +export type RotateSigningKeyData = { + body?: never; + path?: never; + query?: never; + url: '/v1/control/installation/signing-keys/rotate'; +}; -export type ChangeOperatorPasswordResponses = { +export type RotateSigningKeyResponses = { /** - * Password stored and other operator sessions revoked + * New installation signing key activated */ - 204: void; + 201: SigningKey; }; -export type ChangeOperatorPasswordResponse = ChangeOperatorPasswordResponses[keyof ChangeOperatorPasswordResponses]; +export type RotateSigningKeyResponse = RotateSigningKeyResponses[keyof RotateSigningKeyResponses]; -export type GetOperatorAccountData = { +export type GetManagementApiStatusData = { body?: never; path?: never; query?: never; - url: '/v1/control/auth/me'; + url: '/v1/control/installation/management-api'; }; -export type GetOperatorAccountResponses = { +export type GetManagementApiStatusResponses = { /** - * Current operator profile and sign-in methods + * Management API installation status */ - 200: unknown; + 200: ManagementApiStatus; }; -export type UpdateOperatorAccountData = { - body: { - display_name: string; - }; +export type GetManagementApiStatusResponse = GetManagementApiStatusResponses[keyof GetManagementApiStatusResponses]; + +export type UpdateManagementApiStatusData = { + body: UpdateManagementApi; path?: never; query?: never; - url: '/v1/control/auth/me'; + url: '/v1/control/installation/management-api'; }; -export type UpdateOperatorAccountResponses = { +export type UpdateManagementApiStatusResponses = { /** - * Operator profile updated + * Management API status updated */ - 204: void; + 200: ManagementApiStatus; }; -export type UpdateOperatorAccountResponse = UpdateOperatorAccountResponses[keyof UpdateOperatorAccountResponses]; +export type UpdateManagementApiStatusResponse = UpdateManagementApiStatusResponses[keyof UpdateManagementApiStatusResponses]; -export type LogoutOperatorData = { +export type ListManagementClientsData = { body?: never; path?: never; query?: never; - url: '/v1/control/auth/logout'; + url: '/v1/control/installation/management-clients'; }; -export type LogoutOperatorResponses = { +export type ListManagementClientsResponses = { /** - * Operator session revoked + * Successful listManagementClients response. */ - 204: void; + 200: ManagementClientPage; }; -export type LogoutOperatorResponse = LogoutOperatorResponses[keyof LogoutOperatorResponses]; +export type ListManagementClientsResponse = ListManagementClientsResponses[keyof ListManagementClientsResponses]; -export type RefreshOperatorSessionData = { - body?: never; +export type CreateManagementClientData = { + body: CreateManagementClient; path?: never; query?: never; - url: '/v1/control/auth/token/refresh'; + url: '/v1/control/installation/management-clients'; }; -export type RefreshOperatorSessionResponses = { +export type CreateManagementClientErrors = { /** - * Operator session credential rotated + * RFC 9457 problem */ - 200: unknown; + 409: Problem; }; -export type ListOperatorSessionsData = { - body?: never; - path?: never; - query?: never; - url: '/v1/control/auth/sessions'; -}; +export type CreateManagementClientError = CreateManagementClientErrors[keyof CreateManagementClientErrors]; -export type ListOperatorSessionsResponses = { +export type CreateManagementClientResponses = { /** - * Cursor page + * Management client created and secret returned once */ - 200: Page; + 201: ManagementClient; }; -export type ListOperatorSessionsResponse = ListOperatorSessionsResponses[keyof ListOperatorSessionsResponses]; +export type CreateManagementClientResponse = CreateManagementClientResponses[keyof CreateManagementClientResponses]; -export type RevokeOperatorSessionData = { +export type RotateManagementClientSecretData = { body?: never; path: { - session_id: Uuid; + management_client_id: Uuid; }; query?: never; - url: '/v1/control/auth/sessions/{session_id}'; + url: '/v1/control/installation/management-clients/{management_client_id}/rotate-secret'; }; -export type RevokeOperatorSessionResponses = { +export type RotateManagementClientSecretResponses = { /** - * Operator session revoked + * Management client secret rotated and returned once */ - 204: void; + 200: SecretCredential; }; -export type RevokeOperatorSessionResponse = RevokeOperatorSessionResponses[keyof RevokeOperatorSessionResponses]; +export type RotateManagementClientSecretResponse = RotateManagementClientSecretResponses[keyof RotateManagementClientSecretResponses]; -export type LogoutAllOperatorSessionsData = { +export type DisableManagementClientData = { body?: never; - path?: never; + path: { + management_client_id: Uuid; + }; query?: never; - url: '/v1/control/auth/logout-all'; + url: '/v1/control/installation/management-clients/{management_client_id}'; }; -export type LogoutAllOperatorSessionsResponses = { +export type DisableManagementClientResponses = { /** - * All operator sessions revoked + * Management client disabled and all of its tokens invalidated */ 204: void; }; -export type LogoutAllOperatorSessionsResponse = LogoutAllOperatorSessionsResponses[keyof LogoutAllOperatorSessionsResponses]; +export type DisableManagementClientResponse = DisableManagementClientResponses[keyof DisableManagementClientResponses]; -export type AcceptOrganizationInvitationData = { - body: AcceptOrganizationInvitationWritable; - path?: never; +export type UpdateOrganizationPolicyData = { + body: UpdateOrganizationPolicy; + headers: { + /** + * Current resource ETag. + */ + 'If-Match': string; + }; + path: { + organization_id: Uuid; + }; query?: never; - url: '/v1/control/organization-invitations/accept'; + url: '/v1/control/installation/organizations/{organization_id}/policy'; }; -export type AcceptOrganizationInvitationErrors = { +export type UpdateOrganizationPolicyErrors = { /** * RFC 9457 problem */ - 401: Problem; + 412: Problem; }; -export type AcceptOrganizationInvitationError = AcceptOrganizationInvitationErrors[keyof AcceptOrganizationInvitationErrors]; +export type UpdateOrganizationPolicyError = UpdateOrganizationPolicyErrors[keyof UpdateOrganizationPolicyErrors]; -export type AcceptOrganizationInvitationResponses = { +export type UpdateOrganizationPolicyResponses = { /** - * Invitation accepted and operator cookie issued + * Installation-owned organization policy updated */ - 200: unknown; + 204: void; }; -export type ListInstallationNotificationProvidersData = { +export type UpdateOrganizationPolicyResponse = UpdateOrganizationPolicyResponses[keyof UpdateOrganizationPolicyResponses]; + +export type ListOrganizationsData = { body?: never; path?: never; - query?: never; - url: '/v1/control/installation/notification-providers'; + query?: { + include_retired?: boolean; + }; + url: '/v1/control/organizations'; }; -export type ListInstallationNotificationProvidersResponses = { +export type ListOrganizationsResponses = { /** - * Cursor page + * Accessible organizations and the current installation role */ - 200: Page; + 200: OrganizationPage; }; -export type ListInstallationNotificationProvidersResponse = ListInstallationNotificationProvidersResponses[keyof ListInstallationNotificationProvidersResponses]; +export type ListOrganizationsResponse = ListOrganizationsResponses[keyof ListOrganizationsResponses]; -export type CreateInstallationNotificationProviderData = { - body: SmtpProvider; +export type CreateOrganizationData = { + body: Named; path?: never; query?: never; - url: '/v1/control/installation/notification-providers'; -}; - -export type CreateInstallationNotificationProviderResponses = { - /** - * Installation SMTP provider stored - */ - 201: unknown; -}; - -export type DisableInstallationNotificationProviderData = { - body?: never; - path: { - provider_id: Uuid; - }; - query?: never; - url: '/v1/control/installation/notification-providers/{provider_id}'; + url: '/v1/control/organizations'; }; -export type DisableInstallationNotificationProviderErrors = { +export type CreateOrganizationErrors = { /** * RFC 9457 problem */ - 404: Problem; + 409: Problem; }; -export type DisableInstallationNotificationProviderError = DisableInstallationNotificationProviderErrors[keyof DisableInstallationNotificationProviderErrors]; +export type CreateOrganizationError = CreateOrganizationErrors[keyof CreateOrganizationErrors]; -export type DisableInstallationNotificationProviderResponses = { +export type CreateOrganizationResponses = { /** - * Installation notification provider disabled + * Organization created */ - 204: void; + 201: Organization; }; -export type DisableInstallationNotificationProviderResponse = DisableInstallationNotificationProviderResponses[keyof DisableInstallationNotificationProviderResponses]; +export type CreateOrganizationResponse = CreateOrganizationResponses[keyof CreateOrganizationResponses]; -export type GetInstallationNotificationProviderData = { +export type ListApplicationsData = { body?: never; path: { - provider_id: Uuid; + organization_id: Uuid; }; - query?: never; - url: '/v1/control/installation/notification-providers/{provider_id}'; + query?: { + include_retired?: boolean; + }; + url: '/v1/control/organizations/{organization_id}/applications'; }; -export type GetInstallationNotificationProviderErrors = { +export type ListApplicationsResponses = { /** - * RFC 9457 problem + * Successful listApplications response. */ - 404: Problem; + 200: ApplicationPage; }; -export type GetInstallationNotificationProviderError = GetInstallationNotificationProviderErrors[keyof GetInstallationNotificationProviderErrors]; - -export type GetInstallationNotificationProviderResponses = { - /** - * Installation notification provider metadata - */ - 200: unknown; -}; +export type ListApplicationsResponse = ListApplicationsResponses[keyof ListApplicationsResponses]; -export type UpdateInstallationNotificationProviderData = { - body: Object; +export type CreateApplicationData = { + body: Named; path: { - provider_id: Uuid; + organization_id: Uuid; }; query?: never; - url: '/v1/control/installation/notification-providers/{provider_id}'; + url: '/v1/control/organizations/{organization_id}/applications'; }; -export type UpdateInstallationNotificationProviderErrors = { +export type CreateApplicationResponses = { /** - * RFC 9457 problem + * Application created */ - 404: Problem; + 201: Application; }; -export type UpdateInstallationNotificationProviderError = UpdateInstallationNotificationProviderErrors[keyof UpdateInstallationNotificationProviderErrors]; +export type CreateApplicationResponse = CreateApplicationResponses[keyof CreateApplicationResponses]; -export type UpdateInstallationNotificationProviderResponses = { +export type RetireApplicationData = { + body?: never; + path: { + organization_id: Uuid; + application_resource_id: Uuid; + }; + query?: never; + url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}'; +}; + +export type RetireApplicationResponses = { /** - * Installation notification provider updated + * Application retired and live credentials revoked */ - 200: unknown; + 204: void; }; -export type VerifyInstallationNotificationProviderData = { - body?: never; +export type RetireApplicationResponse = RetireApplicationResponses[keyof RetireApplicationResponses]; + +export type UpdateApplicationData = { + body: Rename; path: { - provider_id: Uuid; + organization_id: Uuid; + application_resource_id: Uuid; }; query?: never; - url: '/v1/control/installation/notification-providers/{provider_id}/verify'; + url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}'; }; -export type VerifyInstallationNotificationProviderErrors = { +export type UpdateApplicationErrors = { /** * RFC 9457 problem */ - 502: Problem; + 412: Problem; }; -export type VerifyInstallationNotificationProviderError = VerifyInstallationNotificationProviderErrors[keyof VerifyInstallationNotificationProviderErrors]; +export type UpdateApplicationError = UpdateApplicationErrors[keyof UpdateApplicationErrors]; -export type VerifyInstallationNotificationProviderResponses = { +export type UpdateApplicationResponses = { /** - * SMTP connectivity and credentials verified + * Application renamed */ 204: void; }; -export type VerifyInstallationNotificationProviderResponse = VerifyInstallationNotificationProviderResponses[keyof VerifyInstallationNotificationProviderResponses]; +export type UpdateApplicationResponse = UpdateApplicationResponses[keyof UpdateApplicationResponses]; -export type TestInstallationNotificationProviderData = { - body: Object; - headers?: { - 'Idempotency-Key'?: string; - }; +export type RestoreApplicationData = { + body?: never; path: { - provider_id: Uuid; + organization_id: Uuid; + application_resource_id: Uuid; }; query?: never; - url: '/v1/control/installation/notification-providers/{provider_id}/test'; -}; - -export type TestInstallationNotificationProviderErrors = { - /** - * RFC 9457 problem - */ - 404: Problem; + url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}/restore'; }; -export type TestInstallationNotificationProviderError = TestInstallationNotificationProviderErrors[keyof TestInstallationNotificationProviderErrors]; - -export type TestInstallationNotificationProviderResponses = { +export type RestoreApplicationResponses = { /** - * Installation SMTP test queued + * Application restored without restoring revoked credentials */ - 202: unknown; + 204: void; }; -export type ListInstallationAuthProvidersData = { +export type RestoreApplicationResponse = RestoreApplicationResponses[keyof RestoreApplicationResponses]; + +export type RetireOrganizationData = { body?: never; - path?: never; + path: { + organization_id: Uuid; + }; query?: never; - url: '/v1/control/installation/auth/providers'; + url: '/v1/control/organizations/{organization_id}'; }; -export type ListInstallationAuthProvidersResponses = { +export type RetireOrganizationResponses = { /** - * Cursor page + * Organization and active descendants retired */ - 200: Page; + 204: void; }; -export type ListInstallationAuthProvidersResponse = ListInstallationAuthProvidersResponses[keyof ListInstallationAuthProvidersResponses]; +export type RetireOrganizationResponse = RetireOrganizationResponses[keyof RetireOrganizationResponses]; -export type DisableInstallationAuthProviderData = { +export type GetOrganizationData = { body?: never; path: { - provider: 'google' | 'apple'; + organization_id: Uuid; }; query?: never; - url: '/v1/control/installation/auth/providers/{provider}'; + url: '/v1/control/organizations/{organization_id}'; }; -export type DisableInstallationAuthProviderResponses = { +export type GetOrganizationResponses = { /** - * Installation authentication provider disabled + * Organization details */ - 204: void; + 200: Organization; }; -export type DisableInstallationAuthProviderResponse = DisableInstallationAuthProviderResponses[keyof DisableInstallationAuthProviderResponses]; +export type GetOrganizationResponse = GetOrganizationResponses[keyof GetOrganizationResponses]; -export type UpdateInstallationAuthProviderData = { - body: ProviderInheritance; +export type UpdateOrganizationData = { + body: Rename; path: { - provider: 'google' | 'apple'; + organization_id: Uuid; }; query?: never; - url: '/v1/control/installation/auth/providers/{provider}'; + url: '/v1/control/organizations/{organization_id}'; }; -export type UpdateInstallationAuthProviderErrors = { +export type UpdateOrganizationErrors = { /** * RFC 9457 problem */ - 404: Problem; + 412: Problem; }; -export type UpdateInstallationAuthProviderError = UpdateInstallationAuthProviderErrors[keyof UpdateInstallationAuthProviderErrors]; +export type UpdateOrganizationError = UpdateOrganizationErrors[keyof UpdateOrganizationErrors]; -export type UpdateInstallationAuthProviderResponses = { +export type UpdateOrganizationResponses = { /** - * Installation authentication provider inheritance updated + * Organization renamed */ 204: void; }; -export type UpdateInstallationAuthProviderResponse = UpdateInstallationAuthProviderResponses[keyof UpdateInstallationAuthProviderResponses]; +export type UpdateOrganizationResponse = UpdateOrganizationResponses[keyof UpdateOrganizationResponses]; -export type ConfigureInstallationAuthProviderData = { - body: Object; +export type GetOrganizationPolicyData = { + body?: never; path: { - provider: 'google' | 'apple'; + organization_id: Uuid; }; query?: never; - url: '/v1/control/installation/auth/providers/{provider}'; + url: '/v1/control/organizations/{organization_id}/policy'; }; -export type ConfigureInstallationAuthProviderResponses = { +export type GetOrganizationPolicyResponses = { /** - * Installation authentication provider configured + * Organization policy and current usage */ - 200: unknown; + 200: OrganizationPolicy; }; -export type ListInstallationBillingProvidersData = { +export type GetOrganizationPolicyResponse = GetOrganizationPolicyResponses[keyof GetOrganizationPolicyResponses]; + +export type RestoreOrganizationData = { body?: never; - path?: never; + path: { + organization_id: Uuid; + }; query?: never; - url: '/v1/control/installation/billing/providers'; + url: '/v1/control/organizations/{organization_id}/restore'; }; -export type ListInstallationBillingProvidersResponses = { +export type RestoreOrganizationResponses = { /** - * Cursor page + * Organization restored; descendants remain retired */ - 200: Page; + 204: void; }; -export type ListInstallationBillingProvidersResponse = ListInstallationBillingProvidersResponses[keyof ListInstallationBillingProvidersResponses]; +export type RestoreOrganizationResponse = RestoreOrganizationResponses[keyof RestoreOrganizationResponses]; -export type CreateInstallationBillingProviderData = { - body: CreateBillingProviderWritable; - path?: never; +export type ListOrganizationMembersData = { + body?: never; + path: { + organization_id: Uuid; + }; query?: never; - url: '/v1/control/installation/billing/providers'; + url: '/v1/control/organizations/{organization_id}/members'; }; -export type CreateInstallationBillingProviderResponses = { +export type ListOrganizationMembersResponses = { /** - * Installation billing provider configured + * Successful listOrganizationMembers response. */ - 201: unknown; + 200: OrganizationMemberPage; }; -export type DisableInstallationBillingProviderData = { +export type ListOrganizationMembersResponse = ListOrganizationMembersResponses[keyof ListOrganizationMembersResponses]; + +export type DeleteOrganizationMemberData = { body?: never; path: { - provider_id: Uuid; + organization_id: Uuid; + member_id: Uuid; }; query?: never; - url: '/v1/control/installation/billing/providers/{provider_id}'; + url: '/v1/control/organizations/{organization_id}/members/{member_id}'; }; -export type DisableInstallationBillingProviderResponses = { +export type DeleteOrganizationMemberResponses = { /** - * Installation billing provider disabled + * Organization member removed */ 204: void; }; -export type DisableInstallationBillingProviderResponse = DisableInstallationBillingProviderResponses[keyof DisableInstallationBillingProviderResponses]; +export type DeleteOrganizationMemberResponse = DeleteOrganizationMemberResponses[keyof DeleteOrganizationMemberResponses]; -export type GetInstallationBillingProviderData = { +export type UpdateOrganizationMemberData = { + body: MembershipRole; + path: { + organization_id: Uuid; + member_id: Uuid; + }; + query?: never; + url: '/v1/control/organizations/{organization_id}/members/{member_id}'; +}; + +export type UpdateOrganizationMemberResponses = { + /** + * Organization role updated + */ + 204: void; +}; + +export type UpdateOrganizationMemberResponse = UpdateOrganizationMemberResponses[keyof UpdateOrganizationMemberResponses]; + +export type ListOrganizationInvitationsData = { body?: never; path: { - provider_id: Uuid; + organization_id: Uuid; }; query?: never; - url: '/v1/control/installation/billing/providers/{provider_id}'; + url: '/v1/control/organizations/{organization_id}/invitations'; }; -export type GetInstallationBillingProviderResponses = { +export type ListOrganizationInvitationsResponses = { /** - * Secret-free installation billing provider + * Successful listOrganizationInvitations response. */ - 200: unknown; + 200: ControlUserInvitationPage; }; -export type UpdateInstallationBillingProviderData = { - body: Object; +export type ListOrganizationInvitationsResponse = ListOrganizationInvitationsResponses[keyof ListOrganizationInvitationsResponses]; + +export type CreateOrganizationInvitationData = { + body: CreateControlUserInvitation; path: { - provider_id: Uuid; + organization_id: Uuid; }; query?: never; - url: '/v1/control/installation/billing/providers/{provider_id}'; + url: '/v1/control/organizations/{organization_id}/invitations'; }; -export type UpdateInstallationBillingProviderResponses = { +export type CreateOrganizationInvitationResponses = { /** - * Installation billing provider updated + * Invitation queued and credential returned once */ - 204: void; + 201: ControlUserInvitation; }; -export type UpdateInstallationBillingProviderResponse = UpdateInstallationBillingProviderResponses[keyof UpdateInstallationBillingProviderResponses]; +export type CreateOrganizationInvitationResponse = CreateOrganizationInvitationResponses[keyof CreateOrganizationInvitationResponses]; -export type VerifyInstallationBillingProviderData = { +export type ResendOrganizationInvitationData = { body?: never; path: { - provider_id: Uuid; + organization_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/control/installation/billing/providers/{provider_id}/verify'; + url: '/v1/control/organizations/{organization_id}/invitations/{invitation_id}/resend'; }; -export type VerifyInstallationBillingProviderResponses = { +export type ResendOrganizationInvitationResponses = { /** - * Installation billing provider credentials verified + * Invitation credential rotated and delivery queued */ - 204: void; + 200: ControlUserInvitation; }; -export type VerifyInstallationBillingProviderResponse = VerifyInstallationBillingProviderResponses[keyof VerifyInstallationBillingProviderResponses]; +export type ResendOrganizationInvitationResponse = ResendOrganizationInvitationResponses[keyof ResendOrganizationInvitationResponses]; -export type ListInstallationOperatorsData = { +export type RevokeOrganizationInvitationData = { body?: never; - path?: never; + path: { + organization_id: Uuid; + invitation_id: Uuid; + }; query?: never; - url: '/v1/control/installation/operators'; + url: '/v1/control/organizations/{organization_id}/invitations/{invitation_id}'; }; -export type ListInstallationOperatorsResponses = { +export type RevokeOrganizationInvitationResponses = { /** - * Cursor page + * Pending invitation revoked */ - 200: Page; + 204: void; }; -export type ListInstallationOperatorsResponse = ListInstallationOperatorsResponses[keyof ListInstallationOperatorsResponses]; +export type RevokeOrganizationInvitationResponse = RevokeOrganizationInvitationResponses[keyof RevokeOrganizationInvitationResponses]; -export type CreateInstallationOperatorData = { - body: Object; - path?: never; +export type ListOrganizationAuditLogsData = { + body?: never; + path: { + organization_id: Uuid; + }; query?: never; - url: '/v1/control/installation/operators'; + url: '/v1/control/organizations/{organization_id}/audit-logs'; }; -export type CreateInstallationOperatorResponses = { +export type ListOrganizationAuditLogsResponses = { /** - * Installation operator and role created + * Successful listOrganizationAuditLogs response. */ - 201: unknown; + 200: AuditRecordPage; }; -export type DeleteInstallationOperatorData = { +export type ListOrganizationAuditLogsResponse = ListOrganizationAuditLogsResponses[keyof ListOrganizationAuditLogsResponses]; + +export type ListOrganizationAuthProvidersData = { body?: never; path: { - operator_id: Uuid; + organization_id: Uuid; }; query?: never; - url: '/v1/control/installation/operators/{operator_id}'; + url: '/v1/control/organizations/{organization_id}/auth/providers'; }; -export type DeleteInstallationOperatorResponses = { +export type ListOrganizationAuthProvidersResponses = { /** - * Installation role removed and sessions revoked + * Successful listOrganizationAuthProviders response. */ - 204: void; + 200: AuthProviderPage; }; -export type DeleteInstallationOperatorResponse = DeleteInstallationOperatorResponses[keyof DeleteInstallationOperatorResponses]; +export type ListOrganizationAuthProvidersResponse = ListOrganizationAuthProvidersResponses[keyof ListOrganizationAuthProvidersResponses]; -export type UpdateInstallationOperatorData = { - body: Object; +export type DisableOrganizationAuthProviderData = { + body?: never; path: { - operator_id: Uuid; + organization_id: Uuid; + provider: 'google' | 'apple'; }; query?: never; - url: '/v1/control/installation/operators/{operator_id}'; + url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}'; }; -export type UpdateInstallationOperatorResponses = { +export type DisableOrganizationAuthProviderResponses = { /** - * Installation role updated + * Organization authentication provider disabled */ 204: void; }; -export type UpdateInstallationOperatorResponse = UpdateInstallationOperatorResponses[keyof UpdateInstallationOperatorResponses]; +export type DisableOrganizationAuthProviderResponse = DisableOrganizationAuthProviderResponses[keyof DisableOrganizationAuthProviderResponses]; -export type ListSigningKeysData = { - body?: never; - path?: never; +export type UpdateOrganizationAuthProviderData = { + body: ProviderInheritance; + path: { + organization_id: Uuid; + provider: 'google' | 'apple'; + }; query?: never; - url: '/v1/control/installation/signing-keys'; + url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}'; }; -export type ListSigningKeysResponses = { +export type UpdateOrganizationAuthProviderErrors = { /** - * Cursor page + * RFC 9457 problem */ - 200: Page; + 404: Problem; }; -export type ListSigningKeysResponse = ListSigningKeysResponses[keyof ListSigningKeysResponses]; +export type UpdateOrganizationAuthProviderError = UpdateOrganizationAuthProviderErrors[keyof UpdateOrganizationAuthProviderErrors]; -export type RotateSigningKeyData = { - body?: never; - path?: never; +export type UpdateOrganizationAuthProviderResponses = { + /** + * Organization authentication provider inheritance updated + */ + 204: void; +}; + +export type UpdateOrganizationAuthProviderResponse = UpdateOrganizationAuthProviderResponses[keyof UpdateOrganizationAuthProviderResponses]; + +export type ConfigureOrganizationAuthProviderData = { + body: ConfigureAuthProviderWritable; + path: { + organization_id: Uuid; + provider: 'google' | 'apple'; + }; query?: never; - url: '/v1/control/installation/signing-keys/rotate'; + url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}'; }; -export type RotateSigningKeyResponses = { +export type ConfigureOrganizationAuthProviderResponses = { /** - * New installation signing key activated + * Organization authentication provider configured */ - 201: unknown; + 200: AuthProvider; }; -export type GetManagementApiStatusData = { +export type ConfigureOrganizationAuthProviderResponse = ConfigureOrganizationAuthProviderResponses[keyof ConfigureOrganizationAuthProviderResponses]; + +export type ListOrganizationNotificationProvidersData = { body?: never; - path?: never; + path: { + organization_id: Uuid; + }; query?: never; - url: '/v1/control/installation/management-api'; + url: '/v1/control/organizations/{organization_id}/notification-providers'; }; -export type GetManagementApiStatusResponses = { +export type ListOrganizationNotificationProvidersResponses = { /** - * Management API installation status + * Successful listOrganizationNotificationProviders response. */ - 200: ManagementApiStatus; + 200: NotificationProviderPage; }; -export type GetManagementApiStatusResponse = GetManagementApiStatusResponses[keyof GetManagementApiStatusResponses]; +export type ListOrganizationNotificationProvidersResponse = ListOrganizationNotificationProvidersResponses[keyof ListOrganizationNotificationProvidersResponses]; -export type UpdateManagementApiStatusData = { - body: { - enabled: boolean; +export type CreateOrganizationNotificationProviderData = { + body: SmtpProvider; + path: { + organization_id: Uuid; }; - path?: never; query?: never; - url: '/v1/control/installation/management-api'; + url: '/v1/control/organizations/{organization_id}/notification-providers'; }; -export type UpdateManagementApiStatusResponses = { +export type CreateOrganizationNotificationProviderResponses = { /** - * Management API status updated + * Organization SMTP provider stored */ - 200: unknown; + 201: NotificationProvider; }; -export type ListManagementClientsData = { +export type CreateOrganizationNotificationProviderResponse = CreateOrganizationNotificationProviderResponses[keyof CreateOrganizationNotificationProviderResponses]; + +export type DisableOrganizationNotificationProviderData = { body?: never; - path?: never; + path: { + organization_id: Uuid; + provider_id: Uuid; + }; query?: never; - url: '/v1/control/installation/management-clients'; + url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}'; }; -export type ListManagementClientsResponses = { +export type DisableOrganizationNotificationProviderResponses = { /** - * Cursor page + * Organization SMTP provider disabled */ - 200: Page; + 204: void; }; -export type ListManagementClientsResponse = ListManagementClientsResponses[keyof ListManagementClientsResponses]; +export type DisableOrganizationNotificationProviderResponse = DisableOrganizationNotificationProviderResponses[keyof DisableOrganizationNotificationProviderResponses]; -export type CreateManagementClientData = { - body: CreateManagementClient; - path?: never; +export type GetOrganizationNotificationProviderData = { + body?: never; + path: { + organization_id: Uuid; + provider_id: Uuid; + }; query?: never; - url: '/v1/control/installation/management-clients'; + url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}'; }; -export type CreateManagementClientErrors = { +export type GetOrganizationNotificationProviderResponses = { /** - * RFC 9457 problem + * Redacted organization SMTP provider */ - 409: Problem; + 200: NotificationProvider; }; -export type CreateManagementClientError = CreateManagementClientErrors[keyof CreateManagementClientErrors]; - -export type CreateManagementClientResponses = { - /** - * Management client created and secret returned once - */ - 201: unknown; -}; +export type GetOrganizationNotificationProviderResponse = GetOrganizationNotificationProviderResponses[keyof GetOrganizationNotificationProviderResponses]; -export type RotateManagementClientSecretData = { - body?: never; +export type UpdateOrganizationNotificationProviderData = { + body: UpdateSmtpProviderWritable; path: { - management_client_id: Uuid; + organization_id: Uuid; + provider_id: Uuid; }; query?: never; - url: '/v1/control/installation/management-clients/{management_client_id}/rotate-secret'; + url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}'; }; -export type RotateManagementClientSecretResponses = { +export type UpdateOrganizationNotificationProviderResponses = { /** - * Management client secret rotated and returned once + * Organization SMTP provider updated */ - 200: unknown; + 200: NotificationProvider; }; -export type DisableManagementClientData = { +export type UpdateOrganizationNotificationProviderResponse = UpdateOrganizationNotificationProviderResponses[keyof UpdateOrganizationNotificationProviderResponses]; + +export type VerifyOrganizationNotificationProviderData = { body?: never; path: { - management_client_id: Uuid; + organization_id: Uuid; + provider_id: Uuid; }; query?: never; - url: '/v1/control/installation/management-clients/{management_client_id}'; + url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}/verify'; }; -export type DisableManagementClientResponses = { +export type VerifyOrganizationNotificationProviderResponses = { /** - * Management client disabled and all of its tokens invalidated + * Organization SMTP provider verified */ 204: void; }; -export type DisableManagementClientResponse = DisableManagementClientResponses[keyof DisableManagementClientResponses]; +export type VerifyOrganizationNotificationProviderResponse = VerifyOrganizationNotificationProviderResponses[keyof VerifyOrganizationNotificationProviderResponses]; -export type UpdateOrganizationPolicyData = { - body: UpdateOrganizationPolicy; - headers: { - /** - * Current resource ETag. - */ - 'If-Match': string; +export type TestOrganizationNotificationProviderData = { + body: TestNotificationProvider; + headers?: { + 'Idempotency-Key'?: string; }; path: { organization_id: Uuid; + provider_id: Uuid; }; query?: never; - url: '/v1/control/installation/organizations/{organization_id}/policy'; -}; - -export type UpdateOrganizationPolicyErrors = { - /** - * RFC 9457 problem - */ - 412: Problem; + url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}/test'; }; -export type UpdateOrganizationPolicyError = UpdateOrganizationPolicyErrors[keyof UpdateOrganizationPolicyErrors]; - -export type UpdateOrganizationPolicyResponses = { +export type TestOrganizationNotificationProviderResponses = { /** - * Installation-owned organization policy updated + * Organization SMTP test queued */ - 204: void; + 202: NotificationQueued; }; -export type UpdateOrganizationPolicyResponse = UpdateOrganizationPolicyResponses[keyof UpdateOrganizationPolicyResponses]; +export type TestOrganizationNotificationProviderResponse = TestOrganizationNotificationProviderResponses[keyof TestOrganizationNotificationProviderResponses]; -export type ListOrganizationsData = { +export type ListOrganizationBillingProvidersData = { body?: never; - path?: never; - query?: { - include_retired?: boolean; + path: { + organization_id: Uuid; }; - url: '/v1/control/organizations'; + query?: never; + url: '/v1/control/organizations/{organization_id}/billing/providers'; }; -export type ListOrganizationsResponses = { +export type ListOrganizationBillingProvidersResponses = { /** - * Accessible organizations and the current installation role + * Successful listOrganizationBillingProviders response. */ - 200: OrganizationPage; + 200: BillingProviderPage; }; -export type ListOrganizationsResponse = ListOrganizationsResponses[keyof ListOrganizationsResponses]; +export type ListOrganizationBillingProvidersResponse = ListOrganizationBillingProvidersResponses[keyof ListOrganizationBillingProvidersResponses]; -export type CreateOrganizationData = { - body: Named; - path?: never; +export type CreateOrganizationBillingProviderData = { + body: CreateBillingProviderWritable; + path: { + organization_id: Uuid; + }; query?: never; - url: '/v1/control/organizations'; + url: '/v1/control/organizations/{organization_id}/billing/providers'; }; -export type CreateOrganizationErrors = { +export type CreateOrganizationBillingProviderResponses = { /** - * RFC 9457 problem + * Organization billing provider configured */ - 409: Problem; + 201: BillingProvider; }; -export type CreateOrganizationError = CreateOrganizationErrors[keyof CreateOrganizationErrors]; - -export type CreateOrganizationResponses = { - /** - * Organization created - */ - 201: unknown; -}; +export type CreateOrganizationBillingProviderResponse = CreateOrganizationBillingProviderResponses[keyof CreateOrganizationBillingProviderResponses]; -export type ListApplicationsData = { +export type DisableOrganizationBillingProviderData = { body?: never; path: { organization_id: Uuid; + provider_id: Uuid; }; - query?: { - include_retired?: boolean; - }; - url: '/v1/control/organizations/{organization_id}/applications'; + query?: never; + url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}'; }; -export type ListApplicationsResponses = { +export type DisableOrganizationBillingProviderResponses = { /** - * Cursor page + * Organization billing provider disabled */ - 200: Page; + 204: void; }; -export type ListApplicationsResponse = ListApplicationsResponses[keyof ListApplicationsResponses]; +export type DisableOrganizationBillingProviderResponse = DisableOrganizationBillingProviderResponses[keyof DisableOrganizationBillingProviderResponses]; -export type CreateApplicationData = { - body: Named; +export type GetOrganizationBillingProviderData = { + body?: never; path: { organization_id: Uuid; + provider_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/applications'; + url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}'; }; -export type CreateApplicationResponses = { +export type GetOrganizationBillingProviderResponses = { /** - * Application created + * Secret-free organization billing provider */ - 201: unknown; + 200: BillingProvider; }; -export type RetireApplicationData = { - body?: never; +export type GetOrganizationBillingProviderResponse = GetOrganizationBillingProviderResponses[keyof GetOrganizationBillingProviderResponses]; + +export type UpdateOrganizationBillingProviderData = { + body: UpdateBillingProviderWritable; path: { organization_id: Uuid; - application_resource_id: Uuid; + provider_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}'; + url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}'; }; -export type RetireApplicationResponses = { +export type UpdateOrganizationBillingProviderResponses = { /** - * Application retired and live credentials revoked + * Organization billing provider updated */ 204: void; }; -export type RetireApplicationResponse = RetireApplicationResponses[keyof RetireApplicationResponses]; +export type UpdateOrganizationBillingProviderResponse = UpdateOrganizationBillingProviderResponses[keyof UpdateOrganizationBillingProviderResponses]; -export type UpdateApplicationData = { - body: Rename; +export type VerifyOrganizationBillingProviderData = { + body?: never; path: { organization_id: Uuid; - application_resource_id: Uuid; + provider_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}'; + url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}/verify'; }; -export type UpdateApplicationErrors = { +export type VerifyOrganizationBillingProviderResponses = { /** - * RFC 9457 problem + * Organization billing provider credentials verified */ - 412: Problem; + 204: void; }; -export type UpdateApplicationError = UpdateApplicationErrors[keyof UpdateApplicationErrors]; +export type VerifyOrganizationBillingProviderResponse = VerifyOrganizationBillingProviderResponses[keyof VerifyOrganizationBillingProviderResponses]; -export type UpdateApplicationResponses = { +export type PublicConfigData = { + body?: never; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/public-config'; +}; + +export type PublicConfigResponses = { /** - * Application renamed + * Secret-free runtime configuration */ - 204: void; + 200: RuntimeConfig; }; -export type UpdateApplicationResponse = UpdateApplicationResponses[keyof UpdateApplicationResponses]; +export type PublicConfigResponse = PublicConfigResponses[keyof PublicConfigResponses]; -export type RestoreApplicationData = { +export type GetApplicationData = { body?: never; path: { - organization_id: Uuid; - application_resource_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/applications/{application_resource_id}/restore'; + url: '/v1/control/applications/{application_id}'; }; -export type RestoreApplicationResponses = { +export type GetApplicationResponses = { /** - * Application restored without restoring revoked credentials + * Application details */ - 204: void; + 200: Application; }; -export type RestoreApplicationResponse = RestoreApplicationResponses[keyof RestoreApplicationResponses]; +export type GetApplicationResponse = GetApplicationResponses[keyof GetApplicationResponses]; -export type RetireOrganizationData = { +export type GetApplicationStatisticsData = { body?: never; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}'; + url: '/v1/control/applications/{application_id}/statistics'; }; -export type RetireOrganizationResponses = { +export type GetApplicationStatisticsResponses = { /** - * Organization and active descendants retired + * Application identity, catalog, billing, and delivery counts */ - 204: void; + 200: ApplicationStatistics; }; -export type RetireOrganizationResponse = RetireOrganizationResponses[keyof RetireOrganizationResponses]; +export type GetApplicationStatisticsResponse = GetApplicationStatisticsResponses[keyof GetApplicationStatisticsResponses]; -export type GetOrganizationData = { - body?: never; +export type UpdatePublicApplicationConfigData = { + body: PublicApplicationConfig; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}'; + url: '/v1/control/applications/{application_id}/public-config'; }; -export type GetOrganizationResponses = { +export type UpdatePublicApplicationConfigErrors = { /** - * Organization details + * RFC 9457 problem + */ + 412: Problem; +}; + +export type UpdatePublicApplicationConfigError = UpdatePublicApplicationConfigErrors[keyof UpdatePublicApplicationConfigErrors]; + +export type UpdatePublicApplicationConfigResponses = { + /** + * Explicitly public runtime configuration replaced */ - 200: unknown; + 204: void; }; -export type UpdateOrganizationData = { - body: Rename; +export type UpdatePublicApplicationConfigResponse = UpdatePublicApplicationConfigResponses[keyof UpdatePublicApplicationConfigResponses]; + +export type UpdateInternalApplicationConfigData = { + body: InternalApplicationConfig; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}'; + url: '/v1/control/applications/{application_id}/internal-config'; }; -export type UpdateOrganizationErrors = { +export type UpdateInternalApplicationConfigErrors = { /** * RFC 9457 problem */ 412: Problem; }; -export type UpdateOrganizationError = UpdateOrganizationErrors[keyof UpdateOrganizationErrors]; +export type UpdateInternalApplicationConfigError = UpdateInternalApplicationConfigErrors[keyof UpdateInternalApplicationConfigErrors]; -export type UpdateOrganizationResponses = { +export type UpdateInternalApplicationConfigResponses = { /** - * Organization renamed + * Internal application policy updated and disabled credentials revoked */ 204: void; }; -export type UpdateOrganizationResponse = UpdateOrganizationResponses[keyof UpdateOrganizationResponses]; +export type UpdateInternalApplicationConfigResponse = UpdateInternalApplicationConfigResponses[keyof UpdateInternalApplicationConfigResponses]; -export type GetOrganizationPolicyData = { - body?: never; +export type UpdateAuthConfigData = { + body: ApplicationAuthConfig2; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/policy'; + url: '/v1/control/applications/{application_id}/auth-config'; }; -export type GetOrganizationPolicyResponses = { +export type UpdateAuthConfigResponses = { /** - * Organization policy and current usage + * Authentication configuration and PKCE application redirects updated */ - 200: OrganizationPolicy; + 204: void; }; -export type GetOrganizationPolicyResponse = GetOrganizationPolicyResponses[keyof GetOrganizationPolicyResponses]; +export type UpdateAuthConfigResponse = UpdateAuthConfigResponses[keyof UpdateAuthConfigResponses]; -export type RestoreOrganizationData = { - body?: never; +export type ConfigureGoogleProviderData = { + body: ConfigureAuthProviderWritable; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/restore'; + url: '/v1/control/applications/{application_id}/auth/providers/google'; }; -export type RestoreOrganizationResponses = { +export type ConfigureGoogleProviderResponses = { /** - * Organization restored; descendants remain retired + * Google client configured and callback URI returned */ - 204: void; + 200: AuthProvider; }; -export type RestoreOrganizationResponse = RestoreOrganizationResponses[keyof RestoreOrganizationResponses]; +export type ConfigureGoogleProviderResponse = ConfigureGoogleProviderResponses[keyof ConfigureGoogleProviderResponses]; -export type ListOrganizationMembersData = { - body?: never; +export type ConfigureAppleProviderData = { + body: ConfigureAuthProviderWritable; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/members'; + url: '/v1/control/applications/{application_id}/auth/providers/apple'; }; -export type ListOrganizationMembersResponses = { +export type ConfigureAppleProviderResponses = { /** - * Cursor page + * Apple client configured and callback URI returned */ - 200: Page; + 200: AuthProvider; }; -export type ListOrganizationMembersResponse = ListOrganizationMembersResponses[keyof ListOrganizationMembersResponses]; +export type ConfigureAppleProviderResponse = ConfigureAppleProviderResponses[keyof ConfigureAppleProviderResponses]; -export type DeleteOrganizationMemberData = { +export type ListApplicationAuthProvidersData = { body?: never; path: { - organization_id: Uuid; - member_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/members/{member_id}'; + url: '/v1/control/applications/{application_id}/auth/providers'; }; -export type DeleteOrganizationMemberResponses = { +export type ListApplicationAuthProvidersResponses = { /** - * Organization member removed + * Successful listApplicationAuthProviders response. */ - 204: void; + 200: AuthProviderPage; }; -export type DeleteOrganizationMemberResponse = DeleteOrganizationMemberResponses[keyof DeleteOrganizationMemberResponses]; +export type ListApplicationAuthProvidersResponse = ListApplicationAuthProvidersResponses[keyof ListApplicationAuthProvidersResponses]; -export type UpdateOrganizationMemberData = { - body: Object; +export type DisableApplicationAuthProviderData = { + body?: never; path: { - organization_id: Uuid; - member_id: Uuid; + application_id: Uuid; + provider: 'google' | 'apple'; }; query?: never; - url: '/v1/control/organizations/{organization_id}/members/{member_id}'; + url: '/v1/control/applications/{application_id}/auth/providers/{provider}'; }; -export type UpdateOrganizationMemberResponses = { +export type DisableApplicationAuthProviderResponses = { /** - * Organization role updated + * Application authentication provider disabled */ 204: void; }; -export type UpdateOrganizationMemberResponse = UpdateOrganizationMemberResponses[keyof UpdateOrganizationMemberResponses]; +export type DisableApplicationAuthProviderResponse = DisableApplicationAuthProviderResponses[keyof DisableApplicationAuthProviderResponses]; -export type ListOrganizationInvitationsData = { +export type ListApplicationDomainsData = { body?: never; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/invitations'; + url: '/v1/control/applications/{application_id}/domains'; }; -export type ListOrganizationInvitationsResponses = { +export type ListApplicationDomainsResponses = { /** - * Cursor page + * Successful listApplicationDomains response. */ - 200: Page; + 200: ApplicationDomainPage; }; -export type ListOrganizationInvitationsResponse = ListOrganizationInvitationsResponses[keyof ListOrganizationInvitationsResponses]; +export type ListApplicationDomainsResponse = ListApplicationDomainsResponses[keyof ListApplicationDomainsResponses]; -export type CreateOrganizationInvitationData = { - body: Object; +export type CreateApplicationDomainData = { + body: CreateApplicationDomain; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/invitations'; + url: '/v1/control/applications/{application_id}/domains'; }; -export type CreateOrganizationInvitationResponses = { +export type CreateApplicationDomainResponses = { /** - * Invitation queued and credential returned once + * Domain added and DNS proof returned once */ - 201: unknown; + 201: ApplicationDomain; }; -export type ResendOrganizationInvitationData = { +export type CreateApplicationDomainResponse = CreateApplicationDomainResponses[keyof CreateApplicationDomainResponses]; + +export type DeleteApplicationDomainData = { body?: never; path: { - organization_id: Uuid; - invitation_id: Uuid; + application_id: Uuid; + domain_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/invitations/{invitation_id}/resend'; + url: '/v1/control/applications/{application_id}/domains/{domain_id}'; }; -export type ResendOrganizationInvitationResponses = { +export type DeleteApplicationDomainResponses = { /** - * Invitation credential rotated and delivery queued + * Domain removed */ - 200: unknown; + 204: void; }; -export type RevokeOrganizationInvitationData = { +export type DeleteApplicationDomainResponse = DeleteApplicationDomainResponses[keyof DeleteApplicationDomainResponses]; + +export type VerifyApplicationDomainData = { body?: never; path: { - organization_id: Uuid; - invitation_id: Uuid; + application_id: Uuid; + domain_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/invitations/{invitation_id}'; + url: '/v1/control/applications/{application_id}/domains/{domain_id}/verify'; }; -export type RevokeOrganizationInvitationResponses = { +export type VerifyApplicationDomainResponses = { /** - * Pending invitation revoked + * DNS ownership verified */ 204: void; }; -export type RevokeOrganizationInvitationResponse = RevokeOrganizationInvitationResponses[keyof RevokeOrganizationInvitationResponses]; +export type VerifyApplicationDomainResponse = VerifyApplicationDomainResponses[keyof VerifyApplicationDomainResponses]; -export type ListOrganizationAuditLogsData = { +export type ListClientsData = { body?: never; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/audit-logs'; + url: '/v1/control/applications/{application_id}/clients'; }; -export type ListOrganizationAuditLogsResponses = { +export type ListClientsResponses = { /** - * Cursor page + * Successful listClients response. */ - 200: Page; + 200: OAuthClientPage; }; -export type ListOrganizationAuditLogsResponse = ListOrganizationAuditLogsResponses[keyof ListOrganizationAuditLogsResponses]; +export type ListClientsResponse = ListClientsResponses[keyof ListClientsResponses]; -export type ListOrganizationAuthProvidersData = { - body?: never; +export type CreateClientData = { + body: CreateClient; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/auth/providers'; + url: '/v1/control/applications/{application_id}/clients'; }; -export type ListOrganizationAuthProvidersResponses = { +export type CreateClientResponses = { /** - * Cursor page + * Client created and secret returned once when applicable */ - 200: Page; + 201: OAuthClient; }; -export type ListOrganizationAuthProvidersResponse = ListOrganizationAuthProvidersResponses[keyof ListOrganizationAuthProvidersResponses]; +export type CreateClientResponse = CreateClientResponses[keyof CreateClientResponses]; -export type DisableOrganizationAuthProviderData = { +export type DisableClientData = { body?: never; path: { - organization_id: Uuid; - provider: 'google' | 'apple'; + application_id: Uuid; + client_id: string; }; query?: never; - url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}'; + url: '/v1/control/applications/{application_id}/clients/{client_id}'; }; -export type DisableOrganizationAuthProviderResponses = { +export type DisableClientResponses = { /** - * Organization authentication provider disabled + * Client and active OAuth grants disabled */ 204: void; }; -export type DisableOrganizationAuthProviderResponse = DisableOrganizationAuthProviderResponses[keyof DisableOrganizationAuthProviderResponses]; +export type DisableClientResponse = DisableClientResponses[keyof DisableClientResponses]; -export type UpdateOrganizationAuthProviderData = { - body: ProviderInheritance; +export type GetClientData = { + body?: never; path: { - organization_id: Uuid; - provider: 'google' | 'apple'; + application_id: Uuid; + client_id: string; }; query?: never; - url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}'; + url: '/v1/control/applications/{application_id}/clients/{client_id}'; }; -export type UpdateOrganizationAuthProviderErrors = { +export type GetClientResponses = { /** - * RFC 9457 problem + * Client detail */ - 404: Problem; + 200: OAuthClient; }; -export type UpdateOrganizationAuthProviderError = UpdateOrganizationAuthProviderErrors[keyof UpdateOrganizationAuthProviderErrors]; +export type GetClientResponse = GetClientResponses[keyof GetClientResponses]; -export type UpdateOrganizationAuthProviderResponses = { +export type UpdateClientData = { + body: UpdateClient; + path: { + application_id: Uuid; + client_id: string; + }; + query?: never; + url: '/v1/control/applications/{application_id}/clients/{client_id}'; +}; + +export type UpdateClientResponses = { /** - * Organization authentication provider inheritance updated + * Client updated */ 204: void; }; -export type UpdateOrganizationAuthProviderResponse = UpdateOrganizationAuthProviderResponses[keyof UpdateOrganizationAuthProviderResponses]; +export type UpdateClientResponse = UpdateClientResponses[keyof UpdateClientResponses]; -export type ConfigureOrganizationAuthProviderData = { - body: Object; +export type RotateClientSecretData = { + body?: never; path: { - organization_id: Uuid; - provider: 'google' | 'apple'; + application_id: Uuid; + client_id: string; }; query?: never; - url: '/v1/control/organizations/{organization_id}/auth/providers/{provider}'; + url: '/v1/control/applications/{application_id}/clients/{client_id}/rotate-secret'; }; -export type ConfigureOrganizationAuthProviderResponses = { +export type RotateClientSecretResponses = { /** - * Organization authentication provider configured + * Replacement client secret returned once */ - 200: unknown; + 200: SecretCredential; }; -export type ListOrganizationNotificationProvidersData = { +export type RotateClientSecretResponse = RotateClientSecretResponses[keyof RotateClientSecretResponses]; + +export type ListRolesData = { body?: never; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/notification-providers'; + url: '/v1/control/applications/{application_id}/roles'; }; -export type ListOrganizationNotificationProvidersResponses = { +export type ListRolesResponses = { /** - * Cursor page + * Successful listRoles response. */ - 200: Page; + 200: RolePage; }; -export type ListOrganizationNotificationProvidersResponse = ListOrganizationNotificationProvidersResponses[keyof ListOrganizationNotificationProvidersResponses]; +export type ListRolesResponse = ListRolesResponses[keyof ListRolesResponses]; -export type CreateOrganizationNotificationProviderData = { - body: SmtpProvider; +export type CreateRoleData = { + body: CreateRole; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/notification-providers'; + url: '/v1/control/applications/{application_id}/roles'; }; -export type CreateOrganizationNotificationProviderResponses = { +export type CreateRoleErrors = { /** - * Organization SMTP provider stored + * RFC 9457 problem */ - 201: unknown; + 422: Problem; }; -export type DisableOrganizationNotificationProviderData = { +export type CreateRoleError = CreateRoleErrors[keyof CreateRoleErrors]; + +export type CreateRoleResponses = { + /** + * Role created + */ + 201: Role; +}; + +export type CreateRoleResponse = CreateRoleResponses[keyof CreateRoleResponses]; + +export type DeleteRoleData = { body?: never; path: { - organization_id: Uuid; - provider_id: Uuid; + application_id: Uuid; + role_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}'; + url: '/v1/control/applications/{application_id}/roles/{role_id}'; +}; + +export type DeleteRoleErrors = { + /** + * RFC 9457 problem + */ + 409: Problem; }; -export type DisableOrganizationNotificationProviderResponses = { +export type DeleteRoleError = DeleteRoleErrors[keyof DeleteRoleErrors]; + +export type DeleteRoleResponses = { /** - * Organization SMTP provider disabled + * Unassigned custom role deleted */ 204: void; }; -export type DisableOrganizationNotificationProviderResponse = DisableOrganizationNotificationProviderResponses[keyof DisableOrganizationNotificationProviderResponses]; +export type DeleteRoleResponse = DeleteRoleResponses[keyof DeleteRoleResponses]; -export type GetOrganizationNotificationProviderData = { +export type GetRoleData = { body?: never; path: { - organization_id: Uuid; - provider_id: Uuid; + application_id: Uuid; + role_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}'; + url: '/v1/control/applications/{application_id}/roles/{role_id}'; }; -export type GetOrganizationNotificationProviderResponses = { +export type GetRoleErrors = { /** - * Redacted organization SMTP provider + * RFC 9457 problem */ - 200: unknown; + 404: Problem; }; -export type UpdateOrganizationNotificationProviderData = { - body: Object; - path: { - organization_id: Uuid; - provider_id: Uuid; - }; - query?: never; - url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}'; -}; +export type GetRoleError = GetRoleErrors[keyof GetRoleErrors]; -export type UpdateOrganizationNotificationProviderResponses = { +export type GetRoleResponses = { /** - * Organization SMTP provider updated + * Role details */ - 200: unknown; + 200: Role; }; -export type VerifyOrganizationNotificationProviderData = { - body?: never; +export type GetRoleResponse = GetRoleResponses[keyof GetRoleResponses]; + +export type UpdateRoleData = { + body: UpdateRole; + headers: { + /** + * Current resource ETag. + */ + 'If-Match': string; + }; path: { - organization_id: Uuid; - provider_id: Uuid; + application_id: Uuid; + role_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}/verify'; + url: '/v1/control/applications/{application_id}/roles/{role_id}'; }; -export type VerifyOrganizationNotificationProviderResponses = { +export type UpdateRoleErrors = { /** - * Organization SMTP provider verified + * RFC 9457 problem */ - 204: void; + 409: Problem; + /** + * RFC 9457 problem + */ + 422: Problem; }; -export type VerifyOrganizationNotificationProviderResponse = VerifyOrganizationNotificationProviderResponses[keyof VerifyOrganizationNotificationProviderResponses]; - -export type TestOrganizationNotificationProviderData = { - body: Object; - headers?: { - 'Idempotency-Key'?: string; - }; - path: { - organization_id: Uuid; - provider_id: Uuid; - }; - query?: never; - url: '/v1/control/organizations/{organization_id}/notification-providers/{provider_id}/test'; -}; +export type UpdateRoleError = UpdateRoleErrors[keyof UpdateRoleErrors]; -export type TestOrganizationNotificationProviderResponses = { +export type UpdateRoleResponses = { /** - * Organization SMTP test queued + * Role updated */ - 202: unknown; + 204: void; }; -export type ListOrganizationBillingProvidersData = { +export type UpdateRoleResponse = UpdateRoleResponses[keyof UpdateRoleResponses]; + +export type ListWorkspacesData = { body?: never; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/billing/providers'; + url: '/v1/control/applications/{application_id}/workspaces'; }; -export type ListOrganizationBillingProvidersResponses = { +export type ListWorkspacesResponses = { /** - * Cursor page + * Successful listWorkspaces response. */ - 200: Page; + 200: WorkspacePage; }; -export type ListOrganizationBillingProvidersResponse = ListOrganizationBillingProvidersResponses[keyof ListOrganizationBillingProvidersResponses]; +export type ListWorkspacesResponse = ListWorkspacesResponses[keyof ListWorkspacesResponses]; -export type CreateOrganizationBillingProviderData = { - body: CreateBillingProviderWritable; +export type CreateWorkspaceData = { + body: CreateWorkspace; path: { - organization_id: Uuid; + application_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/billing/providers'; + url: '/v1/control/applications/{application_id}/workspaces'; }; -export type CreateOrganizationBillingProviderResponses = { +export type CreateWorkspaceResponses = { /** - * Organization billing provider configured + * Workspace created */ - 201: unknown; + 201: Workspace; }; -export type DisableOrganizationBillingProviderData = { +export type CreateWorkspaceResponse = CreateWorkspaceResponses[keyof CreateWorkspaceResponses]; + +export type DeleteWorkspaceData = { body?: never; path: { - organization_id: Uuid; - provider_id: Uuid; + application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}'; + url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}'; }; -export type DisableOrganizationBillingProviderResponses = { +export type DeleteWorkspaceErrors = { /** - * Organization billing provider disabled + * RFC 9457 problem + */ + 404: Problem; +}; + +export type DeleteWorkspaceError = DeleteWorkspaceErrors[keyof DeleteWorkspaceErrors]; + +export type DeleteWorkspaceResponses = { + /** + * Workspace retired and memberships removed */ 204: void; }; -export type DisableOrganizationBillingProviderResponse = DisableOrganizationBillingProviderResponses[keyof DisableOrganizationBillingProviderResponses]; +export type DeleteWorkspaceResponse = DeleteWorkspaceResponses[keyof DeleteWorkspaceResponses]; -export type GetOrganizationBillingProviderData = { +export type GetWorkspaceData = { body?: never; path: { - organization_id: Uuid; - provider_id: Uuid; + application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}'; + url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}'; }; -export type GetOrganizationBillingProviderResponses = { +export type GetWorkspaceResponses = { /** - * Secret-free organization billing provider + * Workspace details */ - 200: unknown; + 200: Workspace; }; -export type UpdateOrganizationBillingProviderData = { - body: Object; +export type GetWorkspaceResponse = GetWorkspaceResponses[keyof GetWorkspaceResponses]; + +export type UpdateWorkspaceData = { + body: UpdateWorkspace; path: { - organization_id: Uuid; - provider_id: Uuid; + application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}'; + url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}'; }; -export type UpdateOrganizationBillingProviderResponses = { +export type UpdateWorkspaceResponses = { /** - * Organization billing provider updated + * Workspace updated */ 204: void; }; -export type UpdateOrganizationBillingProviderResponse = UpdateOrganizationBillingProviderResponses[keyof UpdateOrganizationBillingProviderResponses]; +export type UpdateWorkspaceResponse = UpdateWorkspaceResponses[keyof UpdateWorkspaceResponses]; -export type VerifyOrganizationBillingProviderData = { - body?: never; +export type RecoverWorkspaceOwnershipData = { + body: OwnershipTransfer2; path: { - organization_id: Uuid; - provider_id: Uuid; + application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/control/organizations/{organization_id}/billing/providers/{provider_id}/verify'; + url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/owner-transfer'; }; -export type VerifyOrganizationBillingProviderResponses = { +export type RecoverWorkspaceOwnershipResponses = { /** - * Organization billing provider credentials verified + * Workspace ownership transferred atomically */ - 204: void; + 200: OwnershipTransferResult; }; -export type VerifyOrganizationBillingProviderResponse = VerifyOrganizationBillingProviderResponses[keyof VerifyOrganizationBillingProviderResponses]; +export type RecoverWorkspaceOwnershipResponse = RecoverWorkspaceOwnershipResponses[keyof RecoverWorkspaceOwnershipResponses]; -export type PublicConfigData = { +export type ListWorkspaceMembersData = { body?: never; path: { application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/public-config'; + url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members'; }; -export type PublicConfigResponses = { +export type ListWorkspaceMembersResponses = { /** - * Secret-free runtime configuration + * Successful listWorkspaceMembers response. */ - 200: RuntimeConfig; + 200: WorkspaceMemberPage; }; -export type PublicConfigResponse = PublicConfigResponses[keyof PublicConfigResponses]; +export type ListWorkspaceMembersResponse = ListWorkspaceMembersResponses[keyof ListWorkspaceMembersResponses]; -export type GetApplicationData = { +export type DeleteWorkspaceMemberData = { body?: never; path: { application_id: Uuid; + workspace_id: Uuid; + user_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}'; + url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; }; -export type GetApplicationResponses = { +export type DeleteWorkspaceMemberResponses = { /** - * Application details + * Workspace membership removed */ - 200: unknown; + 204: void; }; -export type GetApplicationStatisticsData = { - body?: never; +export type DeleteWorkspaceMemberResponse = DeleteWorkspaceMemberResponses[keyof DeleteWorkspaceMemberResponses]; + +export type ReplaceWorkspaceMemberRolesData = { + body: ReplaceWorkspaceMemberRoles; path: { application_id: Uuid; + workspace_id: Uuid; + user_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/statistics'; + url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; }; -export type GetApplicationStatisticsResponses = { +export type ReplaceWorkspaceMemberRolesResponses = { /** - * Application identity, catalog, billing, and delivery counts + * Workspace member roles replaced atomically */ - 200: unknown; + 200: WorkspaceMember; }; -export type UpdatePublicApplicationConfigData = { - body: PublicApplicationConfig; +export type ReplaceWorkspaceMemberRolesResponse = ReplaceWorkspaceMemberRolesResponses[keyof ReplaceWorkspaceMemberRolesResponses]; + +export type ListRoleAssignmentsData = { + body?: never; path: { application_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/public-config'; -}; - -export type UpdatePublicApplicationConfigErrors = { - /** - * RFC 9457 problem - */ - 412: Problem; + url: '/v1/control/applications/{application_id}/role-assignments'; }; -export type UpdatePublicApplicationConfigError = UpdatePublicApplicationConfigErrors[keyof UpdatePublicApplicationConfigErrors]; - -export type UpdatePublicApplicationConfigResponses = { +export type ListRoleAssignmentsResponses = { /** - * Explicitly public runtime configuration replaced + * Successful listRoleAssignments response. */ - 204: void; + 200: RoleAssignmentPage; }; -export type UpdatePublicApplicationConfigResponse = UpdatePublicApplicationConfigResponses[keyof UpdatePublicApplicationConfigResponses]; +export type ListRoleAssignmentsResponse = ListRoleAssignmentsResponses[keyof ListRoleAssignmentsResponses]; -export type UpdateInternalApplicationConfigData = { - body: InternalApplicationConfig; +export type CreateRoleAssignmentData = { + body: RoleAssignment2; path: { application_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/internal-config'; -}; - -export type UpdateInternalApplicationConfigErrors = { - /** - * RFC 9457 problem - */ - 412: Problem; + url: '/v1/control/applications/{application_id}/role-assignments'; }; -export type UpdateInternalApplicationConfigError = UpdateInternalApplicationConfigErrors[keyof UpdateInternalApplicationConfigErrors]; - -export type UpdateInternalApplicationConfigResponses = { +export type CreateRoleAssignmentResponses = { /** - * Internal application policy updated and disabled credentials revoked + * User or machine-client role assignment created */ - 204: void; + 201: RoleAssignmentRecord; }; -export type UpdateInternalApplicationConfigResponse = UpdateInternalApplicationConfigResponses[keyof UpdateInternalApplicationConfigResponses]; +export type CreateRoleAssignmentResponse = CreateRoleAssignmentResponses[keyof CreateRoleAssignmentResponses]; -export type UpdateAuthConfigData = { - body: ApplicationAuthConfig2; +export type DeleteRoleAssignmentData = { + body?: never; path: { application_id: Uuid; + assignment_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/auth-config'; + url: '/v1/control/applications/{application_id}/role-assignments/{assignment_id}'; }; -export type UpdateAuthConfigResponses = { +export type DeleteRoleAssignmentResponses = { /** - * Authentication configuration and PKCE application redirects updated + * Role assignment deleted */ 204: void; }; -export type UpdateAuthConfigResponse = UpdateAuthConfigResponses[keyof UpdateAuthConfigResponses]; +export type DeleteRoleAssignmentResponse = DeleteRoleAssignmentResponses[keyof DeleteRoleAssignmentResponses]; -export type ConfigureGoogleProviderData = { - body: Object; +export type ListControlPermissionGrantsData = { + body?: never; path: { application_id: Uuid; }; - query?: never; - url: '/v1/control/applications/{application_id}/auth/providers/google'; + query?: { + subject_type?: 'user' | 'client'; + subject_id?: Uuid; + /** + * Explicit accessible workspace whose grants are merged with the current user's grants. + */ + workspace_id?: Uuid; + status?: 'active' | 'revoked'; + }; + url: '/v1/control/applications/{application_id}/permission-grants'; }; -export type ConfigureGoogleProviderResponses = { +export type ListControlPermissionGrantsResponses = { /** - * Google client configured and callback URI returned + * Successful listControlPermissionGrants response. */ - 200: unknown; + 200: PermissionGrantPage; }; -export type ConfigureAppleProviderData = { - body: Object; +export type ListControlPermissionGrantsResponse = ListControlPermissionGrantsResponses[keyof ListControlPermissionGrantsResponses]; + +export type CreateControlPermissionGrantData = { + body: PermissionGrantBody; + headers: { + 'Idempotency-Key': string; + }; path: { application_id: Uuid; }; - query?: never; - url: '/v1/control/applications/{application_id}/auth/providers/apple'; + query?: { + subject_type?: 'user' | 'client'; + subject_id?: Uuid; + /** + * Explicit accessible workspace whose grants are merged with the current user's grants. + */ + workspace_id?: Uuid; + status?: 'active' | 'revoked'; + }; + url: '/v1/control/applications/{application_id}/permission-grants'; }; -export type ConfigureAppleProviderResponses = { +export type CreateControlPermissionGrantErrors = { /** - * Apple client configured and callback URI returned + * RFC 9457 problem + */ + 422: Problem; +}; + +export type CreateControlPermissionGrantError = CreateControlPermissionGrantErrors[keyof CreateControlPermissionGrantErrors]; + +export type CreateControlPermissionGrantResponses = { + /** + * Direct permission grant created */ - 200: unknown; + 201: PermissionGrant; }; -export type ListApplicationAuthProvidersData = { +export type CreateControlPermissionGrantResponse = CreateControlPermissionGrantResponses[keyof CreateControlPermissionGrantResponses]; + +export type GetControlEffectiveAccessData = { body?: never; path: { application_id: Uuid; }; - query?: never; - url: '/v1/control/applications/{application_id}/auth/providers'; + query: { + subject_type: 'user' | 'client'; + subject_id: Uuid; + /** + * Explicit accessible workspace whose grants are merged with the current user's grants. + */ + workspace_id?: Uuid; + }; + url: '/v1/control/applications/{application_id}/permission-grants/effective'; }; -export type ListApplicationAuthProvidersResponses = { +export type GetControlEffectiveAccessResponses = { /** - * Cursor page + * Effective roles and scopes */ - 200: Page; + 200: EffectiveAccess; }; -export type ListApplicationAuthProvidersResponse = ListApplicationAuthProvidersResponses[keyof ListApplicationAuthProvidersResponses]; +export type GetControlEffectiveAccessResponse = GetControlEffectiveAccessResponses[keyof GetControlEffectiveAccessResponses]; -export type DisableApplicationAuthProviderData = { +export type RevokeControlPermissionGrantData = { body?: never; + headers: { + /** + * Current resource ETag. + */ + 'If-Match': string; + }; path: { application_id: Uuid; - provider: 'google' | 'apple'; + grant_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/auth/providers/{provider}'; + url: '/v1/control/applications/{application_id}/permission-grants/{grant_id}'; }; -export type DisableApplicationAuthProviderResponses = { +export type RevokeControlPermissionGrantErrors = { /** - * Application authentication provider disabled + * RFC 9457 problem + */ + 409: Problem; +}; + +export type RevokeControlPermissionGrantError = RevokeControlPermissionGrantErrors[keyof RevokeControlPermissionGrantErrors]; + +export type RevokeControlPermissionGrantResponses = { + /** + * Direct permission grant revoked */ 204: void; }; -export type DisableApplicationAuthProviderResponse = DisableApplicationAuthProviderResponses[keyof DisableApplicationAuthProviderResponses]; +export type RevokeControlPermissionGrantResponse = RevokeControlPermissionGrantResponses[keyof RevokeControlPermissionGrantResponses]; -export type ListApplicationDomainsData = { +export type GetControlPermissionGrantData = { body?: never; path: { application_id: Uuid; + grant_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/domains'; + url: '/v1/control/applications/{application_id}/permission-grants/{grant_id}'; }; -export type ListApplicationDomainsResponses = { +export type GetControlPermissionGrantResponses = { /** - * Cursor page + * Direct permission grant */ - 200: Page; + 200: PermissionGrant; }; -export type ListApplicationDomainsResponse = ListApplicationDomainsResponses[keyof ListApplicationDomainsResponses]; +export type GetControlPermissionGrantResponse = GetControlPermissionGrantResponses[keyof GetControlPermissionGrantResponses]; -export type CreateApplicationDomainData = { - body: Object; +export type ListDelegationsData = { + body?: never; path: { application_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/domains'; + url: '/v1/control/applications/{application_id}/delegations'; }; -export type CreateApplicationDomainResponses = { +export type ListDelegationsResponses = { /** - * Domain added and DNS proof returned once + * Successful listDelegations response. */ - 201: unknown; + 200: DelegationPage; }; -export type DeleteApplicationDomainData = { - body?: never; +export type ListDelegationsResponse = ListDelegationsResponses[keyof ListDelegationsResponses]; + +export type CreateDelegationData = { + body: CreateDelegation; path: { application_id: Uuid; - domain_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/domains/{domain_id}'; + url: '/v1/control/applications/{application_id}/delegations'; }; -export type DeleteApplicationDomainResponses = { +export type CreateDelegationResponses = { /** - * Domain removed + * Short-lived one-time delegation exchange credential */ - 204: void; + 201: Delegation; }; -export type DeleteApplicationDomainResponse = DeleteApplicationDomainResponses[keyof DeleteApplicationDomainResponses]; +export type CreateDelegationResponse = CreateDelegationResponses[keyof CreateDelegationResponses]; -export type VerifyApplicationDomainData = { +export type GetDelegationData = { body?: never; path: { application_id: Uuid; - domain_id: Uuid; + delegation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/domains/{domain_id}/verify'; + url: '/v1/control/applications/{application_id}/delegations/{delegation_id}'; }; -export type VerifyApplicationDomainResponses = { +export type GetDelegationResponses = { /** - * DNS ownership verified + * Delegation details and lifecycle state */ - 204: void; + 200: Delegation; }; -export type VerifyApplicationDomainResponse = VerifyApplicationDomainResponses[keyof VerifyApplicationDomainResponses]; +export type GetDelegationResponse = GetDelegationResponses[keyof GetDelegationResponses]; -export type ListClientsData = { - body?: never; +export type ExchangeDelegationData = { + body: ExchangeDelegation; path: { application_id: Uuid; + delegation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/clients'; + url: '/v1/applications/{application_id}/delegations/{delegation_id}/exchange'; }; -export type ListClientsResponses = { +export type ExchangeDelegationResponses = { /** - * Cursor page + * Non-refreshable delegated access token */ - 200: Page; + 200: TokenResponse; }; -export type ListClientsResponse = ListClientsResponses[keyof ListClientsResponses]; +export type ExchangeDelegationResponse = ExchangeDelegationResponses[keyof ExchangeDelegationResponses]; -export type CreateClientData = { - body: Object; +export type SendMachineNotificationData = { + body: QueueNotification; + headers: { + 'Idempotency-Key': string; + }; path: { application_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/clients'; + url: '/v1/applications/{application_id}/notifications'; }; -export type CreateClientResponses = { +export type SendMachineNotificationErrors = { /** - * Client created and secret returned once when applicable + * RFC 9457 problem */ - 201: unknown; + 403: Problem; }; -export type DisableClientData = { - body?: never; - path: { - application_id: Uuid; - client_id: string; - }; - query?: never; - url: '/v1/control/applications/{application_id}/clients/{client_id}'; -}; +export type SendMachineNotificationError = SendMachineNotificationErrors[keyof SendMachineNotificationErrors]; -export type DisableClientResponses = { +export type SendMachineNotificationResponses = { /** - * Client and active OAuth grants disabled + * Notification queued or suppressed */ - 204: void; + 202: QueuedNotification; }; -export type DisableClientResponse = DisableClientResponses[keyof DisableClientResponses]; +export type SendMachineNotificationResponse = SendMachineNotificationResponses[keyof SendMachineNotificationResponses]; -export type UpdateClientData = { - body: Object; +export type ListPermissionGrantsData = { + body?: never; path: { application_id: Uuid; - client_id: string; }; - query?: never; - url: '/v1/control/applications/{application_id}/clients/{client_id}'; + query?: { + subject_type?: 'user' | 'client'; + subject_id?: Uuid; + /** + * Explicit accessible workspace whose grants are merged with the current user's grants. + */ + workspace_id?: Uuid; + status?: 'active' | 'revoked'; + }; + url: '/v1/applications/{application_id}/permission-grants'; }; -export type UpdateClientResponses = { +export type ListPermissionGrantsErrors = { /** - * Client updated + * RFC 9457 problem */ - 204: void; + 403: Problem; }; -export type UpdateClientResponse = UpdateClientResponses[keyof UpdateClientResponses]; +export type ListPermissionGrantsError = ListPermissionGrantsErrors[keyof ListPermissionGrantsErrors]; -export type RotateClientSecretData = { - body?: never; +export type ListPermissionGrantsResponses = { + /** + * Successful listPermissionGrants response. + */ + 200: PermissionGrantPage; +}; + +export type ListPermissionGrantsResponse = ListPermissionGrantsResponses[keyof ListPermissionGrantsResponses]; + +export type CreatePermissionGrantData = { + body: PermissionGrantBody; + headers: { + 'Idempotency-Key': string; + }; path: { application_id: Uuid; - client_id: string; }; - query?: never; - url: '/v1/control/applications/{application_id}/clients/{client_id}/rotate-secret'; + query?: { + subject_type?: 'user' | 'client'; + subject_id?: Uuid; + /** + * Explicit accessible workspace whose grants are merged with the current user's grants. + */ + workspace_id?: Uuid; + status?: 'active' | 'revoked'; + }; + url: '/v1/applications/{application_id}/permission-grants'; }; -export type RotateClientSecretResponses = { +export type CreatePermissionGrantErrors = { /** - * Replacement client secret returned once + * RFC 9457 problem + */ + 403: Problem; + /** + * RFC 9457 problem */ - 200: unknown; + 422: Problem; }; -export type ListRolesData = { - body?: never; - path: { - application_id: Uuid; - }; - query?: never; - url: '/v1/control/applications/{application_id}/roles'; -}; +export type CreatePermissionGrantError = CreatePermissionGrantErrors[keyof CreatePermissionGrantErrors]; -export type ListRolesResponses = { +export type CreatePermissionGrantResponses = { /** - * Cursor page + * Direct permission grant created */ - 200: Page; + 201: PermissionGrant; }; -export type ListRolesResponse = ListRolesResponses[keyof ListRolesResponses]; +export type CreatePermissionGrantResponse = CreatePermissionGrantResponses[keyof CreatePermissionGrantResponses]; -export type CreateRoleData = { - body: Object; +export type GetEffectiveAccessData = { + body?: never; path: { application_id: Uuid; }; - query?: never; - url: '/v1/control/applications/{application_id}/roles'; + query: { + subject_type: 'user' | 'client'; + subject_id: Uuid; + /** + * Explicit accessible workspace whose grants are merged with the current user's grants. + */ + workspace_id?: Uuid; + }; + url: '/v1/applications/{application_id}/permission-grants/effective'; }; -export type CreateRoleResponses = { +export type GetEffectiveAccessErrors = { /** - * Role created + * RFC 9457 problem */ - 201: unknown; + 403: Problem; }; -export type DeleteRoleData = { +export type GetEffectiveAccessError = GetEffectiveAccessErrors[keyof GetEffectiveAccessErrors]; + +export type GetEffectiveAccessResponses = { + /** + * Effective roles and scopes + */ + 200: EffectiveAccess; +}; + +export type GetEffectiveAccessResponse = GetEffectiveAccessResponses[keyof GetEffectiveAccessResponses]; + +export type RevokePermissionGrantData = { body?: never; + headers: { + /** + * Current resource ETag. + */ + 'If-Match': string; + }; path: { application_id: Uuid; - role_id: Uuid; + grant_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/roles/{role_id}'; + url: '/v1/applications/{application_id}/permission-grants/{grant_id}'; }; -export type DeleteRoleErrors = { +export type RevokePermissionGrantErrors = { /** * RFC 9457 problem */ 409: Problem; }; -export type DeleteRoleError = DeleteRoleErrors[keyof DeleteRoleErrors]; +export type RevokePermissionGrantError = RevokePermissionGrantErrors[keyof RevokePermissionGrantErrors]; -export type DeleteRoleResponses = { +export type RevokePermissionGrantResponses = { /** - * Unassigned custom role deleted + * Direct permission grant revoked */ 204: void; }; -export type DeleteRoleResponse = DeleteRoleResponses[keyof DeleteRoleResponses]; +export type RevokePermissionGrantResponse = RevokePermissionGrantResponses[keyof RevokePermissionGrantResponses]; -export type GetRoleData = { +export type GetPermissionGrantData = { body?: never; path: { application_id: Uuid; - role_id: Uuid; + grant_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/roles/{role_id}'; + url: '/v1/applications/{application_id}/permission-grants/{grant_id}'; }; -export type GetRoleErrors = { +export type GetPermissionGrantResponses = { /** - * RFC 9457 problem + * Direct permission grant */ - 404: Problem; + 200: PermissionGrant; }; -export type GetRoleError = GetRoleErrors[keyof GetRoleErrors]; - -export type GetRoleResponses = { - /** - * Role details - */ - 200: unknown; -}; +export type GetPermissionGrantResponse = GetPermissionGrantResponses[keyof GetPermissionGrantResponses]; -export type UpdateRoleData = { - body: Object; +export type ListApplicationInvitationsData = { + body?: never; path: { application_id: Uuid; - role_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/roles/{role_id}'; + url: '/v1/applications/{application_id}/invitations'; }; -export type UpdateRoleErrors = { +export type ListApplicationInvitationsResponses = { /** - * RFC 9457 problem + * Successful listApplicationInvitations response. */ - 409: Problem; + 200: ApplicationInvitationPage; }; -export type UpdateRoleError = UpdateRoleErrors[keyof UpdateRoleErrors]; +export type ListApplicationInvitationsResponse = ListApplicationInvitationsResponses[keyof ListApplicationInvitationsResponses]; -export type UpdateRoleResponses = { +export type CreateApplicationInvitationMachineData = { + body: CreateInvitation; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/invitations'; +}; + +export type CreateApplicationInvitationMachineResponses = { /** - * Role updated + * Invitation created and email queued */ - 204: void; + 201: ApplicationInvitation; }; -export type UpdateRoleResponse = UpdateRoleResponses[keyof UpdateRoleResponses]; +export type CreateApplicationInvitationMachineResponse = CreateApplicationInvitationMachineResponses[keyof CreateApplicationInvitationMachineResponses]; -export type ListWorkspacesData = { +export type RevokeApplicationInvitationData = { body?: never; path: { application_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces'; + url: '/v1/applications/{application_id}/invitations/{invitation_id}'; }; -export type ListWorkspacesResponses = { +export type RevokeApplicationInvitationResponses = { /** - * Cursor page + * Pending invitation revoked */ - 200: Page; + 204: void; }; -export type ListWorkspacesResponse = ListWorkspacesResponses[keyof ListWorkspacesResponses]; +export type RevokeApplicationInvitationResponse = RevokeApplicationInvitationResponses[keyof RevokeApplicationInvitationResponses]; -export type CreateWorkspaceData = { - body: Object; +export type GetApplicationInvitationData = { + body?: never; path: { application_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces'; + url: '/v1/applications/{application_id}/invitations/{invitation_id}'; }; -export type CreateWorkspaceResponses = { +export type GetApplicationInvitationResponses = { /** - * Workspace created + * Invitation detail */ - 201: unknown; + 200: ApplicationInvitation; }; -export type DeleteWorkspaceData = { +export type GetApplicationInvitationResponse = GetApplicationInvitationResponses[keyof GetApplicationInvitationResponses]; + +export type ResendApplicationInvitationData = { body?: never; path: { application_id: Uuid; - workspace_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}'; + url: '/v1/applications/{application_id}/invitations/{invitation_id}/resend'; }; -export type DeleteWorkspaceErrors = { +export type ResendApplicationInvitationErrors = { /** * RFC 9457 problem */ - 404: Problem; + 429: Problem; }; -export type DeleteWorkspaceError = DeleteWorkspaceErrors[keyof DeleteWorkspaceErrors]; +export type ResendApplicationInvitationError = ResendApplicationInvitationErrors[keyof ResendApplicationInvitationErrors]; -export type DeleteWorkspaceResponses = { +export type ResendApplicationInvitationResponses = { /** - * Workspace retired and memberships removed + * Invitation credentials rotated and email queued */ - 204: void; + 202: InvitationResent; }; -export type DeleteWorkspaceResponse = DeleteWorkspaceResponses[keyof DeleteWorkspaceResponses]; +export type ResendApplicationInvitationResponse = ResendApplicationInvitationResponses[keyof ResendApplicationInvitationResponses]; -export type GetWorkspaceData = { +export type ServiceListApplicationUsersData = { body?: never; path: { application_id: Uuid; - workspace_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}'; + url: '/v1/applications/{application_id}/users'; }; -export type GetWorkspaceResponses = { +export type ServiceListApplicationUsersErrors = { /** - * Workspace details + * RFC 9457 problem */ - 200: unknown; + 403: Problem; }; -export type UpdateWorkspaceData = { - body: Object; - path: { - application_id: Uuid; - workspace_id: Uuid; - }; - query?: never; - url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}'; -}; +export type ServiceListApplicationUsersError = ServiceListApplicationUsersErrors[keyof ServiceListApplicationUsersErrors]; -export type UpdateWorkspaceResponses = { +export type ServiceListApplicationUsersResponses = { /** - * Workspace updated + * Successful serviceListApplicationUsers response. */ - 204: void; + 200: UserPage; }; -export type UpdateWorkspaceResponse = UpdateWorkspaceResponses[keyof UpdateWorkspaceResponses]; +export type ServiceListApplicationUsersResponse = ServiceListApplicationUsersResponses[keyof ServiceListApplicationUsersResponses]; -export type RecoverWorkspaceOwnershipData = { - body: OwnershipTransfer2; +export type ServiceGetApplicationUserData = { + body?: never; path: { application_id: Uuid; - workspace_id: Uuid; + user_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/owner-transfer'; + url: '/v1/applications/{application_id}/users/{user_id}'; }; -export type RecoverWorkspaceOwnershipResponses = { +export type ServiceGetApplicationUserErrors = { /** - * Workspace ownership transferred atomically + * RFC 9457 problem */ - 200: OwnershipTransferResult; + 403: Problem; }; -export type RecoverWorkspaceOwnershipResponse = RecoverWorkspaceOwnershipResponses[keyof RecoverWorkspaceOwnershipResponses]; +export type ServiceGetApplicationUserError = ServiceGetApplicationUserErrors[keyof ServiceGetApplicationUserErrors]; -export type ListWorkspaceMembersData = { +export type ServiceGetApplicationUserResponses = { + /** + * Redacted application user + */ + 200: User; +}; + +export type ServiceGetApplicationUserResponse = ServiceGetApplicationUserResponses[keyof ServiceGetApplicationUserResponses]; + +export type ServiceListApplicationWorkspacesData = { body?: never; path: { application_id: Uuid; - workspace_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members'; + url: '/v1/applications/{application_id}/workspaces'; }; -export type ListWorkspaceMembersResponses = { +export type ServiceListApplicationWorkspacesErrors = { + /** + * RFC 9457 problem + */ + 403: Problem; +}; + +export type ServiceListApplicationWorkspacesError = ServiceListApplicationWorkspacesErrors[keyof ServiceListApplicationWorkspacesErrors]; + +export type ServiceListApplicationWorkspacesResponses = { /** - * Cursor page + * Successful serviceListApplicationWorkspaces response. */ - 200: Page; + 200: WorkspacePage; }; -export type ListWorkspaceMembersResponse = ListWorkspaceMembersResponses[keyof ListWorkspaceMembersResponses]; +export type ServiceListApplicationWorkspacesResponse = ServiceListApplicationWorkspacesResponses[keyof ServiceListApplicationWorkspacesResponses]; -export type DeleteWorkspaceMemberData = { +export type ServiceGetApplicationWorkspaceData = { body?: never; path: { application_id: Uuid; workspace_id: Uuid; - user_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; + url: '/v1/applications/{application_id}/service/workspaces/{workspace_id}'; }; -export type DeleteWorkspaceMemberResponses = { +export type ServiceGetApplicationWorkspaceErrors = { /** - * Workspace membership removed + * RFC 9457 problem */ - 204: void; + 403: Problem; }; -export type DeleteWorkspaceMemberResponse = DeleteWorkspaceMemberResponses[keyof DeleteWorkspaceMemberResponses]; +export type ServiceGetApplicationWorkspaceError = ServiceGetApplicationWorkspaceErrors[keyof ServiceGetApplicationWorkspaceErrors]; -export type ReplaceWorkspaceMemberRolesData = { - body: Object; +export type ServiceGetApplicationWorkspaceResponses = { + /** + * Workspace detail + */ + 200: Workspace; +}; + +export type ServiceGetApplicationWorkspaceResponse = ServiceGetApplicationWorkspaceResponses[keyof ServiceGetApplicationWorkspaceResponses]; + +export type ServiceListApplicationWorkspaceAccessData = { + body?: never; path: { application_id: Uuid; workspace_id: Uuid; - user_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; + url: '/v1/applications/{application_id}/service/workspaces/{workspace_id}/access'; }; -export type ReplaceWorkspaceMemberRolesResponses = { +export type ServiceListApplicationWorkspaceAccessErrors = { /** - * Workspace member roles replaced atomically + * RFC 9457 problem */ - 200: unknown; + 403: Problem; }; -export type ListRoleAssignmentsData = { - body?: never; - path: { - application_id: Uuid; - }; - query?: never; - url: '/v1/control/applications/{application_id}/role-assignments'; -}; +export type ServiceListApplicationWorkspaceAccessError = ServiceListApplicationWorkspaceAccessErrors[keyof ServiceListApplicationWorkspaceAccessErrors]; -export type ListRoleAssignmentsResponses = { +export type ServiceListApplicationWorkspaceAccessResponses = { /** - * Cursor page + * Successful serviceListApplicationWorkspaceAccess response. */ - 200: Page; + 200: WorkspaceAccessPage; }; -export type ListRoleAssignmentsResponse = ListRoleAssignmentsResponses[keyof ListRoleAssignmentsResponses]; +export type ServiceListApplicationWorkspaceAccessResponse = ServiceListApplicationWorkspaceAccessResponses[keyof ServiceListApplicationWorkspaceAccessResponses]; -export type CreateRoleAssignmentData = { - body: RoleAssignment2; +export type ServiceGetSubjectEntitlementsData = { + body?: never; path: { application_id: Uuid; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/role-assignments'; + url: '/v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/entitlements'; }; -export type CreateRoleAssignmentResponses = { +export type ServiceGetSubjectEntitlementsErrors = { /** - * User or machine-client role assignment created + * RFC 9457 problem */ - 201: unknown; + 403: Problem; }; -export type DeleteRoleAssignmentData = { - body?: never; - path: { - application_id: Uuid; - assignment_id: Uuid; - }; - query?: never; - url: '/v1/control/applications/{application_id}/role-assignments/{assignment_id}'; -}; +export type ServiceGetSubjectEntitlementsError = ServiceGetSubjectEntitlementsErrors[keyof ServiceGetSubjectEntitlementsErrors]; -export type DeleteRoleAssignmentResponses = { +export type ServiceGetSubjectEntitlementsResponses = { /** - * Role assignment deleted + * Successful serviceGetSubjectEntitlements response. */ - 204: void; + 200: EntitlementGrantPage; }; -export type DeleteRoleAssignmentResponse = DeleteRoleAssignmentResponses[keyof DeleteRoleAssignmentResponses]; +export type ServiceGetSubjectEntitlementsResponse = ServiceGetSubjectEntitlementsResponses[keyof ServiceGetSubjectEntitlementsResponses]; -export type ListDelegationsData = { +export type ServiceGetSubjectBillingData = { body?: never; path: { application_id: Uuid; + subject_type: 'user' | 'workspace'; + subject_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/delegations'; + url: '/v1/applications/{application_id}/subjects/{subject_type}/{subject_id}/billing'; }; -export type ListDelegationsResponses = { +export type ServiceGetSubjectBillingErrors = { /** - * Cursor page + * RFC 9457 problem */ - 200: Page; + 403: Problem; }; -export type ListDelegationsResponse = ListDelegationsResponses[keyof ListDelegationsResponses]; - -export type CreateDelegationData = { - body: Object; - path: { - application_id: Uuid; - }; - query?: never; - url: '/v1/control/applications/{application_id}/delegations'; -}; +export type ServiceGetSubjectBillingError = ServiceGetSubjectBillingErrors[keyof ServiceGetSubjectBillingErrors]; -export type CreateDelegationResponses = { +export type ServiceGetSubjectBillingResponses = { /** - * Short-lived one-time delegation exchange credential + * Subject billing profile and subscription summary */ - 201: unknown; + 200: BillingSummary; }; -export type GetDelegationData = { +export type ServiceGetSubjectBillingResponse = ServiceGetSubjectBillingResponses[keyof ServiceGetSubjectBillingResponses]; + +export type RevokeDelegationData = { body?: never; path: { application_id: Uuid; delegation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/delegations/{delegation_id}'; + url: '/v1/control/applications/{application_id}/delegations/{delegation_id}/revoke'; }; -export type GetDelegationResponses = { +export type RevokeDelegationResponses = { /** - * Delegation details and lifecycle state + * Delegation and delegated sessions revoked */ - 200: unknown; + 204: void; }; -export type ExchangeDelegationData = { - body: Object; +export type RevokeDelegationResponse = RevokeDelegationResponses[keyof RevokeDelegationResponses]; + +export type ListApplicationInvitationsControlData = { + body?: never; path: { application_id: Uuid; - delegation_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/delegations/{delegation_id}/exchange'; + url: '/v1/control/applications/{application_id}/invitations'; }; -export type ExchangeDelegationResponses = { +export type ListApplicationInvitationsControlResponses = { /** - * Non-refreshable delegated access token + * Successful listApplicationInvitationsControl response. */ - 200: unknown; + 200: ApplicationInvitationPage; }; -export type RevokeDelegationData = { - body?: never; +export type ListApplicationInvitationsControlResponse = ListApplicationInvitationsControlResponses[keyof ListApplicationInvitationsControlResponses]; + +export type CreateApplicationInvitationControlData = { + body: CreateInvitation; path: { application_id: Uuid; - delegation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/delegations/{delegation_id}/revoke'; + url: '/v1/control/applications/{application_id}/invitations'; }; -export type RevokeDelegationResponses = { +export type CreateApplicationInvitationControlResponses = { /** - * Delegation and delegated sessions revoked + * Application or workspace invitation created and email queued */ - 204: void; + 201: ApplicationInvitation; }; -export type RevokeDelegationResponse = RevokeDelegationResponses[keyof RevokeDelegationResponses]; +export type CreateApplicationInvitationControlResponse = CreateApplicationInvitationControlResponses[keyof CreateApplicationInvitationControlResponses]; -export type ListWorkspaceInvitationsData = { +export type RevokeApplicationInvitationControlData = { body?: never; path: { application_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspace-invitations'; + url: '/v1/control/applications/{application_id}/invitations/{invitation_id}'; }; -export type ListWorkspaceInvitationsResponses = { +export type RevokeApplicationInvitationControlResponses = { /** - * Cursor page + * Pending invitation revoked */ - 200: Page; + 204: void; }; -export type ListWorkspaceInvitationsResponse = ListWorkspaceInvitationsResponses[keyof ListWorkspaceInvitationsResponses]; +export type RevokeApplicationInvitationControlResponse = RevokeApplicationInvitationControlResponses[keyof RevokeApplicationInvitationControlResponses]; -export type CreateWorkspaceInvitationData = { - body: Object; +export type GetApplicationInvitationControlData = { + body?: never; path: { application_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspace-invitations'; + url: '/v1/control/applications/{application_id}/invitations/{invitation_id}'; }; -export type CreateWorkspaceInvitationResponses = { +export type GetApplicationInvitationControlResponses = { /** - * Workspace invitation created and credential returned once + * Invitation detail */ - 201: unknown; + 200: ApplicationInvitation; }; -export type RevokeWorkspaceInvitationData = { +export type GetApplicationInvitationControlResponse = GetApplicationInvitationControlResponses[keyof GetApplicationInvitationControlResponses]; + +export type ResendApplicationInvitationControlData = { body?: never; path: { application_id: Uuid; invitation_id: Uuid; }; query?: never; - url: '/v1/control/applications/{application_id}/workspace-invitations/{invitation_id}'; + url: '/v1/control/applications/{application_id}/invitations/{invitation_id}/resend'; }; -export type RevokeWorkspaceInvitationResponses = { +export type ResendApplicationInvitationControlErrors = { /** - * Pending workspace invitation revoked + * RFC 9457 problem */ - 204: void; + 429: Problem; +}; + +export type ResendApplicationInvitationControlError = ResendApplicationInvitationControlErrors[keyof ResendApplicationInvitationControlErrors]; + +export type ResendApplicationInvitationControlResponses = { + /** + * Invitation credentials rotated and localized email queued + */ + 202: InvitationResent; }; -export type RevokeWorkspaceInvitationResponse = RevokeWorkspaceInvitationResponses[keyof RevokeWorkspaceInvitationResponses]; +export type ResendApplicationInvitationControlResponse = ResendApplicationInvitationControlResponses[keyof ResendApplicationInvitationControlResponses]; export type ListUsersData = { body?: never; @@ -3179,15 +6150,15 @@ export type ListUsersData = { export type ListUsersResponses = { /** - * Cursor page + * Successful listUsers response. */ - 200: Page; + 200: UserPage; }; export type ListUsersResponse = ListUsersResponses[keyof ListUsersResponses]; export type CreateUserData = { - body: Object; + body: CreateUserWritable; path: { application_id: Uuid; }; @@ -3199,9 +6170,11 @@ export type CreateUserResponses = { /** * User created */ - 201: unknown; + 201: User; }; +export type CreateUserResponse = CreateUserResponses[keyof CreateUserResponses]; + export type GetUserData = { body?: never; path: { @@ -3216,11 +6189,13 @@ export type GetUserResponses = { /** * User details */ - 200: unknown; + 200: User; }; +export type GetUserResponse = GetUserResponses[keyof GetUserResponses]; + export type UpdateUserData = { - body: Object; + body: UpdateUser; path: { application_id: Uuid; user_id: Uuid; @@ -3239,7 +6214,7 @@ export type UpdateUserResponses = { export type UpdateUserResponse = UpdateUserResponses[keyof UpdateUserResponses]; export type SuspendUserData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; user_id: Uuid; @@ -3258,7 +6233,7 @@ export type SuspendUserResponses = { export type SuspendUserResponse = SuspendUserResponses[keyof SuspendUserResponses]; export type RestoreUserData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; user_id: Uuid; @@ -3277,7 +6252,7 @@ export type RestoreUserResponses = { export type RestoreUserResponse = RestoreUserResponses[keyof RestoreUserResponses]; export type VerifyUserEmailData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; user_id: Uuid; @@ -3296,7 +6271,7 @@ export type VerifyUserEmailResponses = { export type VerifyUserEmailResponse = VerifyUserEmailResponses[keyof VerifyUserEmailResponses]; export type UnverifyUserEmailData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; user_id: Uuid; @@ -3315,7 +6290,7 @@ export type UnverifyUserEmailResponses = { export type UnverifyUserEmailResponse = UnverifyUserEmailResponses[keyof UnverifyUserEmailResponses]; export type VerifyUserOrganizationData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; user_id: Uuid; @@ -3334,7 +6309,7 @@ export type VerifyUserOrganizationResponses = { export type VerifyUserOrganizationResponse = VerifyUserOrganizationResponses[keyof VerifyUserOrganizationResponses]; export type UnverifyUserOrganizationData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; user_id: Uuid; @@ -3364,9 +6339,9 @@ export type ListUserSessionsData = { export type ListUserSessionsResponses = { /** - * Cursor page + * Successful listUserSessions response. */ - 200: Page; + 200: SessionPage; }; export type ListUserSessionsResponse = ListUserSessionsResponses[keyof ListUserSessionsResponses]; @@ -3385,9 +6360,11 @@ export type RevokeUserSessionsResponses = { /** * All active user sessions revoked */ - 200: unknown; + 200: RevokedSessionCount; }; +export type RevokeUserSessionsResponse = RevokeUserSessionsResponses[keyof RevokeUserSessionsResponses]; + export type ListUserAddressesData = { body?: never; path: { @@ -3400,9 +6377,9 @@ export type ListUserAddressesData = { export type ListUserAddressesResponses = { /** - * Cursor page + * Successful listUserAddresses response. */ - 200: Page; + 200: AddressPage; }; export type ListUserAddressesResponse = ListUserAddressesResponses[keyof ListUserAddressesResponses]; @@ -3418,9 +6395,9 @@ export type ListOAuthConsentsData = { export type ListOAuthConsentsResponses = { /** - * Cursor page + * Successful listOAuthConsents response. */ - 200: Page; + 200: OAuthConsentPage; }; export type ListOAuthConsentsResponse = ListOAuthConsentsResponses[keyof ListOAuthConsentsResponses]; @@ -3456,9 +6433,9 @@ export type ListFeaturesData = { export type ListFeaturesResponses = { /** - * Cursor page + * Successful listFeatures response. */ - 200: Page; + 200: FeaturePage; }; export type ListFeaturesResponse = ListFeaturesResponses[keyof ListFeaturesResponses]; @@ -3485,9 +6462,11 @@ export type CreateFeatureResponses = { /** * Feature created */ - 201: unknown; + 201: Feature; }; +export type CreateFeatureResponse = CreateFeatureResponses[keyof CreateFeatureResponses]; + export type PasswordSignUpData = { body: PasswordSignUpWritable; path: { @@ -3543,7 +6522,7 @@ export type PasswordSignInResponses = { export type PasswordSignInResponse = PasswordSignInResponses[keyof PasswordSignInResponses]; export type AuthMethodsData = { - body: Object; + body?: never; path: { application_id: Uuid; }; @@ -3555,9 +6534,11 @@ export type AuthMethodsResponses = { /** * Enumeration-safe enabled authentication methods */ - 200: unknown; + 200: AuthMethods; }; +export type AuthMethodsResponse = AuthMethodsResponses[keyof AuthMethodsResponses]; + export type EmailStartData = { body: EmailStart; path: { @@ -3571,9 +6552,11 @@ export type EmailStartResponses = { /** * Enumeration-safe challenge accepted */ - 202: unknown; + 202: ChallengeAccepted; }; +export type EmailStartResponse = EmailStartResponses[keyof EmailStartResponses]; + export type EmailVerifyData = { body: EmailVerifyWritable; path: { @@ -3593,9 +6576,7 @@ export type EmailVerifyResponses = { export type EmailVerifyResponse = EmailVerifyResponses[keyof EmailVerifyResponses]; export type RefreshData = { - body: { - refresh_token: string; - }; + body: RefreshToken; path: { application_id: Uuid; }; @@ -3613,7 +6594,7 @@ export type RefreshResponses = { export type RefreshResponse = RefreshResponses[keyof RefreshResponses]; export type PasswordResetStartData = { - body: Object; + body: PasswordResetStart; path: { application_id: Uuid; }; @@ -3625,11 +6606,13 @@ export type PasswordResetStartResponses = { /** * Enumeration-safe reset challenge accepted */ - 202: unknown; + 202: ChallengeAccepted; }; +export type PasswordResetStartResponse = PasswordResetStartResponses[keyof PasswordResetStartResponses]; + export type PasswordResetVerifyData = { - body: Object; + body: PasswordResetVerifyWritable; path: { application_id: Uuid; }; @@ -3657,15 +6640,15 @@ export type ListAuthProvidersData = { export type ListAuthProvidersResponses = { /** - * Cursor page + * Successful listAuthProviders response. */ - 200: Page; + 200: AuthProviderPage; }; export type ListAuthProvidersResponse = ListAuthProvidersResponses[keyof ListAuthProvidersResponses]; export type StartGoogleAuthData = { - body: Object; + body: ExternalAuthStartRequest; path: { application_id: Uuid; }; @@ -3677,20 +6660,20 @@ export type StartGoogleAuthResponses = { /** * Google authorization URL with state, nonce, and S256 PKCE */ - 201: unknown; + 201: ExternalAuthStart; }; +export type StartGoogleAuthResponse = StartGoogleAuthResponses[keyof StartGoogleAuthResponses]; + export type GoogleAuthCallbackData = { body?: never; - path: { - application_id: Uuid; - }; + path?: never; query?: never; - url: '/v1/applications/{application_id}/auth/providers/google/callback'; + url: '/v1/auth/providers/google/callback'; }; export type ExchangeGoogleAuthData = { - body: Object; + body: ExternalAuthExchange; path: { application_id: Uuid; }; @@ -3708,7 +6691,7 @@ export type ExchangeGoogleAuthResponses = { export type ExchangeGoogleAuthResponse = ExchangeGoogleAuthResponses[keyof ExchangeGoogleAuthResponses]; export type StartAppleAuthData = { - body: Object; + body: ExternalAuthStartRequest; path: { application_id: Uuid; }; @@ -3720,9 +6703,11 @@ export type StartAppleAuthResponses = { /** * Apple authorization URL with state and nonce */ - 201: unknown; + 201: ExternalAuthStart; }; +export type StartAppleAuthResponse = StartAppleAuthResponses[keyof StartAppleAuthResponses]; + export type AppleAuthCallbackData = { body?: { code?: string; @@ -3730,15 +6715,13 @@ export type AppleAuthCallbackData = { user?: string; error?: string; }; - path: { - application_id: Uuid; - }; + path?: never; query?: never; - url: '/v1/applications/{application_id}/auth/providers/apple/callback'; + url: '/v1/auth/providers/apple/callback'; }; export type ExchangeAppleAuthData = { - body: Object; + body: ExternalAuthExchange; path: { application_id: Uuid; }; @@ -3756,74 +6739,130 @@ export type ExchangeAppleAuthResponses = { export type ExchangeAppleAuthResponse = ExchangeAppleAuthResponses[keyof ExchangeAppleAuthResponses]; export type VerifyMfaData = { - body: Object; + body: VerifyMfaWritable; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/auth/mfa/verify'; +}; + +export type VerifyMfaErrors = { + /** + * RFC 9457 problem + */ + 401: Problem; +}; + +export type VerifyMfaError = VerifyMfaErrors[keyof VerifyMfaErrors]; + +export type VerifyMfaResponses = { + /** + * Rotating user session + */ + 200: TokenResponse; +}; + +export type VerifyMfaResponse = VerifyMfaResponses[keyof VerifyMfaResponses]; + +export type BeginWebAuthnAuthenticationData = { + body: BeginWebAuthnAuthentication; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/auth/mfa/webauthn/options'; +}; + +export type BeginWebAuthnAuthenticationResponses = { + /** + * WebAuthn assertion options and opaque ceremony identifier + */ + 201: WebAuthnChallenge; +}; + +export type BeginWebAuthnAuthenticationResponse = BeginWebAuthnAuthenticationResponses[keyof BeginWebAuthnAuthenticationResponses]; + +export type FinishWebAuthnAuthenticationData = { + body: FinishWebAuthnCeremony; path: { application_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/auth/mfa/verify'; + url: '/v1/applications/{application_id}/auth/mfa/webauthn/verify'; }; -export type VerifyMfaErrors = { +export type FinishWebAuthnAuthenticationErrors = { /** * RFC 9457 problem */ 401: Problem; }; -export type VerifyMfaError = VerifyMfaErrors[keyof VerifyMfaErrors]; +export type FinishWebAuthnAuthenticationError = FinishWebAuthnAuthenticationErrors[keyof FinishWebAuthnAuthenticationErrors]; -export type VerifyMfaResponses = { +export type FinishWebAuthnAuthenticationResponses = { /** * Rotating user session */ 200: TokenResponse; }; -export type VerifyMfaResponse = VerifyMfaResponses[keyof VerifyMfaResponses]; +export type FinishWebAuthnAuthenticationResponse = FinishWebAuthnAuthenticationResponses[keyof FinishWebAuthnAuthenticationResponses]; -export type BeginWebAuthnAuthenticationData = { - body: Object; +export type ExchangeApplicationInvitationData = { + body: ExchangeInvitationWritable; path: { application_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/auth/mfa/webauthn/options'; + url: '/v1/applications/{application_id}/auth/invitations/exchange'; }; -export type BeginWebAuthnAuthenticationResponses = { +export type ExchangeApplicationInvitationErrors = { /** - * WebAuthn assertion options and opaque ceremony identifier + * RFC 9457 problem */ - 201: unknown; + 401: Problem; }; -export type FinishWebAuthnAuthenticationData = { - body: Object; +export type ExchangeApplicationInvitationError = ExchangeApplicationInvitationErrors[keyof ExchangeApplicationInvitationErrors]; + +export type ExchangeApplicationInvitationResponses = { + /** + * Invitation accepted and a short-lived PKCE-bound authorization code returned + */ + 200: InvitationExchangeResult; +}; + +export type ExchangeApplicationInvitationResponse = ExchangeApplicationInvitationResponses[keyof ExchangeApplicationInvitationResponses]; + +export type RedeemApplicationInvitationData = { + body: RedeemInvitation; path: { application_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/auth/mfa/webauthn/verify'; + url: '/v1/applications/{application_id}/auth/invitations/token'; }; -export type FinishWebAuthnAuthenticationErrors = { +export type RedeemApplicationInvitationErrors = { /** * RFC 9457 problem */ 401: Problem; }; -export type FinishWebAuthnAuthenticationError = FinishWebAuthnAuthenticationErrors[keyof FinishWebAuthnAuthenticationErrors]; +export type RedeemApplicationInvitationError = RedeemApplicationInvitationErrors[keyof RedeemApplicationInvitationErrors]; -export type FinishWebAuthnAuthenticationResponses = { +export type RedeemApplicationInvitationResponses = { /** - * Rotating user session + * Authentication completed or MFA challenge returned */ 200: TokenResponse; }; -export type FinishWebAuthnAuthenticationResponse = FinishWebAuthnAuthenticationResponses[keyof FinishWebAuthnAuthenticationResponses]; +export type RedeemApplicationInvitationResponse = RedeemApplicationInvitationResponses[keyof RedeemApplicationInvitationResponses]; export type DeleteMyAccountData = { body?: never; @@ -3917,9 +6956,9 @@ export type ListPersonalApiKeysError = ListPersonalApiKeysErrors[keyof ListPerso export type ListPersonalApiKeysResponses = { /** - * Cursor page + * Successful listPersonalAPIKeys response. */ - 200: Page; + 200: PersonalApiKeyPage; }; export type ListPersonalApiKeysResponse = ListPersonalApiKeysResponses[keyof ListPersonalApiKeysResponses]; @@ -3937,9 +6976,11 @@ export type CreatePersonalApiKeyResponses = { /** * Key created and secret returned once */ - 201: unknown; + 201: PersonalApiKeyCreated; }; +export type CreatePersonalApiKeyResponse = CreatePersonalApiKeyResponses[keyof CreatePersonalApiKeyResponses]; + export type PublicCatalogData = { body?: never; path: { @@ -3951,9 +6992,9 @@ export type PublicCatalogData = { export type PublicCatalogResponses = { /** - * Cursor page + * Successful publicCatalog response. */ - 200: Page; + 200: ProductPage; }; export type PublicCatalogResponse = PublicCatalogResponses[keyof PublicCatalogResponses]; @@ -3969,9 +7010,9 @@ export type ListProductsData = { export type ListProductsResponses = { /** - * Cursor page + * Successful listProducts response. */ - 200: Page; + 200: ProductPage; }; export type ListProductsResponse = ListProductsResponses[keyof ListProductsResponses]; @@ -3989,9 +7030,11 @@ export type CreateProductResponses = { /** * Product created */ - 201: unknown; + 201: Product; }; +export type CreateProductResponse = CreateProductResponses[keyof CreateProductResponses]; + export type ListPricesData = { body?: never; path: { @@ -4004,9 +7047,9 @@ export type ListPricesData = { export type ListPricesResponses = { /** - * Cursor page + * Successful listPrices response. */ - 200: Page; + 200: PricePage; }; export type ListPricesResponse = ListPricesResponses[keyof ListPricesResponses]; @@ -4025,9 +7068,11 @@ export type CreatePriceResponses = { /** * Immutable price created */ - 201: unknown; + 201: Price; }; +export type CreatePriceResponse = CreatePriceResponses[keyof CreatePriceResponses]; + export type GetProductData = { body?: never; path: { @@ -4042,9 +7087,11 @@ export type GetProductResponses = { /** * Product details */ - 200: unknown; + 200: Product; }; +export type GetProductResponse = GetProductResponses[keyof GetProductResponses]; + export type UpdateProductData = { body: UpdateProduct; path: { @@ -4075,15 +7122,15 @@ export type ListEntitlementsData = { export type ListEntitlementsResponses = { /** - * Cursor page + * Successful listEntitlements response. */ - 200: Page; + 200: EntitlementGrantPage; }; export type ListEntitlementsResponse = ListEntitlementsResponses[keyof ListEntitlementsResponses]; export type CreateEntitlementData = { - body: Object; + body: CreateEntitlement; path: { application_id: Uuid; }; @@ -4095,9 +7142,11 @@ export type CreateEntitlementResponses = { /** * Entitlement grant created */ - 201: unknown; + 201: EntitlementGrant; }; +export type CreateEntitlementResponse = CreateEntitlementResponses[keyof CreateEntitlementResponses]; + export type GetEntitlementData = { body?: never; path: { @@ -4112,11 +7161,13 @@ export type GetEntitlementResponses = { /** * Entitlement grant, effective state, and append-only actions */ - 200: unknown; + 200: EntitlementGrant; }; +export type GetEntitlementResponse = GetEntitlementResponses[keyof GetEntitlementResponses]; + export type RevokeEntitlementData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; entitlement_id: Uuid; @@ -4134,8 +7185,27 @@ export type RevokeEntitlementResponses = { export type RevokeEntitlementResponse = RevokeEntitlementResponses[keyof RevokeEntitlementResponses]; +export type AdjustEntitlementData = { + body: AdjustEntitlement; + path: { + application_id: Uuid; + entitlement_id: Uuid; + }; + query?: never; + url: '/v1/control/applications/{application_id}/entitlements/{entitlement_id}/adjust'; +}; + +export type AdjustEntitlementResponses = { + /** + * Append-only expiry adjustment recorded + */ + 204: void; +}; + +export type AdjustEntitlementResponse = AdjustEntitlementResponses[keyof AdjustEntitlementResponses]; + export type RestoreEntitlementData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; entitlement_id: Uuid; @@ -4164,9 +7234,9 @@ export type ListLocalEntitlementRequestsData = { export type ListLocalEntitlementRequestsResponses = { /** - * Cursor page + * Successful listLocalEntitlementRequests response. */ - 200: Page; + 200: LocalEntitlementRequestPage; }; export type ListLocalEntitlementRequestsResponse = ListLocalEntitlementRequestsResponses[keyof ListLocalEntitlementRequestsResponses]; @@ -4185,11 +7255,13 @@ export type GetLocalEntitlementRequestResponses = { /** * Local request with immutable snapshots and action history */ - 200: unknown; + 200: LocalEntitlementRequest; }; +export type GetLocalEntitlementRequestResponse = GetLocalEntitlementRequestResponses[keyof GetLocalEntitlementRequestResponses]; + export type ApproveLocalEntitlementRequestData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; request_id: Uuid; @@ -4202,11 +7274,13 @@ export type ApproveLocalEntitlementRequestResponses = { /** * Request approved exactly once */ - 200: unknown; + 200: LocalEntitlementApproval; }; +export type ApproveLocalEntitlementRequestResponse = ApproveLocalEntitlementRequestResponses[keyof ApproveLocalEntitlementRequestResponses]; + export type RejectLocalEntitlementRequestData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; request_id: Uuid; @@ -4225,7 +7299,7 @@ export type RejectLocalEntitlementRequestResponses = { export type RejectLocalEntitlementRequestResponse = RejectLocalEntitlementRequestResponses[keyof RejectLocalEntitlementRequestResponses]; export type ReopenLocalEntitlementRequestData = { - body: Object; + body: AuditReason; path: { application_id: Uuid; request_id: Uuid; @@ -4259,9 +7333,11 @@ export type LocalEntitlementCheckoutResponses = { /** * Pending local entitlement request */ - 201: unknown; + 201: LocalEntitlementRequest; }; +export type LocalEntitlementCheckoutResponse = LocalEntitlementCheckoutResponses[keyof LocalEntitlementCheckoutResponses]; + export type ListMyLocalEntitlementRequestsData = { body?: never; path: { @@ -4273,9 +7349,9 @@ export type ListMyLocalEntitlementRequestsData = { export type ListMyLocalEntitlementRequestsResponses = { /** - * Cursor page + * Successful listMyLocalEntitlementRequests response. */ - 200: Page; + 200: LocalEntitlementRequestPage; }; export type ListMyLocalEntitlementRequestsResponse = ListMyLocalEntitlementRequestsResponses[keyof ListMyLocalEntitlementRequestsResponses]; @@ -4294,9 +7370,11 @@ export type GetMyLocalEntitlementRequestResponses = { /** * Own local request with immutable snapshots and action history */ - 200: unknown; + 200: LocalEntitlementRequest; }; +export type GetMyLocalEntitlementRequestResponse = GetMyLocalEntitlementRequestResponses[keyof GetMyLocalEntitlementRequestResponses]; + export type CancelMyLocalEntitlementRequestData = { body?: never; path: { @@ -4334,9 +7412,11 @@ export type ListMyEntitlementsResponses = { /** * Effective user entitlements, optionally merged with one accessible workspace and full provenance */ - 200: unknown; + 200: EffectiveEntitlements; }; +export type ListMyEntitlementsResponse = ListMyEntitlementsResponses[keyof ListMyEntitlementsResponses]; + export type ListBillingProvidersData = { body?: never; path: { @@ -4348,9 +7428,9 @@ export type ListBillingProvidersData = { export type ListBillingProvidersResponses = { /** - * Cursor page + * Successful listBillingProviders response. */ - 200: Page; + 200: BillingProviderPage; }; export type ListBillingProvidersResponse = ListBillingProvidersResponses[keyof ListBillingProvidersResponses]; @@ -4368,9 +7448,11 @@ export type CreateBillingProviderResponses = { /** * Billing provider configured */ - 201: unknown; + 201: BillingProvider; }; +export type CreateBillingProviderResponse = CreateBillingProviderResponses[keyof CreateBillingProviderResponses]; + export type DisableBillingProviderData = { body?: never; path: { @@ -4413,11 +7495,13 @@ export type GetBillingProviderResponses = { /** * Secret-free provider connection */ - 200: unknown; + 200: BillingProvider; }; +export type GetBillingProviderResponse = GetBillingProviderResponses[keyof GetBillingProviderResponses]; + export type UpdateBillingProviderData = { - body: Object; + body: UpdateBillingProviderWritable; path: { application_id: Uuid; provider_id: Uuid; @@ -4470,9 +7554,11 @@ export type CreateCheckoutSessionResponses = { /** * Provider checkout created */ - 201: unknown; + 201: CheckoutSession; }; +export type CreateCheckoutSessionResponse = CreateCheckoutSessionResponses[keyof CreateCheckoutSessionResponses]; + export type GetCheckoutSessionData = { body?: never; path: { @@ -4487,11 +7573,13 @@ export type GetCheckoutSessionResponses = { /** * Checkout status and redirect URI */ - 200: unknown; + 200: CheckoutSession; }; +export type GetCheckoutSessionResponse = GetCheckoutSessionResponses[keyof GetCheckoutSessionResponses]; + export type CreateBillingPortalSessionData = { - body: Object; + body: CreatePortalSession; headers?: { 'Idempotency-Key'?: string; }; @@ -4506,9 +7594,11 @@ export type CreateBillingPortalSessionResponses = { /** * Customer portal session created */ - 201: unknown; + 201: PortalSession; }; +export type CreateBillingPortalSessionResponse = CreateBillingPortalSessionResponses[keyof CreateBillingPortalSessionResponses]; + export type ListSubscriptionsData = { body?: never; path: { @@ -4520,9 +7610,9 @@ export type ListSubscriptionsData = { export type ListSubscriptionsResponses = { /** - * Cursor page + * Successful listSubscriptions response. */ - 200: Page; + 200: SubscriptionPage; }; export type ListSubscriptionsResponse = ListSubscriptionsResponses[keyof ListSubscriptionsResponses]; @@ -4541,11 +7631,13 @@ export type GetSubscriptionResponses = { /** * Subscription details */ - 200: unknown; + 200: Subscription; }; +export type GetSubscriptionResponse = GetSubscriptionResponses[keyof GetSubscriptionResponses]; + export type CancelSubscriptionData = { - body: Object; + body: CancelSubscription; headers?: { 'Idempotency-Key'?: string; }; @@ -4589,10 +7681,7 @@ export type ResumeSubscriptionResponses = { export type ResumeSubscriptionResponse = ResumeSubscriptionResponses[keyof ResumeSubscriptionResponses]; export type ChangeSubscriptionPriceData = { - body: { - price_id: Uuid; - proration_behavior?: 'create_prorations' | 'always_invoice' | 'none'; - }; + body: ChangeSubscriptionPrice; headers?: { 'Idempotency-Key'?: string; }; @@ -4608,9 +7697,11 @@ export type ChangeSubscriptionPriceResponses = { /** * Subscription price changed and synchronized */ - 200: unknown; + 200: Subscription; }; +export type ChangeSubscriptionPriceResponse = ChangeSubscriptionPriceResponses[keyof ChangeSubscriptionPriceResponses]; + export type ListInvoicesData = { body?: never; path: { @@ -4622,9 +7713,9 @@ export type ListInvoicesData = { export type ListInvoicesResponses = { /** - * Cursor page + * Successful listInvoices response. */ - 200: Page; + 200: InvoicePage; }; export type ListInvoicesResponse = ListInvoicesResponses[keyof ListInvoicesResponses]; @@ -4643,9 +7734,11 @@ export type GetInvoiceResponses = { /** * Normalized invoice details */ - 200: unknown; + 200: Invoice; }; +export type GetInvoiceResponse = GetInvoiceResponses[keyof GetInvoiceResponses]; + export type ListPaymentsData = { body?: never; path: { @@ -4657,9 +7750,9 @@ export type ListPaymentsData = { export type ListPaymentsResponses = { /** - * Cursor page + * Successful listPayments response. */ - 200: Page; + 200: PaymentPage; }; export type ListPaymentsResponse = ListPaymentsResponses[keyof ListPaymentsResponses]; @@ -4678,11 +7771,13 @@ export type GetPaymentResponses = { /** * Normalized payment details */ - 200: unknown; + 200: Payment; }; +export type GetPaymentResponse = GetPaymentResponses[keyof GetPaymentResponses]; + export type CreateRefundData = { - body: Object; + body: CreateRefund; headers?: { 'Idempotency-Key'?: string; }; @@ -4698,9 +7793,11 @@ export type CreateRefundResponses = { /** * Full or partial refund created */ - 201: unknown; + 201: Refund; }; +export type CreateRefundResponse = CreateRefundResponses[keyof CreateRefundResponses]; + export type ListRefundsData = { body?: never; path: { @@ -4712,9 +7809,9 @@ export type ListRefundsData = { export type ListRefundsResponses = { /** - * Cursor page + * Successful listRefunds response. */ - 200: Page; + 200: RefundPage; }; export type ListRefundsResponse = ListRefundsResponses[keyof ListRefundsResponses]; @@ -4733,9 +7830,11 @@ export type GetRefundResponses = { /** * Normalized refund details */ - 200: unknown; + 200: Refund; }; +export type GetRefundResponse = GetRefundResponses[keyof GetRefundResponses]; + export type ListDisputesData = { body?: never; path: { @@ -4747,9 +7846,9 @@ export type ListDisputesData = { export type ListDisputesResponses = { /** - * Cursor page + * Successful listDisputes response. */ - 200: Page; + 200: DisputePage; }; export type ListDisputesResponse = ListDisputesResponses[keyof ListDisputesResponses]; @@ -4768,9 +7867,11 @@ export type GetDisputeResponses = { /** * Normalized dispute details */ - 200: unknown; + 200: Dispute; }; +export type GetDisputeResponse = GetDisputeResponses[keyof GetDisputeResponses]; + export type GetBillingStatisticsData = { body?: never; path: { @@ -4787,9 +7888,11 @@ export type GetBillingStatisticsResponses = { /** * Bounded revenue, refund, and lifecycle statistics */ - 200: unknown; + 200: BillingStatistics; }; +export type GetBillingStatisticsResponse = GetBillingStatisticsResponses[keyof GetBillingStatisticsResponses]; + export type ListBillingProviderEventsData = { body?: never; path: { @@ -4801,9 +7904,9 @@ export type ListBillingProviderEventsData = { export type ListBillingProviderEventsResponses = { /** - * Cursor page + * Successful listBillingProviderEvents response. */ - 200: Page; + 200: BillingProviderEventPage; }; export type ListBillingProviderEventsResponse = ListBillingProviderEventsResponses[keyof ListBillingProviderEventsResponses]; @@ -4844,9 +7947,11 @@ export type CreateBillingReconciliationRunResponses = { /** * Reconciliation queued transactionally */ - 202: unknown; + 202: ReconciliationAccepted; }; +export type CreateBillingReconciliationRunResponse = CreateBillingReconciliationRunResponses[keyof CreateBillingReconciliationRunResponses]; + export type ListBillingReconciliationRunsData = { body?: never; path: { @@ -4858,9 +7963,9 @@ export type ListBillingReconciliationRunsData = { export type ListBillingReconciliationRunsResponses = { /** - * Cursor page + * Successful listBillingReconciliationRuns response. */ - 200: Page; + 200: ReconciliationRunPage; }; export type ListBillingReconciliationRunsResponse = ListBillingReconciliationRunsResponses[keyof ListBillingReconciliationRunsResponses]; @@ -4879,9 +7984,11 @@ export type GetBillingReconciliationRunResponses = { /** * Reconciliation findings, repairs, and status */ - 200: unknown; + 200: ReconciliationRun; }; +export type GetBillingReconciliationRunResponse = GetBillingReconciliationRunResponses[keyof GetBillingReconciliationRunResponses]; + export type GetMyBillingSummaryData = { body?: never; path: { @@ -4895,9 +8002,11 @@ export type GetMyBillingSummaryResponses = { /** * Current billing resource counts */ - 200: unknown; + 200: BillingSummary; }; +export type GetMyBillingSummaryResponse = GetMyBillingSummaryResponses[keyof GetMyBillingSummaryResponses]; + export type ListMySubscriptionsData = { body?: never; path: { @@ -4909,9 +8018,9 @@ export type ListMySubscriptionsData = { export type ListMySubscriptionsResponses = { /** - * Cursor page + * Successful listMySubscriptions response. */ - 200: Page; + 200: SubscriptionPage; }; export type ListMySubscriptionsResponse = ListMySubscriptionsResponses[keyof ListMySubscriptionsResponses]; @@ -4927,9 +8036,9 @@ export type ListMyInvoicesData = { export type ListMyInvoicesResponses = { /** - * Cursor page + * Successful listMyInvoices response. */ - 200: Page; + 200: InvoicePage; }; export type ListMyInvoicesResponse = ListMyInvoicesResponses[keyof ListMyInvoicesResponses]; @@ -4945,9 +8054,9 @@ export type ListMyPaymentsData = { export type ListMyPaymentsResponses = { /** - * Cursor page + * Successful listMyPayments response. */ - 200: Page; + 200: PaymentPage; }; export type ListMyPaymentsResponse = ListMyPaymentsResponses[keyof ListMyPaymentsResponses]; @@ -4963,9 +8072,9 @@ export type ListMySessionsData = { export type ListMySessionsResponses = { /** - * Cursor page + * Successful listMySessions response. */ - 200: Page; + 200: SessionPage; }; export type ListMySessionsResponse = ListMySessionsResponses[keyof ListMySessionsResponses]; @@ -4983,11 +8092,13 @@ export type EmailVerificationStartResponses = { /** * Verification challenge accepted */ - 202: unknown; + 202: ChallengeAccepted; }; +export type EmailVerificationStartResponse = EmailVerificationStartResponses[keyof EmailVerificationStartResponses]; + export type EmailVerificationVerifyData = { - body: Object; + body: AccountChallengeWritable; path: { application_id: Uuid; }; @@ -5005,7 +8116,7 @@ export type EmailVerificationVerifyResponses = { export type EmailVerificationVerifyResponse = EmailVerificationVerifyResponses[keyof EmailVerificationVerifyResponses]; export type EmailChangeStartData = { - body: Object; + body: EmailAddress; path: { application_id: Uuid; }; @@ -5017,11 +8128,13 @@ export type EmailChangeStartResponses = { /** * Email change challenge accepted */ - 202: unknown; + 202: ChallengeAccepted; }; +export type EmailChangeStartResponse = EmailChangeStartResponses[keyof EmailChangeStartResponses]; + export type EmailChangeVerifyData = { - body: Object; + body: AccountChallengeWritable; path: { application_id: Uuid; }; @@ -5039,7 +8152,7 @@ export type EmailChangeVerifyResponses = { export type EmailChangeVerifyResponse = EmailChangeVerifyResponses[keyof EmailChangeVerifyResponses]; export type PasswordChangeData = { - body: Object; + body: PasswordChange; path: { application_id: Uuid; }; @@ -5069,9 +8182,11 @@ export type ExportMyAccountResponses = { /** * Portable account export */ - 200: unknown; + 200: AccountExport; }; +export type ExportMyAccountResponse = ExportMyAccountResponses[keyof ExportMyAccountResponses]; + export type AnonymizeMyAccountData = { body?: never; path: { @@ -5101,15 +8216,15 @@ export type ListMyMfaMethodsData = { export type ListMyMfaMethodsResponses = { /** - * Cursor page + * Successful listMyMFAMethods response. */ - 200: Page; + 200: MfaMethodPage; }; export type ListMyMfaMethodsResponse = ListMyMfaMethodsResponses[keyof ListMyMfaMethodsResponses]; export type StartTotpEnrollmentData = { - body: Object; + body: StartTotp; path: { application_id: Uuid; }; @@ -5121,11 +8236,13 @@ export type StartTotpEnrollmentResponses = { /** * One-time TOTP secret and provisioning URI */ - 201: unknown; + 201: MfaEnrollment; }; +export type StartTotpEnrollmentResponse = StartTotpEnrollmentResponses[keyof StartTotpEnrollmentResponses]; + export type ActivateTotpEnrollmentData = { - body: Object; + body: ActivateTotp; path: { application_id: Uuid; method_id: Uuid; @@ -5138,11 +8255,13 @@ export type ActivateTotpEnrollmentResponses = { /** * TOTP activated and recovery codes returned once */ - 200: unknown; + 200: MfaActivation; }; +export type ActivateTotpEnrollmentResponse = ActivateTotpEnrollmentResponses[keyof ActivateTotpEnrollmentResponses]; + export type BeginWebAuthnRegistrationData = { - body: Object; + body: BeginWebAuthnRegistration; path: { application_id: Uuid; }; @@ -5154,11 +8273,13 @@ export type BeginWebAuthnRegistrationResponses = { /** * WebAuthn credential creation options and opaque ceremony identifier */ - 201: unknown; + 201: WebAuthnChallenge; }; +export type BeginWebAuthnRegistrationResponse = BeginWebAuthnRegistrationResponses[keyof BeginWebAuthnRegistrationResponses]; + export type FinishWebAuthnRegistrationData = { - body: Object; + body: FinishWebAuthnCeremony; path: { application_id: Uuid; }; @@ -5170,9 +8291,11 @@ export type FinishWebAuthnRegistrationResponses = { /** * WebAuthn credential activated and recovery codes returned once when created */ - 200: unknown; + 200: MfaActivation; }; +export type FinishWebAuthnRegistrationResponse = FinishWebAuthnRegistrationResponses[keyof FinishWebAuthnRegistrationResponses]; + export type DisableMfaMethodData = { body?: never; path: { @@ -5205,11 +8328,13 @@ export type RegenerateRecoveryCodesResponses = { /** * Replacement recovery codes returned once */ - 200: unknown; + 200: RecoveryCodes; }; +export type RegenerateRecoveryCodesResponse = RegenerateRecoveryCodesResponses[keyof RegenerateRecoveryCodesResponses]; + export type StartGoogleLinkData = { - body: Object; + body: ExternalAuthStartRequest; path: { application_id: Uuid; }; @@ -5221,11 +8346,13 @@ export type StartGoogleLinkResponses = { /** * Authenticated Google account-link authorization URL */ - 201: unknown; + 201: ExternalAuthStart; }; +export type StartGoogleLinkResponse = StartGoogleLinkResponses[keyof StartGoogleLinkResponses]; + export type StartAppleLinkData = { - body: Object; + body: ExternalAuthStartRequest; path: { application_id: Uuid; }; @@ -5237,9 +8364,11 @@ export type StartAppleLinkResponses = { /** * Authenticated Apple account-link authorization URL */ - 201: unknown; + 201: ExternalAuthStart; }; +export type StartAppleLinkResponse = StartAppleLinkResponses[keyof StartAppleLinkResponses]; + export type ListMyIdentitiesData = { body?: never; path: { @@ -5251,9 +8380,9 @@ export type ListMyIdentitiesData = { export type ListMyIdentitiesResponses = { /** - * Cursor page + * Successful listMyIdentities response. */ - 200: Page; + 200: ExternalIdentityPage; }; export type ListMyIdentitiesResponse = ListMyIdentitiesResponses[keyof ListMyIdentitiesResponses]; @@ -5344,15 +8473,15 @@ export type ListMyAddressesData = { export type ListMyAddressesResponses = { /** - * Cursor page + * Successful listMyAddresses response. */ - 200: Page; + 200: AddressPage; }; export type ListMyAddressesResponse = ListMyAddressesResponses[keyof ListMyAddressesResponses]; export type CreateMyAddressData = { - body: Object; + body: CreateAddress; path: { application_id: Uuid; }; @@ -5364,9 +8493,11 @@ export type CreateMyAddressResponses = { /** * Address created */ - 201: unknown; + 201: Address; }; +export type CreateMyAddressResponse = CreateMyAddressResponses[keyof CreateMyAddressResponses]; + export type DeleteMyAddressData = { body?: never; path: { @@ -5387,7 +8518,7 @@ export type DeleteMyAddressResponses = { export type DeleteMyAddressResponse = DeleteMyAddressResponses[keyof DeleteMyAddressResponses]; export type UpdateMyAddressData = { - body: Object; + body: UpdateAddress; path: { application_id: Uuid; address_id: Uuid; @@ -5415,250 +8546,469 @@ export type ActivateMyAddressData = { url: '/v1/applications/{application_id}/me/addresses/{address_id}/activate'; }; -export type ActivateMyAddressResponses = { +export type ActivateMyAddressResponses = { + /** + * Address atomically selected as active + */ + 204: void; +}; + +export type ActivateMyAddressResponse = ActivateMyAddressResponses[keyof ActivateMyAddressResponses]; + +export type GetMyBillingProfileData = { + body?: never; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/me/billing-profile'; +}; + +export type GetMyBillingProfileResponses = { + /** + * Current user billing profile + */ + 200: BillingProfile; +}; + +export type GetMyBillingProfileResponse = GetMyBillingProfileResponses[keyof GetMyBillingProfileResponses]; + +export type UpdateMyBillingProfileData = { + body: UpdateBillingProfile; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/me/billing-profile'; +}; + +export type UpdateMyBillingProfileResponses = { + /** + * Current user billing profile updated + */ + 204: void; +}; + +export type UpdateMyBillingProfileResponse = UpdateMyBillingProfileResponses[keyof UpdateMyBillingProfileResponses]; + +export type ListMyWorkspacesData = { + body?: never; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/me/workspaces'; +}; + +export type ListMyWorkspacesResponses = { + /** + * Successful listMyWorkspaces response. + */ + 200: WorkspacePage; +}; + +export type ListMyWorkspacesResponse = ListMyWorkspacesResponses[keyof ListMyWorkspacesResponses]; + +export type CreateMyWorkspaceData = { + body: CreateWorkspace; + path: { + application_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/me/workspaces'; +}; + +export type CreateMyWorkspaceResponses = { + /** + * Workspace created with the current user as owner + */ + 201: Workspace; +}; + +export type CreateMyWorkspaceResponse = CreateMyWorkspaceResponses[keyof CreateMyWorkspaceResponses]; + +export type ArchiveMyWorkspaceData = { + body?: never; + path: { + application_id: Uuid; + workspace_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}'; +}; + +export type ArchiveMyWorkspaceResponses = { + /** + * Owned workspace archived + */ + 204: void; +}; + +export type ArchiveMyWorkspaceResponse = ArchiveMyWorkspaceResponses[keyof ArchiveMyWorkspaceResponses]; + +export type GetMyWorkspaceData = { + body?: never; + path: { + application_id: Uuid; + workspace_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}'; +}; + +export type GetMyWorkspaceResponses = { + /** + * Accessible workspace details + */ + 200: Workspace; +}; + +export type GetMyWorkspaceResponse = GetMyWorkspaceResponses[keyof GetMyWorkspaceResponses]; + +export type UpdateMyWorkspaceData = { + body: UpdateWorkspace; + path: { + application_id: Uuid; + workspace_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}'; +}; + +export type UpdateMyWorkspaceResponses = { + /** + * Workspace updated + */ + 204: void; +}; + +export type UpdateMyWorkspaceResponse = UpdateMyWorkspaceResponses[keyof UpdateMyWorkspaceResponses]; + +export type ListMyWorkspaceMembersData = { + body?: never; + path: { + application_id: Uuid; + workspace_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/members'; +}; + +export type ListMyWorkspaceMembersResponses = { + /** + * Successful listMyWorkspaceMembers response. + */ + 200: WorkspaceMemberPage; +}; + +export type ListMyWorkspaceMembersResponse = ListMyWorkspaceMembersResponses[keyof ListMyWorkspaceMembersResponses]; + +export type RemoveMyWorkspaceMemberData = { + body?: never; + path: { + application_id: Uuid; + workspace_id: Uuid; + user_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; +}; + +export type RemoveMyWorkspaceMemberResponses = { + /** + * Workspace member removed + */ + 204: void; +}; + +export type RemoveMyWorkspaceMemberResponse = RemoveMyWorkspaceMemberResponses[keyof RemoveMyWorkspaceMemberResponses]; + +export type ReplaceMyWorkspaceMemberRolesData = { + body: ReplaceWorkspaceMemberRoles; + path: { + application_id: Uuid; + workspace_id: Uuid; + user_id: Uuid; + }; + query?: never; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; +}; + +export type ReplaceMyWorkspaceMemberRolesResponses = { /** - * Address atomically selected as active + * Workspace member roles replaced */ - 204: void; + 200: WorkspaceMember; }; -export type ActivateMyAddressResponse = ActivateMyAddressResponses[keyof ActivateMyAddressResponses]; +export type ReplaceMyWorkspaceMemberRolesResponse = ReplaceMyWorkspaceMemberRolesResponses[keyof ReplaceMyWorkspaceMemberRolesResponses]; -export type GetMyBillingProfileData = { - body?: never; +export type TransferMyWorkspaceOwnershipData = { + body: OwnershipTransfer2; path: { application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/me/billing-profile'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/owner-transfer'; }; -export type GetMyBillingProfileResponses = { +export type TransferMyWorkspaceOwnershipResponses = { /** - * Current user billing profile + * Workspace ownership transferred atomically */ - 200: unknown; + 200: OwnershipTransferResult; }; -export type UpdateMyBillingProfileData = { - body: Object; +export type TransferMyWorkspaceOwnershipResponse = TransferMyWorkspaceOwnershipResponses[keyof TransferMyWorkspaceOwnershipResponses]; + +export type LeaveWorkspaceData = { + body?: never; path: { application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/me/billing-profile'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/membership'; }; -export type UpdateMyBillingProfileResponses = { +export type LeaveWorkspaceResponses = { /** - * Current user billing profile updated + * Current membership removed */ 204: void; }; -export type UpdateMyBillingProfileResponse = UpdateMyBillingProfileResponses[keyof UpdateMyBillingProfileResponses]; +export type LeaveWorkspaceResponse = LeaveWorkspaceResponses[keyof LeaveWorkspaceResponses]; -export type ListMyWorkspacesData = { +export type ListMyWorkspaceInvitationsData = { body?: never; path: { application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/me/workspaces'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations'; }; -export type ListMyWorkspacesResponses = { +export type ListMyWorkspaceInvitationsResponses = { /** - * Cursor page + * Successful listMyWorkspaceInvitations response. */ - 200: Page; + 200: ApplicationInvitationPage; }; -export type ListMyWorkspacesResponse = ListMyWorkspacesResponses[keyof ListMyWorkspacesResponses]; +export type ListMyWorkspaceInvitationsResponse = ListMyWorkspaceInvitationsResponses[keyof ListMyWorkspaceInvitationsResponses]; -export type CreateMyWorkspaceData = { - body: Object; +export type CreateMyWorkspaceInvitationData = { + body: CreateInvitation; path: { application_id: Uuid; + workspace_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/me/workspaces'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations'; }; -export type CreateMyWorkspaceResponses = { +export type CreateMyWorkspaceInvitationResponses = { /** - * Workspace created with the current user as owner + * Workspace invitation created and email queued */ - 201: unknown; + 201: ApplicationInvitation; }; -export type ArchiveMyWorkspaceData = { +export type CreateMyWorkspaceInvitationResponse = CreateMyWorkspaceInvitationResponses[keyof CreateMyWorkspaceInvitationResponses]; + +export type RevokeMyWorkspaceInvitationData = { body?: never; path: { application_id: Uuid; workspace_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}'; }; -export type ArchiveMyWorkspaceResponses = { +export type RevokeMyWorkspaceInvitationResponses = { /** - * Owned workspace archived + * Pending workspace invitation revoked */ 204: void; }; -export type ArchiveMyWorkspaceResponse = ArchiveMyWorkspaceResponses[keyof ArchiveMyWorkspaceResponses]; +export type RevokeMyWorkspaceInvitationResponse = RevokeMyWorkspaceInvitationResponses[keyof RevokeMyWorkspaceInvitationResponses]; -export type GetMyWorkspaceData = { +export type ResendMyWorkspaceInvitationData = { body?: never; path: { application_id: Uuid; workspace_id: Uuid; + invitation_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations/{invitation_id}/resend'; }; -export type GetMyWorkspaceResponses = { +export type ResendMyWorkspaceInvitationErrors = { /** - * Accessible workspace details + * RFC 9457 problem */ - 200: unknown; + 429: Problem; }; -export type UpdateMyWorkspaceData = { - body: Object; - path: { - application_id: Uuid; - workspace_id: Uuid; - }; - query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}'; -}; +export type ResendMyWorkspaceInvitationError = ResendMyWorkspaceInvitationErrors[keyof ResendMyWorkspaceInvitationErrors]; -export type UpdateMyWorkspaceResponses = { +export type ResendMyWorkspaceInvitationResponses = { /** - * Workspace updated + * Workspace invitation credentials rotated and email queued */ - 204: void; + 202: InvitationResent; }; -export type UpdateMyWorkspaceResponse = UpdateMyWorkspaceResponses[keyof UpdateMyWorkspaceResponses]; +export type ResendMyWorkspaceInvitationResponse = ResendMyWorkspaceInvitationResponses[keyof ResendMyWorkspaceInvitationResponses]; -export type ListMyWorkspaceMembersData = { +export type ListMyWorkspaceAccessData = { body?: never; path: { application_id: Uuid; workspace_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}/members'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/access'; }; -export type ListMyWorkspaceMembersResponses = { +export type ListMyWorkspaceAccessResponses = { /** - * Cursor page + * Successful listMyWorkspaceAccess response. */ - 200: Page; + 200: WorkspaceAccessPage; }; -export type ListMyWorkspaceMembersResponse = ListMyWorkspaceMembersResponses[keyof ListMyWorkspaceMembersResponses]; +export type ListMyWorkspaceAccessResponse = ListMyWorkspaceAccessResponses[keyof ListMyWorkspaceAccessResponses]; -export type RemoveMyWorkspaceMemberData = { +export type ListWorkspacePermissionGrantsData = { body?: never; path: { application_id: Uuid; workspace_id: Uuid; - user_id: Uuid; }; - query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; + query?: { + subject_type?: 'user' | 'client'; + subject_id?: Uuid; + status?: 'active' | 'revoked'; + }; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants'; }; -export type RemoveMyWorkspaceMemberResponses = { +export type ListWorkspacePermissionGrantsErrors = { /** - * Workspace member removed + * RFC 9457 problem */ - 204: void; + 403: Problem; }; -export type RemoveMyWorkspaceMemberResponse = RemoveMyWorkspaceMemberResponses[keyof RemoveMyWorkspaceMemberResponses]; +export type ListWorkspacePermissionGrantsError = ListWorkspacePermissionGrantsErrors[keyof ListWorkspacePermissionGrantsErrors]; -export type ReplaceMyWorkspaceMemberRolesData = { - body: Object; +export type ListWorkspacePermissionGrantsResponses = { + /** + * Successful listWorkspacePermissionGrants response. + */ + 200: PermissionGrantPage; +}; + +export type ListWorkspacePermissionGrantsResponse = ListWorkspacePermissionGrantsResponses[keyof ListWorkspacePermissionGrantsResponses]; + +export type CreateWorkspacePermissionGrantData = { + body: PermissionGrantBody; + headers: { + 'Idempotency-Key': string; + }; path: { application_id: Uuid; workspace_id: Uuid; - user_id: Uuid; }; - query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}/members/{user_id}'; + query?: { + subject_type?: 'user' | 'client'; + subject_id?: Uuid; + status?: 'active' | 'revoked'; + }; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants'; }; -export type ReplaceMyWorkspaceMemberRolesResponses = { +export type CreateWorkspacePermissionGrantErrors = { /** - * Workspace member roles replaced + * RFC 9457 problem */ - 200: unknown; + 403: Problem; }; -export type TransferMyWorkspaceOwnershipData = { - body: OwnershipTransfer2; - path: { - application_id: Uuid; - workspace_id: Uuid; - }; - query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}/owner-transfer'; -}; +export type CreateWorkspacePermissionGrantError = CreateWorkspacePermissionGrantErrors[keyof CreateWorkspacePermissionGrantErrors]; -export type TransferMyWorkspaceOwnershipResponses = { +export type CreateWorkspacePermissionGrantResponses = { /** - * Workspace ownership transferred atomically + * Workspace direct permission grant created */ - 200: OwnershipTransferResult; + 201: PermissionGrant; }; -export type TransferMyWorkspaceOwnershipResponse = TransferMyWorkspaceOwnershipResponses[keyof TransferMyWorkspaceOwnershipResponses]; +export type CreateWorkspacePermissionGrantResponse = CreateWorkspacePermissionGrantResponses[keyof CreateWorkspacePermissionGrantResponses]; -export type LeaveWorkspaceData = { +export type RevokeWorkspacePermissionGrantData = { body?: never; + headers: { + /** + * Current resource ETag. + */ + 'If-Match': string; + }; path: { application_id: Uuid; workspace_id: Uuid; + grant_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}/membership'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}'; }; -export type LeaveWorkspaceResponses = { +export type RevokeWorkspacePermissionGrantErrors = { /** - * Current membership removed + * RFC 9457 problem + */ + 409: Problem; +}; + +export type RevokeWorkspacePermissionGrantError = RevokeWorkspacePermissionGrantErrors[keyof RevokeWorkspacePermissionGrantErrors]; + +export type RevokeWorkspacePermissionGrantResponses = { + /** + * Workspace direct permission grant revoked */ 204: void; }; -export type LeaveWorkspaceResponse = LeaveWorkspaceResponses[keyof LeaveWorkspaceResponses]; +export type RevokeWorkspacePermissionGrantResponse = RevokeWorkspacePermissionGrantResponses[keyof RevokeWorkspacePermissionGrantResponses]; -export type CreateMyWorkspaceInvitationData = { - body: Object; +export type GetWorkspacePermissionGrantData = { + body?: never; path: { application_id: Uuid; workspace_id: Uuid; + grant_id: Uuid; }; query?: never; - url: '/v1/applications/{application_id}/workspaces/{workspace_id}/invitations'; + url: '/v1/applications/{application_id}/workspaces/{workspace_id}/permission-grants/{grant_id}'; }; -export type CreateMyWorkspaceInvitationResponses = { +export type GetWorkspacePermissionGrantResponses = { /** - * Workspace invitation created + * Workspace direct permission grant */ - 201: unknown; + 200: PermissionGrant; }; +export type GetWorkspacePermissionGrantResponse = GetWorkspacePermissionGrantResponses[keyof GetWorkspacePermissionGrantResponses]; + export type GetWorkspaceBillingProfileData = { body?: never; path: { @@ -5673,11 +9023,13 @@ export type GetWorkspaceBillingProfileResponses = { /** * Workspace billing profile */ - 200: unknown; + 200: BillingProfile; }; +export type GetWorkspaceBillingProfileResponse = GetWorkspaceBillingProfileResponses[keyof GetWorkspaceBillingProfileResponses]; + export type UpdateWorkspaceBillingProfileData = { - body: Object; + body: UpdateBillingProfile; path: { application_id: Uuid; workspace_id: Uuid; @@ -5707,15 +9059,15 @@ export type ListWorkspaceAddressesData = { export type ListWorkspaceAddressesResponses = { /** - * Cursor page + * Successful listWorkspaceAddresses response. */ - 200: Page; + 200: AddressPage; }; export type ListWorkspaceAddressesResponse = ListWorkspaceAddressesResponses[keyof ListWorkspaceAddressesResponses]; export type CreateWorkspaceAddressData = { - body: Object; + body: CreateAddress; path: { application_id: Uuid; workspace_id: Uuid; @@ -5728,9 +9080,11 @@ export type CreateWorkspaceAddressResponses = { /** * Workspace billing address created */ - 201: unknown; + 201: Address; }; +export type CreateWorkspaceAddressResponse = CreateWorkspaceAddressResponses[keyof CreateWorkspaceAddressResponses]; + export type DeleteWorkspaceAddressData = { body?: never; path: { @@ -5752,7 +9106,7 @@ export type DeleteWorkspaceAddressResponses = { export type DeleteWorkspaceAddressResponse = DeleteWorkspaceAddressResponses[keyof DeleteWorkspaceAddressResponses]; export type UpdateWorkspaceAddressData = { - body: Object; + body: UpdateAddress; path: { application_id: Uuid; workspace_id: Uuid; @@ -5791,7 +9145,7 @@ export type ActivateWorkspaceAddressResponses = { export type ActivateWorkspaceAddressResponse = ActivateWorkspaceAddressResponses[keyof ActivateWorkspaceAddressResponses]; -export type ListMyWorkspaceInvitationsData = { +export type ListMyPendingInvitationsData = { body?: never; path: { application_id: Uuid; @@ -5800,34 +9154,17 @@ export type ListMyWorkspaceInvitationsData = { url: '/v1/applications/{application_id}/me/workspace-invitations'; }; -export type ListMyWorkspaceInvitationsResponses = { +export type ListMyPendingInvitationsResponses = { /** - * Cursor page + * Successful listMyPendingInvitations response. */ - 200: Page; -}; - -export type ListMyWorkspaceInvitationsResponse = ListMyWorkspaceInvitationsResponses[keyof ListMyWorkspaceInvitationsResponses]; - -export type AcceptMyWorkspaceInvitationData = { - body: Object; - path: { - application_id: Uuid; - invitation_id: Uuid; - }; - query?: never; - url: '/v1/applications/{application_id}/me/workspace-invitations/{invitation_id}/accept'; + 200: ApplicationInvitationPage; }; -export type AcceptMyWorkspaceInvitationResponses = { - /** - * Workspace invitation accepted atomically - */ - 200: unknown; -}; +export type ListMyPendingInvitationsResponse = ListMyPendingInvitationsResponses[keyof ListMyPendingInvitationsResponses]; export type CheckMyPermissionsData = { - body: Object; + body: PermissionCheck; path: { application_id: Uuid; }; @@ -5839,9 +9176,11 @@ export type CheckMyPermissionsResponses = { /** * Permission decisions with role explanations */ - 200: unknown; + 200: PermissionCheckResult; }; +export type CheckMyPermissionsResponse = CheckMyPermissionsResponses[keyof CheckMyPermissionsResponses]; + export type ListMyOAuthConsentsData = { body?: never; path: { @@ -5853,9 +9192,9 @@ export type ListMyOAuthConsentsData = { export type ListMyOAuthConsentsResponses = { /** - * Cursor page + * Successful listMyOAuthConsents response. */ - 200: Page; + 200: OAuthConsentPage; }; export type ListMyOAuthConsentsResponse = ListMyOAuthConsentsResponses[keyof ListMyOAuthConsentsResponses]; @@ -5924,9 +9263,9 @@ export type ListEventsData = { export type ListEventsResponses = { /** - * Cursor page + * Successful listEvents response. */ - 200: Page; + 200: EventPage; }; export type ListEventsResponse = ListEventsResponses[keyof ListEventsResponses]; @@ -5961,9 +9300,9 @@ export type ListEventTypesData = { export type ListEventTypesResponses = { /** - * Cursor page + * Successful listEventTypes response. */ - 200: Page; + 200: EventTypePage; }; export type ListEventTypesResponse = ListEventTypesResponses[keyof ListEventTypesResponses]; @@ -5990,9 +9329,11 @@ export type CreateEventTypeResponses = { /** * Application event type registered */ - 201: unknown; + 201: EventTypeDefinition; }; +export type CreateEventTypeResponse = CreateEventTypeResponses[keyof CreateEventTypeResponses]; + export type ArchiveEventTypeData = { body?: never; path: { @@ -6070,9 +9411,9 @@ export type ListAuditLogsData = { export type ListAuditLogsResponses = { /** - * Cursor page + * Successful listAuditLogs response. */ - 200: Page; + 200: AuditRecordPage; }; export type ListAuditLogsResponse = ListAuditLogsResponses[keyof ListAuditLogsResponses]; @@ -6091,11 +9432,13 @@ export type GetAuditLogResponses = { /** * Audit record detail */ - 200: unknown; + 200: AuditRecord; }; +export type GetAuditLogResponse = GetAuditLogResponses[keyof GetAuditLogResponses]; + export type CreateAuditExportData = { - body: Object; + body: AuditExport; path: { application_id: Uuid; }; @@ -6107,9 +9450,11 @@ export type CreateAuditExportResponses = { /** * Encrypted one-hour audit export created */ - 201: unknown; + 201: AuditExportRecord; }; +export type CreateAuditExportResponse = CreateAuditExportResponses[keyof CreateAuditExportResponses]; + export type GetAuditExportData = { body?: never; path: { @@ -6124,9 +9469,11 @@ export type GetAuditExportResponses = { /** * Decrypted audit export before expiry */ - 200: unknown; + 200: AuditExportRecord; }; +export type GetAuditExportResponse = GetAuditExportResponses[keyof GetAuditExportResponses]; + export type ListWebhooksData = { body?: never; path: { @@ -6138,15 +9485,15 @@ export type ListWebhooksData = { export type ListWebhooksResponses = { /** - * Cursor page + * Successful listWebhooks response. */ - 200: Page; + 200: WebhookPage; }; export type ListWebhooksResponse = ListWebhooksResponses[keyof ListWebhooksResponses]; export type CreateWebhookData = { - body: Object; + body: CreateWebhook; path: { application_id: Uuid; }; @@ -6158,9 +9505,11 @@ export type CreateWebhookResponses = { /** * Webhook created and secret returned once */ - 201: unknown; + 201: Webhook; }; +export type CreateWebhookResponse = CreateWebhookResponses[keyof CreateWebhookResponses]; + export type DisableWebhookData = { body?: never; path: { @@ -6203,11 +9552,13 @@ export type GetWebhookResponses = { /** * Webhook endpoint and delivery statistics */ - 200: unknown; + 200: Webhook; }; +export type GetWebhookResponse = GetWebhookResponses[keyof GetWebhookResponses]; + export type UpdateWebhookData = { - body: Object; + body: UpdateWebhook; path: { application_id: Uuid; webhook_id: Uuid; @@ -6260,9 +9611,11 @@ export type TestWebhookResponses = { /** * Targeted signed test delivery queued */ - 202: unknown; + 202: WebhookTestAccepted; }; +export type TestWebhookResponse = TestWebhookResponses[keyof TestWebhookResponses]; + export type RotateWebhookSecretData = { body?: never; path: { @@ -6277,9 +9630,11 @@ export type RotateWebhookSecretResponses = { /** * Webhook secret rotated and returned once */ - 200: unknown; + 200: SecretCredential; }; +export type RotateWebhookSecretResponse = RotateWebhookSecretResponses[keyof RotateWebhookSecretResponses]; + export type ListWebhookDeliveriesData = { body?: never; path: { @@ -6291,9 +9646,9 @@ export type ListWebhookDeliveriesData = { export type ListWebhookDeliveriesResponses = { /** - * Cursor page + * Successful listWebhookDeliveries response. */ - 200: Page; + 200: WebhookDeliveryPage; }; export type ListWebhookDeliveriesResponse = ListWebhookDeliveriesResponses[keyof ListWebhookDeliveriesResponses]; @@ -6321,9 +9676,11 @@ export type GetWebhookDeliveryResponses = { /** * Webhook delivery history detail */ - 200: unknown; + 200: WebhookDelivery; }; +export type GetWebhookDeliveryResponse = GetWebhookDeliveryResponses[keyof GetWebhookDeliveryResponses]; + export type ReplayWebhookDeliveryData = { body?: never; path: { @@ -6354,9 +9711,9 @@ export type ListNotificationProvidersData = { export type ListNotificationProvidersResponses = { /** - * Cursor page + * Successful listNotificationProviders response. */ - 200: Page; + 200: NotificationProviderPage; }; export type ListNotificationProvidersResponse = ListNotificationProvidersResponses[keyof ListNotificationProvidersResponses]; @@ -6374,9 +9731,11 @@ export type CreateNotificationProviderResponses = { /** * SMTP provider stored */ - 201: unknown; + 201: NotificationProvider; }; +export type CreateNotificationProviderResponse = CreateNotificationProviderResponses[keyof CreateNotificationProviderResponses]; + export type DisableNotificationProviderData = { body?: never; path: { @@ -6410,11 +9769,13 @@ export type GetNotificationProviderResponses = { /** * Redacted provider configuration and health */ - 200: unknown; + 200: NotificationProvider; }; +export type GetNotificationProviderResponse = GetNotificationProviderResponses[keyof GetNotificationProviderResponses]; + export type UpdateNotificationProviderData = { - body: Object; + body: UpdateSmtpProviderWritable; path: { application_id: Uuid; provider_id: Uuid; @@ -6427,9 +9788,11 @@ export type UpdateNotificationProviderResponses = { /** * Redacted updated provider configuration */ - 200: unknown; + 200: NotificationProvider; }; +export type UpdateNotificationProviderResponse = UpdateNotificationProviderResponses[keyof UpdateNotificationProviderResponses]; + export type VerifyNotificationProviderData = { body?: never; path: { @@ -6459,7 +9822,7 @@ export type VerifyNotificationProviderResponses = { export type VerifyNotificationProviderResponse = VerifyNotificationProviderResponses[keyof VerifyNotificationProviderResponses]; export type TestNotificationProviderData = { - body: Object; + body: TestNotificationProvider; headers?: { 'Idempotency-Key'?: string; }; @@ -6475,9 +9838,11 @@ export type TestNotificationProviderResponses = { /** * Provider-specific test notification queued */ - 202: unknown; + 202: NotificationQueued; }; +export type TestNotificationProviderResponse = TestNotificationProviderResponses[keyof TestNotificationProviderResponses]; + export type ListSenderIdentitiesData = { body?: never; path: { @@ -6489,15 +9854,15 @@ export type ListSenderIdentitiesData = { export type ListSenderIdentitiesResponses = { /** - * Cursor page + * Successful listSenderIdentities response. */ - 200: Page; + 200: SenderIdentityPage; }; export type ListSenderIdentitiesResponse = ListSenderIdentitiesResponses[keyof ListSenderIdentitiesResponses]; export type CreateSenderIdentityData = { - body: Object; + body: CreateSenderIdentity; path: { application_id: Uuid; }; @@ -6509,9 +9874,11 @@ export type CreateSenderIdentityResponses = { /** * Sender identity created */ - 201: unknown; + 201: SenderIdentity; }; +export type CreateSenderIdentityResponse = CreateSenderIdentityResponses[keyof CreateSenderIdentityResponses]; + export type SetDefaultSenderIdentityData = { body?: never; path: { @@ -6540,15 +9907,15 @@ export type ListInstallationNotificationTemplatesData = { export type ListInstallationNotificationTemplatesResponses = { /** - * Cursor page + * Successful listInstallationNotificationTemplates response. */ - 200: Page; + 200: NotificationTemplatePage; }; export type ListInstallationNotificationTemplatesResponse = ListInstallationNotificationTemplatesResponses[keyof ListInstallationNotificationTemplatesResponses]; export type CreateInstallationNotificationTemplateData = { - body: Object; + body: CreateNotificationTemplate; path?: never; query?: never; url: '/v1/control/installation/notification-templates'; @@ -6558,9 +9925,11 @@ export type CreateInstallationNotificationTemplateResponses = { /** * Installation template draft created */ - 201: unknown; + 201: NotificationTemplate; }; +export type CreateInstallationNotificationTemplateResponse = CreateInstallationNotificationTemplateResponses[keyof CreateInstallationNotificationTemplateResponses]; + export type ListInstallationNotificationTemplateVariablesData = { body?: never; path?: never; @@ -6572,9 +9941,11 @@ export type ListInstallationNotificationTemplateVariablesResponses = { /** * Installation template variables and samples */ - 200: unknown; + 200: TemplateVariables; }; +export type ListInstallationNotificationTemplateVariablesResponse = ListInstallationNotificationTemplateVariablesResponses[keyof ListInstallationNotificationTemplateVariablesResponses]; + export type GetInstallationNotificationTemplateData = { body?: never; path: { @@ -6588,11 +9959,13 @@ export type GetInstallationNotificationTemplateResponses = { /** * Installation template and immutable history */ - 200: unknown; + 200: NotificationTemplate; }; +export type GetInstallationNotificationTemplateResponse = GetInstallationNotificationTemplateResponses[keyof GetInstallationNotificationTemplateResponses]; + export type UpdateInstallationNotificationTemplateData = { - body: Object; + body: UpdateNotificationTemplate; path: { template_id: Uuid; }; @@ -6604,11 +9977,13 @@ export type UpdateInstallationNotificationTemplateResponses = { /** * New installation template draft version created */ - 201: unknown; + 201: NotificationTemplate; }; +export type UpdateInstallationNotificationTemplateResponse = UpdateInstallationNotificationTemplateResponses[keyof UpdateInstallationNotificationTemplateResponses]; + export type PreviewInstallationNotificationTemplateData = { - body: Object; + body: PreviewNotificationTemplate; path: { template_id: Uuid; }; @@ -6620,9 +9995,11 @@ export type PreviewInstallationNotificationTemplateResponses = { /** * Safely rendered installation template preview */ - 200: unknown; + 200: NotificationTemplatePreview; }; +export type PreviewInstallationNotificationTemplateResponse = PreviewInstallationNotificationTemplateResponses[keyof PreviewInstallationNotificationTemplateResponses]; + export type PublishInstallationNotificationTemplateData = { body?: never; path: { @@ -6670,15 +10047,15 @@ export type ListNotificationTemplatesData = { export type ListNotificationTemplatesResponses = { /** - * Cursor page + * Successful listNotificationTemplates response. */ - 200: Page; + 200: NotificationTemplatePage; }; export type ListNotificationTemplatesResponse = ListNotificationTemplatesResponses[keyof ListNotificationTemplatesResponses]; export type CreateNotificationTemplateData = { - body: Object; + body: CreateNotificationTemplate; path: { application_id: Uuid; }; @@ -6690,9 +10067,11 @@ export type CreateNotificationTemplateResponses = { /** * Immutable draft template version created */ - 201: unknown; + 201: NotificationTemplate; }; +export type CreateNotificationTemplateResponse = CreateNotificationTemplateResponses[keyof CreateNotificationTemplateResponses]; + export type ListNotificationTemplateVariablesData = { body?: never; path: { @@ -6706,9 +10085,11 @@ export type ListNotificationTemplateVariablesResponses = { /** * Built-in notification template variables and sample values */ - 200: unknown; + 200: TemplateVariables; }; +export type ListNotificationTemplateVariablesResponse = ListNotificationTemplateVariablesResponses[keyof ListNotificationTemplateVariablesResponses]; + export type GetNotificationTemplateData = { body?: never; path: { @@ -6723,11 +10104,13 @@ export type GetNotificationTemplateResponses = { /** * Template version and immutable version history */ - 200: unknown; + 200: NotificationTemplate; }; +export type GetNotificationTemplateResponse = GetNotificationTemplateResponses[keyof GetNotificationTemplateResponses]; + export type UpdateNotificationTemplateData = { - body: Object; + body: UpdateNotificationTemplate; path: { application_id: Uuid; template_id: Uuid; @@ -6740,11 +10123,13 @@ export type UpdateNotificationTemplateResponses = { /** * New immutable draft version created */ - 201: unknown; + 201: NotificationTemplate; }; +export type UpdateNotificationTemplateResponse = UpdateNotificationTemplateResponses[keyof UpdateNotificationTemplateResponses]; + export type PreviewNotificationTemplateData = { - body: Object; + body: PreviewNotificationTemplate; path: { application_id: Uuid; template_id: Uuid; @@ -6757,9 +10142,11 @@ export type PreviewNotificationTemplateResponses = { /** * Safely rendered preview without delivery */ - 200: unknown; + 200: NotificationTemplatePreview; }; +export type PreviewNotificationTemplateResponse = PreviewNotificationTemplateResponses[keyof PreviewNotificationTemplateResponses]; + export type PublishNotificationTemplateData = { body?: never; path: { @@ -6809,34 +10196,13 @@ export type ListNotificationsData = { export type ListNotificationsResponses = { /** - * Cursor page + * Successful listNotifications response. */ - 200: Page; + 200: NotificationPage; }; export type ListNotificationsResponse = ListNotificationsResponses[keyof ListNotificationsResponses]; -export type QueueNotificationData = { - body: QueueNotification; - headers?: { - 'Idempotency-Key'?: string; - }; - path: { - application_id: Uuid; - }; - query?: never; - url: '/v1/control/applications/{application_id}/notifications'; -}; - -export type QueueNotificationResponses = { - /** - * Rendered locale-aware template snapshot queued or suppressed by preference - */ - 202: QueuedNotification; -}; - -export type QueueNotificationResponse = QueueNotificationResponses[keyof QueueNotificationResponses]; - export type GetNotificationStatisticsData = { body?: never; path: { @@ -6850,9 +10216,11 @@ export type GetNotificationStatisticsResponses = { /** * Notification and attempt status totals */ - 200: unknown; + 200: NotificationStatistics; }; +export type GetNotificationStatisticsResponse = GetNotificationStatisticsResponses[keyof GetNotificationStatisticsResponses]; + export type GetNotificationData = { body?: never; path: { @@ -6867,9 +10235,11 @@ export type GetNotificationResponses = { /** * Notification metadata, attachment metadata, and attempts without encrypted payload */ - 200: unknown; + 200: Notification; }; +export type GetNotificationResponse = GetNotificationResponses[keyof GetNotificationResponses]; + export type RetryNotificationData = { body?: never; path: { @@ -6900,15 +10270,15 @@ export type ListMyNotificationPreferencesData = { export type ListMyNotificationPreferencesResponses = { /** - * Cursor page + * Successful listMyNotificationPreferences response. */ - 200: Page; + 200: NotificationPreferencePage; }; export type ListMyNotificationPreferencesResponse = ListMyNotificationPreferencesResponses[keyof ListMyNotificationPreferencesResponses]; export type UpdateMyNotificationPreferenceData = { - body: Object; + body: UpdateNotificationPreference; path: { application_id: Uuid; category: 'transactional' | 'billing' | 'product' | 'marketing'; @@ -6935,15 +10305,15 @@ export type ListInstallationStorageProvidersData = { export type ListInstallationStorageProvidersResponses = { /** - * Cursor page + * Successful listInstallationStorageProviders response. */ - 200: Page; + 200: StorageProviderPage; }; export type ListInstallationStorageProvidersResponse = ListInstallationStorageProvidersResponses[keyof ListInstallationStorageProvidersResponses]; export type CreateInstallationStorageProviderData = { - body: StorageProvider; + body: StorageProviderBody; path?: never; query?: never; url: '/v1/control/installation/storage/providers'; @@ -6953,9 +10323,11 @@ export type CreateInstallationStorageProviderResponses = { /** * Storage provider stored without exposing credentials */ - 201: unknown; + 201: StorageProvider; }; +export type CreateInstallationStorageProviderResponse = CreateInstallationStorageProviderResponses[keyof CreateInstallationStorageProviderResponses]; + export type DisableInstallationStorageProviderData = { body?: never; path: { @@ -7001,11 +10373,13 @@ export type GetInstallationStorageProviderResponses = { /** * Secret-free storage provider */ - 200: unknown; + 200: StorageProvider; }; +export type GetInstallationStorageProviderResponse = GetInstallationStorageProviderResponses[keyof GetInstallationStorageProviderResponses]; + export type UpdateInstallationStorageProviderData = { - body: Object; + body: UpdateStorageProviderWritable; path: { provider_id: Uuid; }; @@ -7017,9 +10391,11 @@ export type UpdateInstallationStorageProviderResponses = { /** * Storage provider updated and marked unverified */ - 200: unknown; + 200: StorageProvider; }; +export type UpdateInstallationStorageProviderResponse = UpdateInstallationStorageProviderResponses[keyof UpdateInstallationStorageProviderResponses]; + export type VerifyInstallationStorageProviderData = { body?: never; path: { @@ -7060,9 +10436,11 @@ export type EnableInstallationStorageProviderResponses = { /** * Provider re-enabled */ - 200: unknown; + 200: StorageProviderStatus; }; +export type EnableInstallationStorageProviderResponse = EnableInstallationStorageProviderResponses[keyof EnableInstallationStorageProviderResponses]; + export type ListOrganizationStorageProvidersData = { body?: never; path: { @@ -7074,15 +10452,15 @@ export type ListOrganizationStorageProvidersData = { export type ListOrganizationStorageProvidersResponses = { /** - * Cursor page + * Successful listOrganizationStorageProviders response. */ - 200: Page; + 200: StorageProviderPage; }; export type ListOrganizationStorageProvidersResponse = ListOrganizationStorageProvidersResponses[keyof ListOrganizationStorageProvidersResponses]; export type CreateOrganizationStorageProviderData = { - body: StorageProvider; + body: StorageProviderBody; path: { organization_id: Uuid; }; @@ -7094,9 +10472,11 @@ export type CreateOrganizationStorageProviderResponses = { /** * Organization storage override stored */ - 201: unknown; + 201: StorageProvider; }; +export type CreateOrganizationStorageProviderResponse = CreateOrganizationStorageProviderResponses[keyof CreateOrganizationStorageProviderResponses]; + export type DisableOrganizationStorageProviderData = { body?: never; path: { @@ -7144,11 +10524,13 @@ export type GetOrganizationStorageProviderResponses = { /** * Secret-free storage provider */ - 200: unknown; + 200: StorageProvider; }; +export type GetOrganizationStorageProviderResponse = GetOrganizationStorageProviderResponses[keyof GetOrganizationStorageProviderResponses]; + export type UpdateOrganizationStorageProviderData = { - body: Object; + body: UpdateStorageProviderWritable; path: { organization_id: Uuid; provider_id: Uuid; @@ -7161,9 +10543,11 @@ export type UpdateOrganizationStorageProviderResponses = { /** * Storage provider updated and marked unverified */ - 200: unknown; + 200: StorageProvider; }; +export type UpdateOrganizationStorageProviderResponse = UpdateOrganizationStorageProviderResponses[keyof UpdateOrganizationStorageProviderResponses]; + export type VerifyOrganizationStorageProviderData = { body?: never; path: { @@ -7197,9 +10581,11 @@ export type EnableOrganizationStorageProviderResponses = { /** * Provider re-enabled */ - 200: unknown; + 200: StorageProviderStatus; }; +export type EnableOrganizationStorageProviderResponse = EnableOrganizationStorageProviderResponses[keyof EnableOrganizationStorageProviderResponses]; + export type ListApplicationStorageProvidersData = { body?: never; path: { @@ -7211,15 +10597,15 @@ export type ListApplicationStorageProvidersData = { export type ListApplicationStorageProvidersResponses = { /** - * Cursor page + * Successful listApplicationStorageProviders response. */ - 200: Page; + 200: StorageProviderPage; }; export type ListApplicationStorageProvidersResponse = ListApplicationStorageProvidersResponses[keyof ListApplicationStorageProvidersResponses]; export type CreateApplicationStorageProviderData = { - body: StorageProvider; + body: StorageProviderBody; path: { application_id: Uuid; }; @@ -7231,9 +10617,11 @@ export type CreateApplicationStorageProviderResponses = { /** * Application storage override stored */ - 201: unknown; + 201: StorageProvider; }; +export type CreateApplicationStorageProviderResponse = CreateApplicationStorageProviderResponses[keyof CreateApplicationStorageProviderResponses]; + export type DisableApplicationStorageProviderData = { body?: never; path: { @@ -7281,11 +10669,13 @@ export type GetApplicationStorageProviderResponses = { /** * Secret-free storage provider */ - 200: unknown; + 200: StorageProvider; }; +export type GetApplicationStorageProviderResponse = GetApplicationStorageProviderResponses[keyof GetApplicationStorageProviderResponses]; + export type UpdateApplicationStorageProviderData = { - body: Object; + body: UpdateStorageProviderWritable; path: { application_id: Uuid; provider_id: Uuid; @@ -7298,9 +10688,11 @@ export type UpdateApplicationStorageProviderResponses = { /** * Storage provider updated and marked unverified */ - 200: unknown; + 200: StorageProvider; }; +export type UpdateApplicationStorageProviderResponse = UpdateApplicationStorageProviderResponses[keyof UpdateApplicationStorageProviderResponses]; + export type VerifyApplicationStorageProviderData = { body?: never; path: { @@ -7334,9 +10726,11 @@ export type EnableApplicationStorageProviderResponses = { /** * Provider re-enabled */ - 200: unknown; + 200: StorageProviderStatus; }; +export type EnableApplicationStorageProviderResponse = EnableApplicationStorageProviderResponses[keyof EnableApplicationStorageProviderResponses]; + export type CreateInstallationStorageUploadData = { body: StorageUpload; headers: { @@ -7369,9 +10763,11 @@ export type CompleteInstallationStorageUploadResponses = { /** * Upload verified */ - 200: unknown; + 200: StorageObject; }; +export type CompleteInstallationStorageUploadResponse = CompleteInstallationStorageUploadResponses[keyof CompleteInstallationStorageUploadResponses]; + export type ListInstallationStorageObjectsData = { body?: never; path?: never; @@ -7381,9 +10777,9 @@ export type ListInstallationStorageObjectsData = { export type ListInstallationStorageObjectsResponses = { /** - * Cursor page + * Successful listInstallationStorageObjects response. */ - 200: Page; + 200: StorageObjectPage; }; export type ListInstallationStorageObjectsResponse = ListInstallationStorageObjectsResponses[keyof ListInstallationStorageObjectsResponses]; @@ -7424,9 +10820,11 @@ export type GetInstallationStorageObjectResponses = { /** * Installation asset metadata */ - 200: unknown; + 200: StorageObject; }; +export type GetInstallationStorageObjectResponse = GetInstallationStorageObjectResponses[keyof GetInstallationStorageObjectResponses]; + export type DownloadInstallationStorageObjectData = { body?: never; path: { @@ -7440,9 +10838,11 @@ export type DownloadInstallationStorageObjectResponses = { /** * Public or short-lived private URL */ - 200: unknown; + 200: StorageDownload; }; +export type DownloadInstallationStorageObjectResponse = DownloadInstallationStorageObjectResponses[keyof DownloadInstallationStorageObjectResponses]; + export type ListOrganizationStorageObjectsData = { body?: never; path: { @@ -7454,9 +10854,9 @@ export type ListOrganizationStorageObjectsData = { export type ListOrganizationStorageObjectsResponses = { /** - * Cursor page + * Successful listOrganizationStorageObjects response. */ - 200: Page; + 200: StorageObjectPage; }; export type ListOrganizationStorageObjectsResponse = ListOrganizationStorageObjectsResponses[keyof ListOrganizationStorageObjectsResponses]; @@ -7499,9 +10899,11 @@ export type GetOrganizationStorageObjectResponses = { /** * Organization object metadata */ - 200: unknown; + 200: StorageObject; }; +export type GetOrganizationStorageObjectResponse = GetOrganizationStorageObjectResponses[keyof GetOrganizationStorageObjectResponses]; + export type DownloadOrganizationStorageObjectData = { body?: never; path: { @@ -7516,9 +10918,11 @@ export type DownloadOrganizationStorageObjectResponses = { /** * Public or short-lived private URL */ - 200: unknown; + 200: StorageDownload; }; +export type DownloadOrganizationStorageObjectResponse = DownloadOrganizationStorageObjectResponses[keyof DownloadOrganizationStorageObjectResponses]; + export type CreateControlApplicationStorageUploadData = { body: StorageUpload; headers: { @@ -7535,9 +10939,11 @@ export type CreateControlApplicationStorageUploadResponses = { /** * Presigned application asset upload */ - 201: unknown; + 201: StorageUploadAuthorization; }; +export type CreateControlApplicationStorageUploadResponse = CreateControlApplicationStorageUploadResponses[keyof CreateControlApplicationStorageUploadResponses]; + export type CompleteControlApplicationStorageUploadData = { body?: never; path: { @@ -7552,9 +10958,11 @@ export type CompleteControlApplicationStorageUploadResponses = { /** * Upload verified */ - 200: unknown; + 200: StorageObject; }; +export type CompleteControlApplicationStorageUploadResponse = CompleteControlApplicationStorageUploadResponses[keyof CompleteControlApplicationStorageUploadResponses]; + export type ListControlApplicationStorageObjectsData = { body?: never; path: { @@ -7566,9 +10974,9 @@ export type ListControlApplicationStorageObjectsData = { export type ListControlApplicationStorageObjectsResponses = { /** - * Cursor page + * Successful listControlApplicationStorageObjects response. */ - 200: Page; + 200: StorageObjectPage; }; export type ListControlApplicationStorageObjectsResponse = ListControlApplicationStorageObjectsResponses[keyof ListControlApplicationStorageObjectsResponses]; @@ -7611,9 +11019,11 @@ export type GetControlApplicationStorageObjectResponses = { /** * Application object metadata */ - 200: unknown; + 200: StorageObject; }; +export type GetControlApplicationStorageObjectResponse = GetControlApplicationStorageObjectResponses[keyof GetControlApplicationStorageObjectResponses]; + export type DownloadControlApplicationStorageObjectData = { body?: never; path: { @@ -7628,9 +11038,11 @@ export type DownloadControlApplicationStorageObjectResponses = { /** * Public or short-lived private URL */ - 200: unknown; + 200: StorageDownload; }; +export type DownloadControlApplicationStorageObjectResponse = DownloadControlApplicationStorageObjectResponses[keyof DownloadControlApplicationStorageObjectResponses]; + export type CreateApplicationStorageUploadData = { body: StorageUpload; headers: { @@ -7647,9 +11059,11 @@ export type CreateApplicationStorageUploadResponses = { /** * Presigned application-owned upload */ - 201: unknown; + 201: StorageUploadAuthorization; }; +export type CreateApplicationStorageUploadResponse = CreateApplicationStorageUploadResponses[keyof CreateApplicationStorageUploadResponses]; + export type CompleteApplicationStorageUploadData = { body?: never; path: { @@ -7664,9 +11078,11 @@ export type CompleteApplicationStorageUploadResponses = { /** * Upload verified */ - 200: unknown; + 200: StorageObject; }; +export type CompleteApplicationStorageUploadResponse = CompleteApplicationStorageUploadResponses[keyof CompleteApplicationStorageUploadResponses]; + export type ListApplicationStorageObjectsData = { body?: never; path: { @@ -7678,9 +11094,9 @@ export type ListApplicationStorageObjectsData = { export type ListApplicationStorageObjectsResponses = { /** - * Cursor page + * Successful listApplicationStorageObjects response. */ - 200: Page; + 200: StorageObjectPage; }; export type ListApplicationStorageObjectsResponse = ListApplicationStorageObjectsResponses[keyof ListApplicationStorageObjectsResponses]; @@ -7718,9 +11134,11 @@ export type GetApplicationStorageObjectResponses = { /** * Application object metadata */ - 200: unknown; + 200: StorageObject; }; +export type GetApplicationStorageObjectResponse = GetApplicationStorageObjectResponses[keyof GetApplicationStorageObjectResponses]; + export type DownloadApplicationStorageObjectData = { body?: never; path: { @@ -7735,9 +11153,11 @@ export type DownloadApplicationStorageObjectResponses = { /** * Public or short-lived private URL */ - 200: unknown; + 200: StorageDownload; }; +export type DownloadApplicationStorageObjectResponse = DownloadApplicationStorageObjectResponses[keyof DownloadApplicationStorageObjectResponses]; + export type CreateMyStorageUploadData = { body: StorageUpload; headers: { @@ -7754,9 +11174,11 @@ export type CreateMyStorageUploadResponses = { /** * Presigned user-owned upload */ - 201: unknown; + 201: StorageUploadAuthorization; }; +export type CreateMyStorageUploadResponse = CreateMyStorageUploadResponses[keyof CreateMyStorageUploadResponses]; + export type CompleteMyStorageUploadData = { body?: never; path: { @@ -7771,9 +11193,11 @@ export type CompleteMyStorageUploadResponses = { /** * Upload verified */ - 200: unknown; + 200: StorageObject; }; +export type CompleteMyStorageUploadResponse = CompleteMyStorageUploadResponses[keyof CompleteMyStorageUploadResponses]; + export type ListMyStorageObjectsData = { body?: never; path: { @@ -7785,9 +11209,9 @@ export type ListMyStorageObjectsData = { export type ListMyStorageObjectsResponses = { /** - * Cursor page + * Successful listMyStorageObjects response. */ - 200: Page; + 200: StorageObjectPage; }; export type ListMyStorageObjectsResponse = ListMyStorageObjectsResponses[keyof ListMyStorageObjectsResponses]; @@ -7825,9 +11249,11 @@ export type GetMyStorageObjectResponses = { /** * User object metadata */ - 200: unknown; + 200: StorageObject; }; +export type GetMyStorageObjectResponse = GetMyStorageObjectResponses[keyof GetMyStorageObjectResponses]; + export type DownloadMyStorageObjectData = { body?: never; path: { @@ -7842,9 +11268,11 @@ export type DownloadMyStorageObjectResponses = { /** * Public or short-lived private URL */ - 200: unknown; + 200: StorageDownload; }; +export type DownloadMyStorageObjectResponse = DownloadMyStorageObjectResponses[keyof DownloadMyStorageObjectResponses]; + export type CreateWorkspaceStorageUploadData = { body: StorageUpload; headers: { @@ -7862,9 +11290,11 @@ export type CreateWorkspaceStorageUploadResponses = { /** * Presigned workspace-owned upload */ - 201: unknown; + 201: StorageUploadAuthorization; }; +export type CreateWorkspaceStorageUploadResponse = CreateWorkspaceStorageUploadResponses[keyof CreateWorkspaceStorageUploadResponses]; + export type CompleteWorkspaceStorageUploadData = { body?: never; path: { @@ -7880,9 +11310,11 @@ export type CompleteWorkspaceStorageUploadResponses = { /** * Upload verified */ - 200: unknown; + 200: StorageObject; }; +export type CompleteWorkspaceStorageUploadResponse = CompleteWorkspaceStorageUploadResponses[keyof CompleteWorkspaceStorageUploadResponses]; + export type ListWorkspaceStorageObjectsData = { body?: never; path: { @@ -7895,9 +11327,9 @@ export type ListWorkspaceStorageObjectsData = { export type ListWorkspaceStorageObjectsResponses = { /** - * Cursor page + * Successful listWorkspaceStorageObjects response. */ - 200: Page; + 200: StorageObjectPage; }; export type ListWorkspaceStorageObjectsResponse = ListWorkspaceStorageObjectsResponses[keyof ListWorkspaceStorageObjectsResponses]; @@ -7937,9 +11369,11 @@ export type GetWorkspaceStorageObjectResponses = { /** * Workspace object metadata */ - 200: unknown; + 200: StorageObject; }; +export type GetWorkspaceStorageObjectResponse = GetWorkspaceStorageObjectResponses[keyof GetWorkspaceStorageObjectResponses]; + export type DownloadWorkspaceStorageObjectData = { body?: never; path: { @@ -7955,9 +11389,11 @@ export type DownloadWorkspaceStorageObjectResponses = { /** * Public or short-lived private URL */ - 200: unknown; + 200: StorageDownload; }; +export type DownloadWorkspaceStorageObjectResponse = DownloadWorkspaceStorageObjectResponses[keyof DownloadWorkspaceStorageObjectResponses]; + export type OidcDiscoveryData = { body?: never; path?: never; @@ -7969,9 +11405,11 @@ export type OidcDiscoveryResponses = { /** * OpenID Provider metadata */ - 200: unknown; + 200: OidcDiscovery; }; +export type OidcDiscoveryResponse = OidcDiscoveryResponses[keyof OidcDiscoveryResponses]; + export type OidcJwksData = { body?: never; path?: never; @@ -7983,9 +11421,11 @@ export type OidcJwksResponses = { /** * Active and retiring JSON Web Keys */ - 200: unknown; + 200: Jwks; }; +export type OidcJwksResponse = OidcJwksResponses[keyof OidcJwksResponses]; + export type BeginOidcAuthorizationData = { body?: never; path?: never; @@ -8005,9 +11445,11 @@ export type BeginOidcAuthorizationResponses = { /** * Headless consent interaction */ - 200: unknown; + 200: AuthorizationRedirect; }; +export type BeginOidcAuthorizationResponse = BeginOidcAuthorizationResponses[keyof BeginOidcAuthorizationResponses]; + export type DecideOidcAuthorizationData = { body: OAuthAuthorizationDecision; path?: never; @@ -8019,9 +11461,11 @@ export type DecideOidcAuthorizationResponses = { /** * Headless authorization response containing redirect_to when JSON is requested */ - 200: unknown; + 200: AuthorizationRedirect; }; +export type DecideOidcAuthorizationResponse = DecideOidcAuthorizationResponses[keyof DecideOidcAuthorizationResponses]; + export type ExchangeOidcTokenData = { body: OAuthToken; path?: never; @@ -8040,9 +11484,11 @@ export type ExchangeOidcTokenResponses = { /** * OAuth token response */ - 200: unknown; + 200: TokenResponse; }; +export type ExchangeOidcTokenResponse = ExchangeOidcTokenResponses[keyof ExchangeOidcTokenResponses]; + export type RevokeOidcTokenData = { body: OAuthTokenCredential; path?: never; @@ -8054,9 +11500,11 @@ export type RevokeOidcTokenResponses = { /** * Token revoked or already inactive */ - 200: unknown; + 200: EmptyResponse; }; +export type RevokeOidcTokenResponse = RevokeOidcTokenResponses[keyof RevokeOidcTokenResponses]; + export type IntrospectOidcTokenData = { body: OAuthTokenCredential; path?: never; @@ -8068,9 +11516,11 @@ export type IntrospectOidcTokenResponses = { /** * RFC 7662 token state */ - 200: unknown; + 200: TokenIntrospection; }; +export type IntrospectOidcTokenResponse = IntrospectOidcTokenResponses[keyof IntrospectOidcTokenResponses]; + export type OidcUserinfoData = { body?: never; path?: never; @@ -8091,9 +11541,11 @@ export type OidcUserinfoResponses = { /** * OpenID Connect claims */ - 200: unknown; + 200: UserInfo; }; +export type OidcUserinfoResponse = OidcUserinfoResponses[keyof OidcUserinfoResponses]; + export type StripeWebhookData = { body: unknown; headers: { @@ -8119,9 +11571,11 @@ export type StripeWebhookResponses = { /** * Event stored and processed */ - 200: unknown; + 200: WebhookAcknowledgement; }; +export type StripeWebhookResponse = StripeWebhookResponses[keyof StripeWebhookResponses]; + export type ManagementListOrganizationsData = { body?: never; path?: never; @@ -8133,9 +11587,9 @@ export type ManagementListOrganizationsData = { export type ManagementListOrganizationsResponses = { /** - * Cursor page + * Successful managementListOrganizations response. */ - 200: Page; + 200: OrganizationPage; }; export type ManagementListOrganizationsResponse = ManagementListOrganizationsResponses[keyof ManagementListOrganizationsResponses]; @@ -8149,11 +11603,13 @@ export type ManagementCreateOrganizationData = { export type ManagementCreateOrganizationResponses = { /** - * Organization provisioned without an operator membership + * Organization provisioned without a Platform user membership */ - 201: unknown; + 201: Organization; }; +export type ManagementCreateOrganizationResponse = ManagementCreateOrganizationResponses[keyof ManagementCreateOrganizationResponses]; + export type ManagementRetireOrganizationData = { body?: never; path: { @@ -8185,9 +11641,11 @@ export type ManagementGetOrganizationResponses = { /** * Organization details */ - 200: unknown; + 200: Organization; }; +export type ManagementGetOrganizationResponse = ManagementGetOrganizationResponses[keyof ManagementGetOrganizationResponses]; + export type ManagementUpdateOrganizationData = { body: Rename; headers: { @@ -8285,9 +11743,9 @@ export type ManagementListApplicationsData = { export type ManagementListApplicationsResponses = { /** - * Cursor page + * Successful managementListApplications response. */ - 200: Page; + 200: ApplicationPage; }; export type ManagementListApplicationsResponse = ManagementListApplicationsResponses[keyof ManagementListApplicationsResponses]; @@ -8314,9 +11772,11 @@ export type ManagementCreateApplicationResponses = { /** * Application provisioned */ - 201: unknown; + 201: Application; }; +export type ManagementCreateApplicationResponse = ManagementCreateApplicationResponses[keyof ManagementCreateApplicationResponses]; + export type ManagementRetireApplicationData = { body?: never; path: { diff --git a/sdk/typescript/sdk/src/index.ts b/sdk/typescript/sdk/src/index.ts index fd69b77..da7e0f8 100644 --- a/sdk/typescript/sdk/src/index.ts +++ b/sdk/typescript/sdk/src/index.ts @@ -16,6 +16,7 @@ export type Problem = { code: string; request_id?: string; errors?: Record; + affected_users?: number; }; export class Platform93Error extends Error { @@ -89,6 +90,14 @@ export class ApplicationClient { refresh(refreshToken: string) { return this.client.request("POST", this.path("/auth/token/refresh"), { refresh_token: refreshToken }); } startEmail(input: EmailStart) { return this.client.request<{ challenge_id: string; expires_in: number }>("POST", this.path("/auth/email/start"), input); } verifyEmail(input: EmailVerify) { return this.client.request("POST", this.path("/auth/email/verify"), input); } + startExternalAuth(provider: ExternalAuthProvider, input: ExternalAuthStart) { return this.client.request("POST", this.path(`/auth/providers/${provider}/start`), input); } + exchangeExternalAuth(provider: ExternalAuthProvider, exchange: string) { return this.client.request("POST", this.path(`/auth/providers/${provider}/exchange`), { exchange }); } + startGoogleAuth(input: ExternalAuthStart) { return this.startExternalAuth("google", input); } + exchangeGoogleAuth(exchange: string) { return this.exchangeExternalAuth("google", exchange); } + startAppleAuth(input: ExternalAuthStart) { return this.startExternalAuth("apple", input); } + exchangeAppleAuth(exchange: string) { return this.exchangeExternalAuth("apple", exchange); } + exchangeInvitation(input: InvitationExchange) { return this.client.request("POST", this.path("/auth/invitations/exchange"), input); } + redeemInvitation(input: { authorization_code: string; code_verifier: string }) { return this.client.request("POST", this.path("/auth/invitations/token"), input); } verifyMFA(input: MFAVerify) { return this.client.request("POST", this.path("/auth/mfa/verify"), input); } authMethods(email?: string) { return this.client.request("POST", this.path("/auth/methods"), email ? { email } : {}); } me() { return this.client.request("GET", this.path("/me")); } @@ -104,6 +113,11 @@ export class ApplicationClient { archiveWorkspace(workspaceId: string) { return this.client.request("DELETE", this.path(`/workspaces/${encodeURIComponent(workspaceId)}`)); } transferWorkspaceOwnership(workspaceId: string, input: { new_owner_user_id: string; previous_owner_disposition?: "member" | "remove" }) { return this.client.request("POST", this.path(`/workspaces/${encodeURIComponent(workspaceId)}/owner-transfer`), input); } leaveWorkspace(workspaceId: string) { return this.client.request("DELETE", this.path(`/workspaces/${encodeURIComponent(workspaceId)}/membership`)); } + listWorkspaceAccess(workspaceId: string) { return this.client.request>("GET", this.path(`/workspaces/${encodeURIComponent(workspaceId)}/access`)); } + createWorkspaceInvitation(workspaceId: string, input: Omit) { return this.client.request("POST", this.path(`/workspaces/${encodeURIComponent(workspaceId)}/invitations`), input); } + listWorkspaceInvitations(workspaceId: string) { return this.client.request>("GET", this.path(`/workspaces/${encodeURIComponent(workspaceId)}/invitations`)); } + resendWorkspaceInvitation(workspaceId: string, invitationId: string) { return this.client.request("POST", this.path(`/workspaces/${encodeURIComponent(workspaceId)}/invitations/${encodeURIComponent(invitationId)}/resend`)); } + revokeWorkspaceInvitation(workspaceId: string, invitationId: string) { return this.client.request("DELETE", this.path(`/workspaces/${encodeURIComponent(workspaceId)}/invitations/${encodeURIComponent(invitationId)}`)); } getBillingProfile(workspaceId?: string) { return this.client.request("GET", this.path(workspaceId ? `/workspaces/${encodeURIComponent(workspaceId)}/billing-profile` : "/me/billing-profile")); } updateBillingProfile(input: Partial & { version: number }, workspaceId?: string) { return this.client.request("PATCH", this.path(workspaceId ? `/workspaces/${encodeURIComponent(workspaceId)}/billing-profile` : "/me/billing-profile"), input); } listAddresses(workspaceId?: string) { return this.client.request>("GET", this.path(workspaceId ? `/workspaces/${encodeURIComponent(workspaceId)}/addresses` : "/me/addresses")); } @@ -166,13 +180,23 @@ export type PasswordSignIn = { email: string; password: string }; export type PasswordSignUp = PasswordSignIn & { first_name?: string; last_name?: string }; export type EmailStart = { email: string; intent: "sign_in" | "sign_up" | "automatic"; delivery: "code" | "link" | "both"; redirect_uri?: string }; export type EmailVerify = { challenge_id: string; code?: string; link_token?: string }; -export type LocalCheckoutInput = { price_id: string; subject_type?: "user" | "workspace"; subject_id?: string; address_id?: string; local_reference?: string }; -export type CheckoutInput = { price_id: string; provider_id: string; subject_type?: "user" | "workspace"; subject_id?: string; payment_methods?: Array<"card" | "twint">; success_uri: string; cancel_uri: string }; -export type CheckoutSession = { id: string; status: string; checkout_uri: string; provider_session_id: string }; -export type LocalEntitlementRequest = { id: string; status: string; product_snapshot: Record; price_snapshot: Record; feature_snapshot: Record; address_snapshot: Record | null; history?: Array> }; +export type ExternalAuthProvider = "google" | "apple"; +export type ExternalAuthFlow = "sign_in" | "sign_up" | "automatic"; +export type ExternalAuthStart = { redirect_uri: string; flow?: ExternalAuthFlow; login_hint?: string }; +export type ExternalAuthAuthorization = { provider: ExternalAuthProvider; authorize_url: string; expires_in: number }; +export type LocalCheckoutInput = { price_id: string; subject_type?: "user" | "workspace"; subject_id?: string; address_id?: string; external_reference?: string }; +export type CheckoutInput = { price_id: string; provider_id?: string; subject_type?: "user" | "workspace"; subject_id?: string; payment_methods?: Array<"card" | "twint">; success_uri: string; cancel_uri: string; external_reference?: string }; +export type CheckoutSession = { id: string; status: string; checkout_uri: string; provider_session_id: string; external_reference?: string | null }; +export type LocalEntitlementRequest = { id: string; status: string; external_reference?: string | null; product_snapshot: Record; price_snapshot: Record; feature_snapshot: Record; address_snapshot: Record | null; history?: Array> }; export type EffectiveEntitlements = { effective: Record; provenance: Record>>; sources: Array> }; export type BillingProfile = { id: string; subject_type: "user" | "workspace"; subject_id: string; name: string; email: string | null; tax_id: string | null; version: number }; export type WorkspaceOwnershipTransferResult = { workspace_id: string; owner_user_id: string; previous_owner_user_id: string; previous_owner_disposition: "member" | "remove" }; export type BillingAddress = { id: string; name: string; line1: string; line2: string; city: string; region: string; postal_code: string; country_code: string; tax_id?: string | null; active: boolean; version: number }; export type PublishCustomEvent = Record> = { type: string; subject: string; data: T; correlation_id?: string; causation_id?: string }; export type PublishedEvent = Record> = PublishCustomEvent & { specversion: "1.0"; id: string; source: string; schema_version: string }; +export type CreateInvitation = { email: string; workspace_id?: string; application_role_keys?: string[]; workspace_role_keys?: string[]; expires_in?: number }; +export type Invitation = { id: string; email: string; workspace_id?: string | null; application_role_keys: string[]; workspace_role_keys: string[]; status?: "pending" | "accepted" | "revoked" | "expired"; expires_at: string; last_sent_at: string; resend_available_at: string }; +export type InvitationCredential = { email: string; code: string; invitation_id?: never; link_token?: never } | { invitation_id: string; link_token: string; email?: never; code?: never }; +export type InvitationExchange = InvitationCredential & { code_challenge: string }; +export type InvitationAuthorizationCode = { authorization_code: string; expires_in: number }; +export type WorkspaceAccessEntry = { entry_type: "user"; status: "owner" | "active"; user_id: string; email: string; first_name: string; last_name: string; role_keys: string[] } | { entry_type: "invitation"; status: "pending" | "expired"; invitation_id: string; email: string; role_keys: string[]; expires_at: string; last_sent_at: string; resend_available_at: string }; diff --git a/sdk/typescript/server/README.md b/sdk/typescript/server/README.md index c570c94..4d8c0c8 100644 --- a/sdk/typescript/server/README.md +++ b/sdk/typescript/server/README.md @@ -8,3 +8,28 @@ npm install @supaapps/platform93-server The verifier enforces issuer, audience, actor type, application boundary, and token expiry rather than only checking the signature. + +Application backends can also use `Platform93MachineClient`. It exchanges OAuth +client credentials, caches the short-lived machine token, and exposes typed methods +for notifications, invitations, users, workspaces, entitlements, billing summaries, +and custom events. + +```ts +import { Platform93MachineClient } from "@supaapps/platform93-server"; + +const platform93 = new Platform93MachineClient({ + baseUrl: process.env.PLATFORM93_URL!, + applicationId: process.env.PLATFORM93_APPLICATION_ID!, + clientId: process.env.PLATFORM93_CLIENT_ID!, + clientSecret: process.env.PLATFORM93_CLIENT_SECRET!, +}); + +await platform93.sendNotification({ + template_key: "account.activity", + user_id: userId, + variables: { activity: "report_ready" }, +}, crypto.randomUUID()); +``` + +Machine credentials belong only in backend secret storage. Do not import this +client or expose its secret in browser bundles. diff --git a/sdk/typescript/server/package.json b/sdk/typescript/server/package.json index cd9cf67..0cc57f6 100644 --- a/sdk/typescript/server/package.json +++ b/sdk/typescript/server/package.json @@ -29,6 +29,7 @@ "typecheck": "tsc -p tsconfig.json --noEmit" }, "dependencies": { + "@supaapps/platform93-sdk": "workspace:*", "jose": "^6.0.12" }, "devDependencies": { diff --git a/sdk/typescript/server/src/index.ts b/sdk/typescript/server/src/index.ts index 67dd2dc..b8eb0f8 100644 --- a/sdk/typescript/server/src/index.ts +++ b/sdk/typescript/server/src/index.ts @@ -1,13 +1,26 @@ import { createRemoteJWKSet, customFetch, jwtVerify, type JWTPayload } from "jose"; +import { + Platform93Client, + Platform93Error, + generated, + type CreateInvitation, + type Invitation, + type Page, + type PublishCustomEvent, + type PublishedEvent, + type User, +} from "@supaapps/platform93-sdk"; export type Platform93Claims = JWTPayload & { application_id: string; token_kind: "access" | "machine"; actor_type: "user" | "client"; scope: string; + roles: { application: string[]; workspaces: Record }; locale?: string; email_verified?: boolean; is_org_verified?: boolean; + custom_claims?: Record; act?: { sub: string; type: string }; }; @@ -35,7 +48,7 @@ export function createVerifier(options: VerifierOptions) { algorithms: ["RS256"], typ: "JWT", clockTolerance: options.clockToleranceSeconds ?? 30, - requiredClaims: ["iss", "sub", "aud", "exp", "iat", "nbf", "application_id", "token_kind", "actor_type", "scope"], + requiredClaims: ["iss", "sub", "aud", "exp", "iat", "nbf", "application_id", "token_kind", "actor_type", "scope", "roles"], }); const claims = payload as Platform93Claims; const tolerance = options.clockToleranceSeconds ?? 30; @@ -45,13 +58,161 @@ export function createVerifier(options: VerifierOptions) { typeof claims.iat !== "number" || claims.iat > now + tolerance) { throw new Error("Platform93 token context rejected"); } - if (claims.act && (claims.token_kind !== "access" || claims.act.type !== "operator" || !claims.act.sub)) { + if (claims.act && (claims.token_kind !== "access" || claims.act.type !== "control_user" || !claims.act.sub)) { throw new Error("Platform93 delegated token actor rejected"); } + if (!validScopeClaim(claims.scope, options.applicationId) || !validRolesClaim(claims.roles) || + claims.act && (claims.roles.application.length !== 0 || Object.keys(claims.roles.workspaces).length !== 0)) { + throw new Error("Platform93 token authorization claims rejected"); + } return claims; }; } export function hasPermission(claims: Platform93Claims, permission: string) { - return claims.scope.split(/\s+/).some((value) => value === permission || value === "*" || value.endsWith("/*") && (permission === value.slice(0, -2) || permission.startsWith(value.slice(0, -1)))); + if (!validAbsolutePermission(permission)) return false; + return claims.scope.split(" ").some((value) => validAbsolutePermission(value) && + (value === permission || value.endsWith("/*") && (permission === value.slice(0, -2) || permission.startsWith(value.slice(0, -1))))); +} + +const permissionSegment = /^[a-z0-9][a-z0-9._-]{0,63}$/; +const roleKey = /^[a-z][a-z0-9_-]{0,62}$/; +const workspaceKey = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/; +const protocolScopes = new Set(["openid", "profile", "email", "offline_access"]); + +function validScopeClaim(scope: unknown, applicationId: string) { + if (typeof scope !== "string") return false; + if (scope === "") return true; + if (scope !== scope.trim() || /[\t\r\n]| {2}/.test(scope)) return false; + const values = scope.split(" "); + if (new Set(values).size !== values.length) return false; + const prefix = `/applications/${applicationId}/`; + return values.every((value) => protocolScopes.has(value) || value.startsWith(prefix) && validAbsolutePermission(value)); +} + +function validAbsolutePermission(value: string) { + if (!value.startsWith("/") || /[ :\\%\t\r\n]/.test(value)) return false; + const segments = value.slice(1).split("/"); + return segments.length >= 3 && segments.every((segment, index) => + segment === "*" ? index === segments.length - 1 : permissionSegment.test(segment)); +} + +function validRolesClaim(value: unknown): value is Platform93Claims["roles"] { + if (!value || typeof value !== "object" || Array.isArray(value)) return false; + const roles = value as Record; + if (Object.keys(roles).sort().join(",") !== "application,workspaces") return false; + if (!Array.isArray(roles.application) || !roles.workspaces || typeof roles.workspaces !== "object" || Array.isArray(roles.workspaces)) return false; + if (!uniqueRoleKeys(roles.application)) return false; + return Object.entries(roles.workspaces as Record).every(([workspaceId, values]) => + workspaceKey.test(workspaceId) && Array.isArray(values) && uniqueRoleKeys(values)); } + +function uniqueRoleKeys(values: unknown[]) { + return values.every((value) => typeof value === "string" && roleKey.test(value)) && new Set(values).size === values.length; +} + +export type MachineClientOptions = { + baseUrl: string; + applicationId: string; + clientId: string; + clientSecret: string; + scopes?: string[]; + fetch?: typeof globalThis.fetch; +}; + +export type MachineNotification = { + template_key: string; + user_id?: string; + recipient?: string; + locale?: string; + variables?: Record; + attachments?: Array<{ filename: string; content_type: string; content_base64: string }>; +}; + +export class Platform93MachineClient { + private readonly baseUrl: string; + private readonly applicationId: string; + private readonly clientId: string; + private clientSecret: string; + private readonly scopes: string[]; + private readonly fetcher: typeof globalThis.fetch; + private accessToken: string | null = null; + private expiresAt = 0; + private tokenRequest: Promise | null = null; + private readonly api: Platform93Client; + + constructor(options: MachineClientOptions) { + if (!options.baseUrl || !options.applicationId || !options.clientId || !options.clientSecret) { + throw new Error("Platform93 machine client requires baseUrl, applicationId, clientId, and clientSecret"); + } + this.baseUrl = options.baseUrl.replace(/\/$/, ""); + this.applicationId = options.applicationId; + this.clientId = options.clientId; + this.clientSecret = options.clientSecret; + this.scopes = options.scopes ?? []; + this.fetcher = options.fetch ?? globalThis.fetch.bind(globalThis); + this.api = new Platform93Client({ + baseUrl: this.baseUrl, + applicationId: this.applicationId, + fetch: this.fetcher, + accessToken: () => this.token(), + }); + } + + updateSecret(secret: string) { + if (!secret) throw new Error("Platform93 machine client secret is required"); + this.clientSecret = secret; + this.accessToken = null; + this.expiresAt = 0; + } + + async token() { + if (this.accessToken && Date.now() < this.expiresAt - 30_000) return this.accessToken; + if (this.tokenRequest) return this.tokenRequest; + this.tokenRequest = this.exchangeToken().finally(() => { this.tokenRequest = null; }); + return this.tokenRequest; + } + + sendNotification(input: MachineNotification, idempotencyKey: string) { + return this.request("POST", "/notifications", input, idempotencyKey); + } + createInvitation(input: CreateInvitation) { return this.request("POST", "/invitations", input); } + listInvitations() { return this.request>("GET", "/invitations"); } + getInvitation(id: string) { return this.request("GET", `/invitations/${encodeURIComponent(id)}`); } + resendInvitation(id: string) { return this.request("POST", `/invitations/${encodeURIComponent(id)}/resend`); } + revokeInvitation(id: string) { return this.request("DELETE", `/invitations/${encodeURIComponent(id)}`); } + listUsers() { return this.request>("GET", "/users"); } + getUser(id: string) { return this.request("GET", `/users/${encodeURIComponent(id)}`); } + listWorkspaces() { return this.request("GET", "/workspaces"); } + getWorkspace(id: string) { return this.request("GET", `/service/workspaces/${encodeURIComponent(id)}`); } + getWorkspaceAccess(id: string) { return this.request("GET", `/service/workspaces/${encodeURIComponent(id)}/access`); } + getEntitlements(subjectType: "user" | "workspace", subjectId: string) { return this.request("GET", `/subjects/${subjectType}/${encodeURIComponent(subjectId)}/entitlements`); } + getBilling(subjectType: "user" | "workspace", subjectId: string) { return this.request("GET", `/subjects/${subjectType}/${encodeURIComponent(subjectId)}/billing`); } + publishEvent>(input: PublishCustomEvent, idempotencyKey: string) { return this.request>("POST", "/events", input, idempotencyKey); } + + private async exchangeToken() { + const body = new URLSearchParams({ grant_type: "client_credentials" }); + if (this.scopes.length) body.set("scope", this.scopes.join(" ")); + const response = await this.fetcher(`${this.baseUrl}/oidc/token`, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + Authorization: `Basic ${btoa(`${this.clientId}:${this.clientSecret}`)}`, + }, + body, + }); + if (!response.ok) throw new Error(`Platform93 client credentials exchange failed with HTTP ${response.status}`); + const payload = await response.json() as { access_token?: string; expires_in?: number }; + if (!payload.access_token) throw new Error("Platform93 token response did not contain an access token"); + this.accessToken = payload.access_token; + this.expiresAt = Date.now() + Math.max(1, payload.expires_in ?? 300) * 1000; + return payload.access_token; + } + + private request(method: string, path: string, body?: unknown, idempotencyKey?: string) { + return this.api.request(method, `/v1/applications/${encodeURIComponent(this.applicationId)}${path}`, body, { idempotencyKey }); + } +} + +export { Platform93Error }; diff --git a/sdk/typescript/server/test/conformance.test.mjs b/sdk/typescript/server/test/conformance.test.mjs index 9d9da58..5ac83fe 100644 --- a/sdk/typescript/server/test/conformance.test.mjs +++ b/sdk/typescript/server/test/conformance.test.mjs @@ -26,7 +26,7 @@ for (const testCase of fixture.cases) { } test("permission matching supports global and namespace wildcards", () => { - assert.equal(hasPermission({ application_id: fixture.application_id, token_kind: "access", actor_type: "user", scope: "*" }, "/applications/app/billing/refund"), true); + assert.equal(hasPermission({ application_id: fixture.application_id, token_kind: "access", actor_type: "user", scope: "*" }, "/applications/app/billing/refund"), false); assert.equal(hasPermission({ application_id: fixture.application_id, token_kind: "access", actor_type: "user", scope: "/applications/app/billing/*" }, "/applications/app/billing/refund"), true); }); @@ -34,11 +34,12 @@ async function fixtureToken(mutation) { const now = Math.floor(Date.now() / 1000); const header = { alg: "RS256", typ: "JWT", kid: "primary" }; const claims = { iss: issuer, sub: "user-1", aud: [fixture.audience], exp: now + 300, iat: now, nbf: now - 1, - application_id: fixture.application_id, token_kind: "access", actor_type: "user", scope: "/applications/app/profile/read" }; + application_id: fixture.application_id, token_kind: "access", actor_type: "user", scope: `/applications/${fixture.application_id}/profile/read`, + roles: { application: ["member"], workspaces: {} } }; let signingKey = primary.privateKey; switch (mutation) { case "machine": claims.token_kind = "machine"; claims.actor_type = "client"; break; - case "delegated": claims.act = { sub: "operator-1", type: "operator" }; break; + case "delegated": claims.act = { sub: "control_user-1", type: "control_user" }; claims.roles = { application: [], workspaces: {} }; break; case "wrong_issuer": claims.iss = "https://wrong.example"; break; case "wrong_audience": claims.aud = ["wrong-api"]; break; case "wrong_application": claims.application_id = "01900000-0000-7000-8000-000000000000"; break; @@ -49,11 +50,21 @@ async function fixtureToken(mutation) { case "missing_application": delete claims.application_id; break; case "missing_token_kind": delete claims.token_kind; break; case "missing_actor_type": delete claims.actor_type; break; - case "operator_actor": claims.actor_type = "operator"; break; + case "missing_roles": delete claims.roles; break; + case "space_injected_scope": claims.scope += ` /applications/${fixture.application_id}/billing/write`; break; + case "tab_injected_scope": claims.scope += `\t/applications/${fixture.application_id}/billing/write`; break; + case "unicode_injected_scope": claims.scope += `\u200b/applications/${fixture.application_id}/billing/write`; break; + case "encoded_space_scope": claims.scope = `/applications/${fixture.application_id}/billing%20write`; break; + case "cross_application_scope": claims.scope = "/applications/01900000-0000-7000-8000-000000000000/billing/read"; break; + case "embedded_wildcard_scope": claims.scope = `/applications/${fixture.application_id}/billing/*/write`; break; + case "duplicate_scope": claims.scope += ` ${claims.scope}`; break; + case "invalid_roles": claims.roles = { application: ["billing admin"], workspaces: {} }; break; + case "delegated_roles": claims.act = { sub: "control_user-1", type: "control_user" }; break; + case "control_user_actor": claims.actor_type = "control_user"; break; case "missing_kid": delete header.kid; break; case "unknown_kid": header.kid = "unknown"; break; case "wrong_signature": signingKey = wrong.privateKey; break; - case "delegated_wrong_actor_type": claims.act = { sub: "operator-1", type: "user" }; break; + case "delegated_wrong_actor_type": claims.act = { sub: "control_user-1", type: "user" }; break; } const token = await new SignJWT(claims).setProtectedHeader(header).sign(signingKey); if (mutation !== "wrong_algorithm") return token; diff --git a/sdk/typescript/server/test/machine.test.mjs b/sdk/typescript/server/test/machine.test.mjs new file mode 100644 index 0000000..e563e73 --- /dev/null +++ b/sdk/typescript/server/test/machine.test.mjs @@ -0,0 +1,24 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { Platform93MachineClient } from "../dist/index.js"; + +test("machine client caches tokens and invalidates after secret rotation", async () => { + let tokenRequests = 0; + const fetch = async (input, init = {}) => { + const url = String(input); + if (url.endsWith("/oidc/token")) { + tokenRequests += 1; + assert.match(String(init.headers.Authorization), /^Basic /); + return Response.json({ access_token: "machine-token", expires_in: 300 }); + } + assert.equal(init.headers.Authorization, "Bearer machine-token"); + return Response.json({ items: [], next_cursor: null }); + }; + const client = new Platform93MachineClient({ baseUrl: "https://platform93.example", applicationId: "app", clientId: "client", clientSecret: "secret", fetch }); + await client.listUsers(); + await client.listUsers(); + assert.equal(tokenRequests, 1); + client.updateSecret("rotated"); + await client.listUsers(); + assert.equal(tokenRequests, 2); +}); diff --git a/web/app/page.tsx b/web/app/page.tsx index b7eb164..2321597 100644 --- a/web/app/page.tsx +++ b/web/app/page.tsx @@ -27,14 +27,16 @@ type OrganizationPolicy = { version: number; }; type ManagementAPIStatus = { enabled: boolean; can_manage: boolean; active_clients: number; token_endpoint: string; api_base: string }; -type OperatorAccount = { +type ControlAuthMethods = { email_code: boolean; magic_link: boolean; password: boolean; providers: string[] }; +type ControlExternalIdentity = { id: string; provider: "google" | "apple"; available: boolean; metadata?: { email?: string }; created_at: string; last_used_at?: string | null }; +type ControlUserAccount = { id: string; email: string; display_name: string; status: string; installation_role: string | null; organizations: { id: string; name: string; role: string }[]; - sign_in_methods: { email_code: boolean; magic_link: boolean; password: boolean; external_identities: unknown[] }; + sign_in_methods: { email_code: boolean; magic_link: boolean; password: boolean; external_identities: ControlExternalIdentity[] }; }; type FreeFormFormat = "text" | "csv" | "json"; type CatalogFeature = { id: string; key: string; name: string; value_type: "boolean" | "quantity" | "free_form"; free_form_format?: FreeFormFormat }; @@ -43,6 +45,7 @@ type TemplateVariableDefinition = { key: string; label: string; description: str type CustomTemplateVariable = { key: string; label: string; type: TemplateVariableDefinition["type"]; sample: string; required: boolean }; type StorageObject = { id: string; owner_type: string; owner_id?: string | null; visibility: "public" | "private"; filename: string; content_type: string; size_bytes: number; status: string; public_url?: string | null; metadata: Record; created_at: string }; type StorageUploadAuthorization = { object: StorageObject; upload_url: string; upload_expires_at: string; required_headers: Record }; +type PermissionGrant = { id: string; subject_type: "user" | "client"; subject_id: string; workspace_id?: string | null; permission: string; canonical_scope: string; status: "active" | "revoked"; version: number }; type AdminIconName = | "open" | "archive" | "restore" | "details" | "refresh" | "replay" | "trash" | "remove" | "revoke" | "disable" | "suspend" | "approve" @@ -59,10 +62,10 @@ type FieldSpec = { }; type CreateSpec = { label: string; fields: FieldSpec[] }; type Resource = { label: string; path: string; create?: CreateSpec }; -const operatorSessionExpiredEvent = "platform93:operator-session-expired"; +const controlUserSessionExpiredEvent = "platform93:control_user-session-expired"; const networkActivityEvent = "platform93:network-activity"; const errorMessagePrefix = "platform93-error:"; -let operatorRefresh: Promise | null = null; +let controlUserRefresh: Promise | null = null; let activeNetworkRequests = 0; function updateNetworkActivity(delta: number) { @@ -75,17 +78,21 @@ function requestPath(input: RequestInfo | URL): string { return new URL(value, typeof location === "undefined" ? "http://localhost" : location.origin).pathname; } -function canRefreshOperatorRequest(path: string): boolean { +function canRefreshControlUserRequest(path: string): boolean { return path.startsWith("/v1/control/") && ![ "/v1/control/auth/email/start", "/v1/control/auth/email/verify", "/v1/control/auth/token/refresh", "/v1/control/auth/logout", - "/v1/control/organization-invitations/accept", + "/v1/control/invitations/accept", + "/v1/control/auth/providers/google/start", + "/v1/control/auth/providers/apple/start", + "/v1/control/invitations/providers/google/start", + "/v1/control/invitations/providers/apple/start", ].includes(path); } -async function refreshOperatorSession(): Promise { +async function refreshControlUserSession(): Promise { const response = await globalThis.fetch("/v1/control/auth/token/refresh", { method: "POST", credentials: "same-origin", @@ -98,13 +105,13 @@ const adminFetch: typeof globalThis.fetch = async (input, init) => { updateNetworkActivity(1); try { const response = await globalThis.fetch(input, init); - if (response.status !== 401 || !canRefreshOperatorRequest(requestPath(input))) return response; + if (response.status !== 401 || !canRefreshControlUserRequest(requestPath(input))) return response; - operatorRefresh ??= refreshOperatorSession().finally(() => { - operatorRefresh = null; + controlUserRefresh ??= refreshControlUserSession().finally(() => { + controlUserRefresh = null; }); - if (!(await operatorRefresh)) { - globalThis.dispatchEvent?.(new Event(operatorSessionExpiredEvent)); + if (!(await controlUserRefresh)) { + globalThis.dispatchEvent?.(new Event(controlUserSessionExpiredEvent)); return response; } return globalThis.fetch(input, init); @@ -121,15 +128,16 @@ const api = new Platform93Client({ type NavigationModule = { label: string; group: string }; const platformModules: NavigationModule[] = [ { label: "Overview", group: "Platform" }, - { label: "Operators", group: "Access" }, + { label: "Platform users", group: "Access" }, { label: "Sessions", group: "Access" }, + { label: "Identity", group: "Configuration" }, { label: "Providers", group: "Configuration" }, { label: "Email", group: "Configuration" }, { label: "Management API", group: "Configuration" }, ]; const organizationModules: NavigationModule[] = [ { label: "Overview", group: "Organization" }, - { label: "Operators", group: "Access" }, + { label: "Platform users", group: "Access" }, { label: "Sessions", group: "Access" }, { label: "Policy", group: "Governance" }, { label: "Providers", group: "Configuration" }, @@ -156,13 +164,14 @@ const resources: Record = { { label: "Users", path: "users", create: { label: "Create user", fields: [{ name: "email", label: "Email", type: "email", required: true }, { name: "first_name", label: "First name" }, { name: "last_name", label: "Last name" }, { name: "locale", label: "Preferred locale", placeholder: "de-CH" }] } }, { label: "Roles", path: "roles", create: { label: "Create role", fields: [{ name: "key", label: "Key", required: true }, { name: "name", label: "Name", required: true }, { name: "scope", label: "Scope", placeholder: "application", required: true }, { name: "permissions", label: "Permissions, comma separated", required: true }] } }, { label: "Role assignments", path: "role-assignments", create: { label: "Assign role", fields: [{ name: "user_id", label: "User ID (choose user or client)" }, { name: "client_id", label: "Client database ID (choose user or client)" }, { name: "role_id", label: "Role ID", required: true }, { name: "workspace_id", label: "Workspace ID (workspace roles only)" }] } }, + { label: "Direct scopes", path: "permission-grants" }, { label: "OAuth consents", path: "oauth-consents" }, { label: "Domains", path: "domains", create: { label: "Add domain", fields: [{ name: "hostname", label: "Hostname", required: true }] } }, - { label: "Clients", path: "clients", create: { label: "Create client", fields: [{ name: "client_id", label: "Client ID", required: true }, { name: "name", label: "Name", required: true }, { name: "client_type", label: "Type", placeholder: "public", required: true }, { name: "redirect_uris", label: "Redirect URIs, comma separated", required: true }, { name: "allowed_grants", label: "Grants, comma separated", placeholder: "authorization_code,refresh_token" }, { name: "allowed_scopes", label: "Scopes, comma separated", placeholder: "openid,profile,email" }] } }, + { label: "OAuth clients", path: "clients", create: { label: "Create OAuth client", fields: [{ name: "client_id", label: "Client ID", required: true }, { name: "name", label: "Name", required: true }, { name: "client_type", label: "Type", placeholder: "public", required: true }, { name: "redirect_uris", label: "Allowed redirect URIs, comma separated (not used by machine clients)" }, { name: "allowed_grants", label: "Grants, comma separated", placeholder: "authorization_code,refresh_token" }, { name: "allowed_scopes", label: "Scopes, comma separated", placeholder: "openid,profile,email" }] } }, ], Workspaces: [ { label: "Workspaces", path: "workspaces", create: { label: "Create workspace", fields: [{ name: "owner_user_id", label: "Owner user ID", required: true }, { name: "key", label: "Key", required: true }, { name: "name", label: "Name", required: true }] } }, - { label: "Invitations", path: "workspace-invitations", create: { label: "Invite member", fields: [{ name: "workspace_id", label: "Workspace ID", required: true }, { name: "email", label: "Email", type: "email", required: true }, { name: "role_keys", label: "Workspace role keys, comma separated", required: true }, { name: "expires_in", label: "Expires in seconds", type: "number", placeholder: "604800" }] } }, + { label: "Invitations", path: "invitations", create: { label: "Create invitation", fields: [{ name: "email", label: "Email", type: "email", required: true }, { name: "workspace_id", label: "Workspace ID (optional)" }, { name: "application_role_keys", label: "Application role keys, comma separated" }, { name: "workspace_role_keys", label: "Workspace role keys, comma separated" }, { name: "expires_in", label: "Expires in seconds", type: "number", placeholder: "604800" }] } }, { label: "Delegations", path: "delegations" }, ], Catalog: [ @@ -175,7 +184,7 @@ const resources: Record = { { label: "Disputes", path: "billing/disputes" }, { label: "Provider events", path: "billing/provider-events" }, { label: "Reconciliation", path: "billing/reconciliation-runs" }, ], - Entitlements: [{ label: "Grants", path: "entitlements", create: { label: "Grant entitlement", fields: [{ name: "subject_type", label: "Subject type", placeholder: "user", required: true }, { name: "subject_id", label: "Subject ID", required: true }, { name: "product_id", label: "Product ID", required: true }, { name: "price_id", label: "Price ID" }, { name: "expires_at", label: "Expires at, RFC3339" }] } }], + Entitlements: [{ label: "Grants", path: "entitlements", create: { label: "Grant entitlement", fields: [{ name: "subject_type", label: "Subject type", placeholder: "user", required: true }, { name: "subject_id", label: "Subject ID", required: true }, { name: "product_id", label: "Product ID", required: true }, { name: "price_id", label: "Price ID" }, { name: "expires_at", label: "Expires at, RFC3339" }, { name: "external_reference", label: "External reference" }] } }], Requests: [{ label: "Local requests", path: "local-entitlement-requests" }], Notifications: [ { label: "Messages", path: "notifications" }, @@ -206,7 +215,7 @@ function NetworkActivity() { function PlatformAdmin() { const [setup, setSetup] = useState(null); - const [operatorEmailLoginAvailable, setOperatorEmailLoginAvailable] = useState(false); + const [controlAuthMethods, setControlAuthMethods] = useState({ email_code: false, magic_link: false, password: true, providers: [] }); const [needsLogin, setNeedsLogin] = useState(false); const [section, setSection] = useState("Overview"); const [organizations, setOrganizations] = useState([]); @@ -222,12 +231,27 @@ function PlatformAdmin() { }); useEffect(() => { api - .request<{ available: boolean; operator_email_login_available: boolean }>("GET", "/v1/setup/status") + .request<{ available: boolean; control_user_email_login_available: boolean; control_auth_methods: ControlAuthMethods }>("GET", "/v1/setup/status") .then((value) => { setSetup(value.available); - setOperatorEmailLoginAvailable(value.operator_email_login_available); + setControlAuthMethods(value.control_auth_methods); if (!value.available) { - if (new URLSearchParams(location.search).get("operator_challenge") === "true") setNeedsLogin(true); + const params = new URLSearchParams(location.search); + const provider = params.get("control_provider"); + const providerError = params.get("error"); + if (provider) { + params.delete("control_provider"); + params.delete("status"); + params.delete("error"); + history.replaceState(null, "", `${location.pathname}${params.size ? `?${params}` : ""}${location.hash}`); + if (providerError) { + setMessage(`${errorMessagePrefix}${titleCase(provider)} sign-in could not be completed (${providerError.replaceAll("_", " ")}).`); + setNeedsLogin(true); + } else { + setMessage(`${titleCase(provider)} authentication completed.`); + void loadOrganizationsRef.current(); + } + } else if (params.get("control_user_challenge") === "true" || params.get("control_invitation") === "true") setNeedsLogin(true); else void loadOrganizationsRef.current(); } }) @@ -235,8 +259,8 @@ function PlatformAdmin() { }, []); useEffect(() => { const requireLogin = () => setNeedsLogin(true); - globalThis.addEventListener?.(operatorSessionExpiredEvent, requireLogin); - return () => globalThis.removeEventListener?.(operatorSessionExpiredEvent, requireLogin); + globalThis.addEventListener?.(controlUserSessionExpiredEvent, requireLogin); + return () => globalThis.removeEventListener?.(controlUserSessionExpiredEvent, requireLogin); }, []); async function loadOrganizations() { try { @@ -297,8 +321,8 @@ function PlatformAdmin() { /> ); if (needsLogin) - return { - setMessage("Operator signed in."); + return { + setMessage("Platform user signed in."); void loadOrganizations(); }} />; const contextValue = application @@ -408,6 +432,7 @@ function PlatformAdmin() {
- {accountOpen && setAccountOpen(false)} onLogout={() => void logout()} onOpenSessions={() => { @@ -438,6 +463,7 @@ function PlatformAdmin() { function Setup({ onComplete }: { onComplete: () => void }) { const [session, setSession] = useState(false); + const [enableEmail, setEnableEmail] = useState(false); const [busy, setBusy] = useState(false); const [message, setMessage] = useState(""); async function submit(event: FormEvent) { @@ -461,7 +487,7 @@ function Setup({ onComplete }: { onComplete: () => void }) { "/v1/setup/notification-providers", smtpInput(form), ); - await api.request("POST", "/v1/setup/complete", {}); + await api.request("POST", "/v1/setup/complete", enableEmail ? {} : { password: form.get("owner_password") }); onComplete(); } } catch (error) { @@ -476,7 +502,7 @@ function Setup({ onComplete }: { onComplete: () => void }) {

FIRST INSTALLATION

Make the platform yours.

- Consume the one-time console credential, establish the first operator, + Consume the one-time console credential, establish the first Platform user, then permanently close setup.

@@ -493,7 +519,7 @@ function Setup({ onComplete }: { onComplete: () => void }) {