@faable/auth-sdk 2.7.16 → 2.7.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/api-types.d.ts +2 -0
- package/dist/api/generated-client.d.ts +40 -0
- package/dist/api/generated-client.js +22 -0
- package/dist/api/types.d.ts +217 -1
- package/dist/version.js +2 -2
- package/package.json +1 -1
- package/spec/openapi.json +455 -2
package/dist/api/api-types.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { components } from "./types.js";
|
|
2
2
|
export type AccountNotificationSettings = components["schemas"]["AccountNotificationSettings"];
|
|
3
|
+
export type AccountTransferBody = components["schemas"]["AccountTransferBody"];
|
|
4
|
+
export type AccountTransferResponse = components["schemas"]["AccountTransferResponse"];
|
|
3
5
|
export type Action = components["schemas"]["Action"];
|
|
4
6
|
export type ActionCreate = components["schemas"]["ActionCreate"];
|
|
5
7
|
export type ActionMetadata = components["schemas"]["ActionMetadata"];
|
|
@@ -588,6 +588,46 @@ export declare abstract class GeneratedFaableAuthApi extends FaableApi {
|
|
|
588
588
|
latest_checked_at: string | null;
|
|
589
589
|
retention_days: number;
|
|
590
590
|
}>;
|
|
591
|
+
/**
|
|
592
|
+
* `POST /account/{account_id}/transfer` — operationId: `account/transfer`
|
|
593
|
+
*
|
|
594
|
+
* Move an Account to another project
|
|
595
|
+
*
|
|
596
|
+
* Re-parents an Auth Account (tenant) under another Faable project. Only `Account.team` changes: the tenant keeps its id, slug, `*.auth.faable.link` domain, clients and secrets, and end-user logins are unaffected. `dry_run` returns the plan (what rides along + blockers) without writing. Platform credentials only. See arch/auth/tenant-project-transfer.md.
|
|
597
|
+
*
|
|
598
|
+
* @throws {FaableApiError} `invalid_project_id` (400) — The project id is not of the form `project_<hex>` or `team_<hex>`.
|
|
599
|
+
* @throws {FaableApiError} `validation_error` (400) — The body, query or path failed schema validation. `details.issues` lists each failing field.
|
|
600
|
+
* @throws {FaableApiError} `unauthorized` (401) — The request carries no valid credentials.
|
|
601
|
+
* @throws {FaableApiError} `forbidden` (403) — The credentials are valid but do not allow this operation.
|
|
602
|
+
* @throws {FaableApiError} `insufficient_scope` (403) — The token lacks a scope this operation requires. `message` names it.
|
|
603
|
+
* @throws {FaableApiError} `user_suspended` (403) — The user is suspended and cannot sign in or be modified.
|
|
604
|
+
* @throws {FaableApiError} `account_not_found` (404) — No Auth Account matches the request (domain, header or token).
|
|
605
|
+
* @throws {FaableApiError} `account_transfer_refused` (409) — The Auth Account cannot be moved to that project. `details.blockers` lists why.
|
|
606
|
+
* @throws {FaableApiError} `too_many_requests` (429) — Rate limit exceeded. Honour the `Retry-After` header.
|
|
607
|
+
* @throws {FaableApiError} `internal_error` (500) — Unexpected server error. Retry later; the request id is logged.
|
|
608
|
+
*/
|
|
609
|
+
accountTransfer(account_id: string, data: OpBody<"account/transfer">): Promise<{
|
|
610
|
+
moved: boolean;
|
|
611
|
+
account_id: string;
|
|
612
|
+
account_name: string;
|
|
613
|
+
slug: string;
|
|
614
|
+
domain: string;
|
|
615
|
+
from_project: string;
|
|
616
|
+
to_project: string;
|
|
617
|
+
target_tenants_before: {
|
|
618
|
+
id: string;
|
|
619
|
+
name: string;
|
|
620
|
+
}[];
|
|
621
|
+
moves_with_it: {
|
|
622
|
+
[key: string]: number;
|
|
623
|
+
};
|
|
624
|
+
blockers: {
|
|
625
|
+
code: string;
|
|
626
|
+
detail: string;
|
|
627
|
+
}[];
|
|
628
|
+
tenants_left_in_source?: number | undefined;
|
|
629
|
+
tenants_in_target?: number | undefined;
|
|
630
|
+
}>;
|
|
591
631
|
/**
|
|
592
632
|
* `POST /account/{account_id}` — operationId: `account/update`
|
|
593
633
|
*
|
|
@@ -192,6 +192,28 @@ export class GeneratedFaableAuthApi extends FaableApi {
|
|
|
192
192
|
requireId("account_id", account_id);
|
|
193
193
|
return this.fetcher.get(`/sdk-health/${account_id}`);
|
|
194
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* `POST /account/{account_id}/transfer` — operationId: `account/transfer`
|
|
197
|
+
*
|
|
198
|
+
* Move an Account to another project
|
|
199
|
+
*
|
|
200
|
+
* Re-parents an Auth Account (tenant) under another Faable project. Only `Account.team` changes: the tenant keeps its id, slug, `*.auth.faable.link` domain, clients and secrets, and end-user logins are unaffected. `dry_run` returns the plan (what rides along + blockers) without writing. Platform credentials only. See arch/auth/tenant-project-transfer.md.
|
|
201
|
+
*
|
|
202
|
+
* @throws {FaableApiError} `invalid_project_id` (400) — The project id is not of the form `project_<hex>` or `team_<hex>`.
|
|
203
|
+
* @throws {FaableApiError} `validation_error` (400) — The body, query or path failed schema validation. `details.issues` lists each failing field.
|
|
204
|
+
* @throws {FaableApiError} `unauthorized` (401) — The request carries no valid credentials.
|
|
205
|
+
* @throws {FaableApiError} `forbidden` (403) — The credentials are valid but do not allow this operation.
|
|
206
|
+
* @throws {FaableApiError} `insufficient_scope` (403) — The token lacks a scope this operation requires. `message` names it.
|
|
207
|
+
* @throws {FaableApiError} `user_suspended` (403) — The user is suspended and cannot sign in or be modified.
|
|
208
|
+
* @throws {FaableApiError} `account_not_found` (404) — No Auth Account matches the request (domain, header or token).
|
|
209
|
+
* @throws {FaableApiError} `account_transfer_refused` (409) — The Auth Account cannot be moved to that project. `details.blockers` lists why.
|
|
210
|
+
* @throws {FaableApiError} `too_many_requests` (429) — Rate limit exceeded. Honour the `Retry-After` header.
|
|
211
|
+
* @throws {FaableApiError} `internal_error` (500) — Unexpected server error. Retry later; the request id is logged.
|
|
212
|
+
*/
|
|
213
|
+
accountTransfer(account_id, data) {
|
|
214
|
+
requireId("account_id", account_id);
|
|
215
|
+
return this.fetcher.post(`/account/${account_id}/transfer`, data);
|
|
216
|
+
}
|
|
195
217
|
/**
|
|
196
218
|
* `POST /account/{account_id}` — operationId: `account/update`
|
|
197
219
|
*
|
package/dist/api/types.d.ts
CHANGED
|
@@ -204,6 +204,26 @@ export interface paths {
|
|
|
204
204
|
patch?: never;
|
|
205
205
|
trace?: never;
|
|
206
206
|
};
|
|
207
|
+
"/account/{account_id}/transfer": {
|
|
208
|
+
parameters: {
|
|
209
|
+
query?: never;
|
|
210
|
+
header?: never;
|
|
211
|
+
path?: never;
|
|
212
|
+
cookie?: never;
|
|
213
|
+
};
|
|
214
|
+
get?: never;
|
|
215
|
+
put?: never;
|
|
216
|
+
/**
|
|
217
|
+
* Move an Account to another project
|
|
218
|
+
* @description Re-parents an Auth Account (tenant) under another Faable project. Only `Account.team` changes: the tenant keeps its id, slug, `*.auth.faable.link` domain, clients and secrets, and end-user logins are unaffected. `dry_run` returns the plan (what rides along + blockers) without writing. Platform credentials only. See arch/auth/tenant-project-transfer.md.
|
|
219
|
+
*/
|
|
220
|
+
post: operations["account/transfer"];
|
|
221
|
+
delete?: never;
|
|
222
|
+
options?: never;
|
|
223
|
+
head?: never;
|
|
224
|
+
patch?: never;
|
|
225
|
+
trace?: never;
|
|
226
|
+
};
|
|
207
227
|
"/connection": {
|
|
208
228
|
parameters: {
|
|
209
229
|
query?: never;
|
|
@@ -6019,6 +6039,44 @@ export interface components {
|
|
|
6019
6039
|
AuthAccountMetadataCreate: {
|
|
6020
6040
|
[key: string]: unknown;
|
|
6021
6041
|
};
|
|
6042
|
+
AccountTransferBody: {
|
|
6043
|
+
/** @description Destination project (`project_<hex>`) or its team id (`team_<hex>`) — both spellings are accepted. */
|
|
6044
|
+
to_project: string;
|
|
6045
|
+
/** @description Why the tenant is being moved. Recorded in the tenant's log and in ours. */
|
|
6046
|
+
reason: string;
|
|
6047
|
+
/**
|
|
6048
|
+
* @description Return the plan (what rides along + blockers) without writing.
|
|
6049
|
+
* @default false
|
|
6050
|
+
*/
|
|
6051
|
+
dry_run: boolean;
|
|
6052
|
+
/**
|
|
6053
|
+
* @description Move even if the destination ends up above the per-project cap on Auth Accounts.
|
|
6054
|
+
* @default false
|
|
6055
|
+
*/
|
|
6056
|
+
allow_over_cap: boolean;
|
|
6057
|
+
};
|
|
6058
|
+
AccountTransferResponse: {
|
|
6059
|
+
moved: boolean;
|
|
6060
|
+
account_id: string;
|
|
6061
|
+
account_name: string;
|
|
6062
|
+
slug: string;
|
|
6063
|
+
domain: string;
|
|
6064
|
+
from_project: string;
|
|
6065
|
+
to_project: string;
|
|
6066
|
+
target_tenants_before: {
|
|
6067
|
+
id: string;
|
|
6068
|
+
name: string;
|
|
6069
|
+
}[];
|
|
6070
|
+
moves_with_it: {
|
|
6071
|
+
[key: string]: number;
|
|
6072
|
+
};
|
|
6073
|
+
blockers: {
|
|
6074
|
+
code: string;
|
|
6075
|
+
detail: string;
|
|
6076
|
+
}[];
|
|
6077
|
+
tenants_left_in_source?: number;
|
|
6078
|
+
tenants_in_target?: number;
|
|
6079
|
+
};
|
|
6022
6080
|
/** @description AuthAccountUpdate */
|
|
6023
6081
|
AuthAccountUpdate: {
|
|
6024
6082
|
name?: string;
|
|
@@ -6198,6 +6256,8 @@ export interface components {
|
|
|
6198
6256
|
* - `insufficient_scope` (403): The token lacks a scope this operation requires. `message` names it.
|
|
6199
6257
|
* - `team_required` (400): An Auth Account must belong to a project (team).
|
|
6200
6258
|
* - `account_limit_reached` (409): The project already has the maximum number of Auth Accounts.
|
|
6259
|
+
* - `invalid_project_id` (400): The project id is not of the form `project_<hex>` or `team_<hex>`.
|
|
6260
|
+
* - `account_transfer_refused` (409): The Auth Account cannot be moved to that project. `details.blockers` lists why.
|
|
6201
6261
|
* - `plan_required` (402): The setting requires a higher plan. `message` says which.
|
|
6202
6262
|
* - `not_logged_in` (401): There is no signed-in session for this request.
|
|
6203
6263
|
* - `invalid_token` (401): The bearer token is missing, malformed, expired or has no subject.
|
|
@@ -6282,7 +6342,7 @@ export interface components {
|
|
|
6282
6342
|
* - `revision_not_found` (404): The revision is not in the flow history.
|
|
6283
6343
|
* @enum {string}
|
|
6284
6344
|
*/
|
|
6285
|
-
ErrorCode: "bad_request" | "validation_error" | "unauthorized" | "payment_required" | "forbidden" | "not_found" | "method_not_allowed" | "conflict" | "payload_too_large" | "unsupported_media_type" | "unprocessable_entity" | "too_many_requests" | "internal_error" | "already_exists" | "invalid_id" | "account_not_found" | "invalid_query" | "search_not_supported" | "invalid_expand" | "access_denied" | "insufficient_scope" | "team_required" | "account_limit_reached" | "plan_required" | "not_logged_in" | "invalid_token" | "not_owner" | "user_suspended" | "invalid_credentials" | "login_denied" | "signup_denied" | "client_credentials_denied" | "signup_disabled" | "email_taken" | "invalid_email" | "same_email" | "user_has_no_email" | "password_too_weak" | "invalid_code" | "invalid_phone" | "phone_changed" | "phone_already_verified" | "sms_unavailable" | "sms_failed" | "invalid_state" | "state_mismatch" | "invalid_ticket" | "ticket_used" | "ticket_expired" | "ticket_not_found" | "credential_not_found" | "invalid_link" | "expired_link" | "invalid_otp" | "invalid_client" | "client_not_found" | "client_mismatch" | "invalid_client_metadata" | "invalid_connection" | "connection_required" | "connection_misconfigured" | "passwordless_unavailable" | "ambiguous_connection" | "invalid_redirect_uri" | "origin_not_allowed" | "audience_not_found" | "system_resource" | "invalid_request" | "invalid_device_code" | "provider_error" | "identity_already_linked" | "identity_link_denied" | "identity_conflict" | "identity_orphaned" | "no_provider_token" | "no_refresh_token" | "action_unavailable" | "login_flow_misconfigured" | "mfa_required" | "step_up_required" | "interaction_required" | "passkey_login_disabled" | "mfa_pending" | "mfa_invalid_code" | "mfa_invalid_recovery_code" | "too_many_attempts" | "totp_not_allowed" | "no_usable_factor" | "factor_not_found" | "factor_already_confirmed" | "invalid_factor" | "session_missing" | "passkey_verification_failed" | "no_passkey_enrolled" | "malformed_credential" | "unknown_passkey" | "invalid_passkey" | "invite_not_found" | "invite_used" | "already_member" | "not_a_member" | "role_not_found" | "invalid_role" | "flow_not_found" | "revision_not_found";
|
|
6345
|
+
ErrorCode: "bad_request" | "validation_error" | "unauthorized" | "payment_required" | "forbidden" | "not_found" | "method_not_allowed" | "conflict" | "payload_too_large" | "unsupported_media_type" | "unprocessable_entity" | "too_many_requests" | "internal_error" | "already_exists" | "invalid_id" | "account_not_found" | "invalid_query" | "search_not_supported" | "invalid_expand" | "access_denied" | "insufficient_scope" | "team_required" | "account_limit_reached" | "invalid_project_id" | "account_transfer_refused" | "plan_required" | "not_logged_in" | "invalid_token" | "not_owner" | "user_suspended" | "invalid_credentials" | "login_denied" | "signup_denied" | "client_credentials_denied" | "signup_disabled" | "email_taken" | "invalid_email" | "same_email" | "user_has_no_email" | "password_too_weak" | "invalid_code" | "invalid_phone" | "phone_changed" | "phone_already_verified" | "sms_unavailable" | "sms_failed" | "invalid_state" | "state_mismatch" | "invalid_ticket" | "ticket_used" | "ticket_expired" | "ticket_not_found" | "credential_not_found" | "invalid_link" | "expired_link" | "invalid_otp" | "invalid_client" | "client_not_found" | "client_mismatch" | "invalid_client_metadata" | "invalid_connection" | "connection_required" | "connection_misconfigured" | "passwordless_unavailable" | "ambiguous_connection" | "invalid_redirect_uri" | "origin_not_allowed" | "audience_not_found" | "system_resource" | "invalid_request" | "invalid_device_code" | "provider_error" | "identity_already_linked" | "identity_link_denied" | "identity_conflict" | "identity_orphaned" | "no_provider_token" | "no_refresh_token" | "action_unavailable" | "login_flow_misconfigured" | "mfa_required" | "step_up_required" | "interaction_required" | "passkey_login_disabled" | "mfa_pending" | "mfa_invalid_code" | "mfa_invalid_recovery_code" | "too_many_attempts" | "totp_not_allowed" | "no_usable_factor" | "factor_not_found" | "factor_already_confirmed" | "invalid_factor" | "session_missing" | "passkey_verification_failed" | "no_passkey_enrolled" | "malformed_credential" | "unknown_passkey" | "invalid_passkey" | "invite_not_found" | "invite_used" | "already_member" | "not_a_member" | "role_not_found" | "invalid_role" | "flow_not_found" | "revision_not_found";
|
|
6286
6346
|
/** @description Every error response has this shape. Branch on `error_code`, never on `message`: the message is written for a person and may change. */
|
|
6287
6347
|
ErrorResponse: {
|
|
6288
6348
|
/** @description The HTTP status, repeated. */
|
|
@@ -7926,6 +7986,162 @@ export interface operations {
|
|
|
7926
7986
|
};
|
|
7927
7987
|
};
|
|
7928
7988
|
};
|
|
7989
|
+
"account/transfer": {
|
|
7990
|
+
parameters: {
|
|
7991
|
+
query?: never;
|
|
7992
|
+
header?: never;
|
|
7993
|
+
path: {
|
|
7994
|
+
account_id: string;
|
|
7995
|
+
};
|
|
7996
|
+
cookie?: never;
|
|
7997
|
+
};
|
|
7998
|
+
requestBody: {
|
|
7999
|
+
content: {
|
|
8000
|
+
"application/json": {
|
|
8001
|
+
/** @description Destination project (`project_<hex>`) or its team id (`team_<hex>`) — both spellings are accepted. */
|
|
8002
|
+
to_project: string;
|
|
8003
|
+
/** @description Why the tenant is being moved. Recorded in the tenant's log and in ours. */
|
|
8004
|
+
reason: string;
|
|
8005
|
+
/**
|
|
8006
|
+
* @description Return the plan (what rides along + blockers) without writing.
|
|
8007
|
+
* @default false
|
|
8008
|
+
*/
|
|
8009
|
+
dry_run?: boolean;
|
|
8010
|
+
/**
|
|
8011
|
+
* @description Move even if the destination ends up above the per-project cap on Auth Accounts.
|
|
8012
|
+
* @default false
|
|
8013
|
+
*/
|
|
8014
|
+
allow_over_cap?: boolean;
|
|
8015
|
+
};
|
|
8016
|
+
};
|
|
8017
|
+
};
|
|
8018
|
+
responses: {
|
|
8019
|
+
/** @description Default Response */
|
|
8020
|
+
200: {
|
|
8021
|
+
headers: {
|
|
8022
|
+
[name: string]: unknown;
|
|
8023
|
+
};
|
|
8024
|
+
content: {
|
|
8025
|
+
"application/json": {
|
|
8026
|
+
moved: boolean;
|
|
8027
|
+
account_id: string;
|
|
8028
|
+
account_name: string;
|
|
8029
|
+
slug: string;
|
|
8030
|
+
domain: string;
|
|
8031
|
+
from_project: string;
|
|
8032
|
+
to_project: string;
|
|
8033
|
+
target_tenants_before: {
|
|
8034
|
+
id: string;
|
|
8035
|
+
name: string;
|
|
8036
|
+
}[];
|
|
8037
|
+
moves_with_it: {
|
|
8038
|
+
[key: string]: number;
|
|
8039
|
+
};
|
|
8040
|
+
blockers: {
|
|
8041
|
+
code: string;
|
|
8042
|
+
detail: string;
|
|
8043
|
+
}[];
|
|
8044
|
+
tenants_left_in_source?: number;
|
|
8045
|
+
tenants_in_target?: number;
|
|
8046
|
+
};
|
|
8047
|
+
};
|
|
8048
|
+
};
|
|
8049
|
+
/**
|
|
8050
|
+
* @description `invalid_project_id` — The project id is not of the form `project_<hex>` or `team_<hex>`.
|
|
8051
|
+
*
|
|
8052
|
+
* `validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.
|
|
8053
|
+
*/
|
|
8054
|
+
400: {
|
|
8055
|
+
headers: {
|
|
8056
|
+
[name: string]: unknown;
|
|
8057
|
+
};
|
|
8058
|
+
content: {
|
|
8059
|
+
"application/json": components["schemas"]["ErrorResponse"] & {
|
|
8060
|
+
/** @enum {string} */
|
|
8061
|
+
error_code?: "invalid_project_id" | "validation_error";
|
|
8062
|
+
};
|
|
8063
|
+
};
|
|
8064
|
+
};
|
|
8065
|
+
/** @description `unauthorized` — The request carries no valid credentials. */
|
|
8066
|
+
401: {
|
|
8067
|
+
headers: {
|
|
8068
|
+
[name: string]: unknown;
|
|
8069
|
+
};
|
|
8070
|
+
content: {
|
|
8071
|
+
"application/json": components["schemas"]["ErrorResponse"] & {
|
|
8072
|
+
/** @enum {string} */
|
|
8073
|
+
error_code?: "unauthorized";
|
|
8074
|
+
};
|
|
8075
|
+
};
|
|
8076
|
+
};
|
|
8077
|
+
/**
|
|
8078
|
+
* @description `forbidden` — The credentials are valid but do not allow this operation.
|
|
8079
|
+
*
|
|
8080
|
+
* `insufficient_scope` — The token lacks a scope this operation requires. `message` names it.
|
|
8081
|
+
*
|
|
8082
|
+
* `user_suspended` — The user is suspended and cannot sign in or be modified.
|
|
8083
|
+
*/
|
|
8084
|
+
403: {
|
|
8085
|
+
headers: {
|
|
8086
|
+
[name: string]: unknown;
|
|
8087
|
+
};
|
|
8088
|
+
content: {
|
|
8089
|
+
"application/json": components["schemas"]["ErrorResponse"] & {
|
|
8090
|
+
/** @enum {string} */
|
|
8091
|
+
error_code?: "forbidden" | "insufficient_scope" | "user_suspended";
|
|
8092
|
+
};
|
|
8093
|
+
};
|
|
8094
|
+
};
|
|
8095
|
+
/** @description `account_not_found` — No Auth Account matches the request (domain, header or token). */
|
|
8096
|
+
404: {
|
|
8097
|
+
headers: {
|
|
8098
|
+
[name: string]: unknown;
|
|
8099
|
+
};
|
|
8100
|
+
content: {
|
|
8101
|
+
"application/json": components["schemas"]["ErrorResponse"] & {
|
|
8102
|
+
/** @enum {string} */
|
|
8103
|
+
error_code?: "account_not_found";
|
|
8104
|
+
};
|
|
8105
|
+
};
|
|
8106
|
+
};
|
|
8107
|
+
/** @description `account_transfer_refused` — The Auth Account cannot be moved to that project. `details.blockers` lists why. */
|
|
8108
|
+
409: {
|
|
8109
|
+
headers: {
|
|
8110
|
+
[name: string]: unknown;
|
|
8111
|
+
};
|
|
8112
|
+
content: {
|
|
8113
|
+
"application/json": components["schemas"]["ErrorResponse"] & {
|
|
8114
|
+
/** @enum {string} */
|
|
8115
|
+
error_code?: "account_transfer_refused";
|
|
8116
|
+
};
|
|
8117
|
+
};
|
|
8118
|
+
};
|
|
8119
|
+
/** @description `too_many_requests` — Rate limit exceeded. Honour the `Retry-After` header. */
|
|
8120
|
+
429: {
|
|
8121
|
+
headers: {
|
|
8122
|
+
[name: string]: unknown;
|
|
8123
|
+
};
|
|
8124
|
+
content: {
|
|
8125
|
+
"application/json": components["schemas"]["ErrorResponse"] & {
|
|
8126
|
+
/** @enum {string} */
|
|
8127
|
+
error_code?: "too_many_requests";
|
|
8128
|
+
};
|
|
8129
|
+
};
|
|
8130
|
+
};
|
|
8131
|
+
/** @description `internal_error` — Unexpected server error. Retry later; the request id is logged. */
|
|
8132
|
+
500: {
|
|
8133
|
+
headers: {
|
|
8134
|
+
[name: string]: unknown;
|
|
8135
|
+
};
|
|
8136
|
+
content: {
|
|
8137
|
+
"application/json": components["schemas"]["ErrorResponse"] & {
|
|
8138
|
+
/** @enum {string} */
|
|
8139
|
+
error_code?: "internal_error";
|
|
8140
|
+
};
|
|
8141
|
+
};
|
|
8142
|
+
};
|
|
8143
|
+
};
|
|
8144
|
+
};
|
|
7929
8145
|
"connection/list": {
|
|
7930
8146
|
parameters: {
|
|
7931
8147
|
query?: {
|
package/dist/version.js
CHANGED
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
// login pages could not import the SDK at all. Same pattern as auth-js.
|
|
10
10
|
//
|
|
11
11
|
// The sentinels MUST stay byte-identical to the `from` values in `.releaserc`.
|
|
12
|
-
export const version = "2.7.
|
|
12
|
+
export const version = "2.7.17";
|
|
13
13
|
// Short git SHA of the released commit. The version dates a build; this names
|
|
14
14
|
// the exact tree, so a canonical log line or an audit entry leads straight to
|
|
15
15
|
// `git show <sha>`. Deliberately NOT hex: an unreleased build (dev, a local
|
|
16
16
|
// link) cannot be mistaken for a real commit — auth only records values that
|
|
17
17
|
// look like a SHA, and this one never will.
|
|
18
|
-
export const commit = "
|
|
18
|
+
export const commit = "54d90ba";
|
|
19
19
|
// What this SDK writes in `x-faable-client`. Exported for a consumer that
|
|
20
20
|
// builds a strategy on its own (outside `FaableAuthApi`) and still wants the
|
|
21
21
|
// token request attributed — a bare `authClientCredentials` stamps only what
|
package/package.json
CHANGED
package/spec/openapi.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "@faablecloud/auth",
|
|
5
5
|
"description": "Auth Platform made by Faable. Manage Users and Roles",
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.27.0",
|
|
7
7
|
"license": {
|
|
8
8
|
"name": "private",
|
|
9
9
|
"url": "https://faable.com/docs/platform/privacy-policy"
|
|
@@ -6117,6 +6117,122 @@
|
|
|
6117
6117
|
"additionalProperties": true,
|
|
6118
6118
|
"description": "Add Metadata"
|
|
6119
6119
|
},
|
|
6120
|
+
"AccountTransferBody": {
|
|
6121
|
+
"type": "object",
|
|
6122
|
+
"required": [
|
|
6123
|
+
"to_project",
|
|
6124
|
+
"reason"
|
|
6125
|
+
],
|
|
6126
|
+
"properties": {
|
|
6127
|
+
"to_project": {
|
|
6128
|
+
"type": "string",
|
|
6129
|
+
"description": "Destination project (`project_<hex>`) or its team id (`team_<hex>`) — both spellings are accepted."
|
|
6130
|
+
},
|
|
6131
|
+
"reason": {
|
|
6132
|
+
"type": "string",
|
|
6133
|
+
"minLength": 3,
|
|
6134
|
+
"maxLength": 500,
|
|
6135
|
+
"description": "Why the tenant is being moved. Recorded in the tenant's log and in ours."
|
|
6136
|
+
},
|
|
6137
|
+
"dry_run": {
|
|
6138
|
+
"type": "boolean",
|
|
6139
|
+
"default": false,
|
|
6140
|
+
"description": "Return the plan (what rides along + blockers) without writing."
|
|
6141
|
+
},
|
|
6142
|
+
"allow_over_cap": {
|
|
6143
|
+
"type": "boolean",
|
|
6144
|
+
"default": false,
|
|
6145
|
+
"description": "Move even if the destination ends up above the per-project cap on Auth Accounts."
|
|
6146
|
+
}
|
|
6147
|
+
},
|
|
6148
|
+
"additionalProperties": false
|
|
6149
|
+
},
|
|
6150
|
+
"AccountTransferResponse": {
|
|
6151
|
+
"type": "object",
|
|
6152
|
+
"required": [
|
|
6153
|
+
"moved",
|
|
6154
|
+
"account_id",
|
|
6155
|
+
"account_name",
|
|
6156
|
+
"slug",
|
|
6157
|
+
"domain",
|
|
6158
|
+
"from_project",
|
|
6159
|
+
"to_project",
|
|
6160
|
+
"target_tenants_before",
|
|
6161
|
+
"moves_with_it",
|
|
6162
|
+
"blockers"
|
|
6163
|
+
],
|
|
6164
|
+
"properties": {
|
|
6165
|
+
"moved": {
|
|
6166
|
+
"type": "boolean"
|
|
6167
|
+
},
|
|
6168
|
+
"account_id": {
|
|
6169
|
+
"type": "string"
|
|
6170
|
+
},
|
|
6171
|
+
"account_name": {
|
|
6172
|
+
"type": "string"
|
|
6173
|
+
},
|
|
6174
|
+
"slug": {
|
|
6175
|
+
"type": "string"
|
|
6176
|
+
},
|
|
6177
|
+
"domain": {
|
|
6178
|
+
"type": "string"
|
|
6179
|
+
},
|
|
6180
|
+
"from_project": {
|
|
6181
|
+
"type": "string"
|
|
6182
|
+
},
|
|
6183
|
+
"to_project": {
|
|
6184
|
+
"type": "string"
|
|
6185
|
+
},
|
|
6186
|
+
"target_tenants_before": {
|
|
6187
|
+
"type": "array",
|
|
6188
|
+
"items": {
|
|
6189
|
+
"type": "object",
|
|
6190
|
+
"required": [
|
|
6191
|
+
"id",
|
|
6192
|
+
"name"
|
|
6193
|
+
],
|
|
6194
|
+
"properties": {
|
|
6195
|
+
"id": {
|
|
6196
|
+
"type": "string"
|
|
6197
|
+
},
|
|
6198
|
+
"name": {
|
|
6199
|
+
"type": "string"
|
|
6200
|
+
}
|
|
6201
|
+
}
|
|
6202
|
+
}
|
|
6203
|
+
},
|
|
6204
|
+
"moves_with_it": {
|
|
6205
|
+
"type": "object",
|
|
6206
|
+
"additionalProperties": {
|
|
6207
|
+
"type": "number"
|
|
6208
|
+
}
|
|
6209
|
+
},
|
|
6210
|
+
"blockers": {
|
|
6211
|
+
"type": "array",
|
|
6212
|
+
"items": {
|
|
6213
|
+
"type": "object",
|
|
6214
|
+
"required": [
|
|
6215
|
+
"code",
|
|
6216
|
+
"detail"
|
|
6217
|
+
],
|
|
6218
|
+
"properties": {
|
|
6219
|
+
"code": {
|
|
6220
|
+
"type": "string"
|
|
6221
|
+
},
|
|
6222
|
+
"detail": {
|
|
6223
|
+
"type": "string"
|
|
6224
|
+
}
|
|
6225
|
+
}
|
|
6226
|
+
}
|
|
6227
|
+
},
|
|
6228
|
+
"tenants_left_in_source": {
|
|
6229
|
+
"type": "number"
|
|
6230
|
+
},
|
|
6231
|
+
"tenants_in_target": {
|
|
6232
|
+
"type": "number"
|
|
6233
|
+
}
|
|
6234
|
+
}
|
|
6235
|
+
},
|
|
6120
6236
|
"AuthAccountUpdate": {
|
|
6121
6237
|
"type": "object",
|
|
6122
6238
|
"properties": {
|
|
@@ -6820,7 +6936,7 @@
|
|
|
6820
6936
|
},
|
|
6821
6937
|
"ErrorCode": {
|
|
6822
6938
|
"type": "string",
|
|
6823
|
-
"description": "Machine-readable error code. One HTTP status per code.\n\n- `bad_request` (400): The request is malformed. `message` says what is wrong.\n- `validation_error` (400): The body, query or path failed schema validation. `details.issues` lists each failing field.\n- `unauthorized` (401): The request carries no valid credentials.\n- `payment_required` (402): The feature is not included in the current plan.\n- `forbidden` (403): The credentials are valid but do not allow this operation.\n- `not_found` (404): The resource does not exist in this account.\n- `method_not_allowed` (405): The HTTP method is not supported on this path.\n- `conflict` (409): The request conflicts with the current state of the resource.\n- `payload_too_large` (413): The request body exceeds the size limit.\n- `unsupported_media_type` (415): The `Content-Type` is not accepted by this endpoint.\n- `unprocessable_entity` (422): The request is well-formed but cannot be processed.\n- `too_many_requests` (429): Rate limit exceeded. Honour the `Retry-After` header.\n- `internal_error` (500): Unexpected server error. Retry later; the request id is logged.\n- `already_exists` (400): A resource with the same unique field already exists (for a user, usually `email`). `details.fields` names the field.\n- `invalid_id` (400): The id in the path is not a valid id for this resource.\n- `account_not_found` (404): No Auth Account matches the request (domain, header or token).\n- `invalid_query` (400): The `?query=` FaableQL expression could not be parsed.\n- `search_not_supported` (400): This resource does not support `?search=`.\n- `invalid_expand` (400): An `?expand=` path is not allowed on this resource.\n- `access_denied` (401): The caller may not access this row (ownership or machine-to-machine restriction).\n- `insufficient_scope` (403): The token lacks a scope this operation requires. `message` names it.\n- `team_required` (400): An Auth Account must belong to a project (team).\n- `account_limit_reached` (409): The project already has the maximum number of Auth Accounts.\n- `plan_required` (402): The setting requires a higher plan. `message` says which.\n- `not_logged_in` (401): There is no signed-in session for this request.\n- `invalid_token` (401): The bearer token is missing, malformed, expired or has no subject.\n- `not_owner` (403): The caller may only perform this operation on their own user.\n- `user_suspended` (403): The user is suspended and cannot sign in or be modified.\n- `invalid_credentials` (400): The email/username or password is incorrect.\n- `login_denied` (401): A post-login Action denied the sign-in. `message` carries the reason it gave. On token grants it is a 403 with `error: invalid_grant`.\n- `signup_denied` (403): A pre-signup Action or an active block denied the sign-up. `message` carries the reason.\n- `client_credentials_denied` (401): An Action denied the client_credentials grant. `message` carries the reason.\n- `signup_disabled` (403): Self-service sign-up is disabled on this connection.\n- `email_taken` (409): Another user in this account already uses that email.\n- `invalid_email` (400): The email address is not valid.\n- `same_email` (400): The new email is the same as the current one.\n- `user_has_no_email` (400): The operation needs an email but the user has none.\n- `password_too_weak` (400): The password does not meet the connection policy. `message` lists each unmet rule.\n- `invalid_code` (400): The verification code is wrong, expired or already used.\n- `invalid_phone` (400): The phone number is not E.164 and could not be resolved with the account default country. Include the country code.\n- `phone_changed` (400): The phone on the user changed after the code was sent. Start again.\n- `phone_already_verified` (409): The user already has a verified phone; the number cannot be swapped from the screen.\n- `sms_unavailable` (409): This account cannot send SMS right now. The suffix says why: `sms_unavailable:plan`, `:quota`, `:provider`.\n- `sms_failed` (409): The SMS provider rejected the message.\n- `invalid_state` (400): The `state` is missing, expired, or does not describe a resumable step.\n- `state_mismatch` (401): The `state` belongs to another account, session, client or ceremony.\n- `invalid_ticket` (400): The ticket does not exist or is not the kind this endpoint accepts.\n- `ticket_used` (400): The ticket was already consumed.\n- `ticket_expired` (400): The ticket is past its expiry.\n- `ticket_not_found` (404): No ticket with that id belongs to this user.\n- `credential_not_found` (404): The user has no password credential on this connection.\n- `invalid_link` (400): The magic link is malformed.\n- `expired_link` (400): The magic link token was not found or has expired.\n- `invalid_otp` (401): The one-time password is wrong or expired.\n- `invalid_client` (400): The `client_id` in the request does not name a client of this account.\n- `client_not_found` (404): No client with that `client_id`.\n- `client_mismatch` (401): The client belongs to a different account.\n- `invalid_client_metadata` (400): Dynamic client registration rejected a field (RFC 7591). `message` names it.\n- `invalid_connection` (400): The connection does not exist, is disabled, or is not of the type this flow needs.\n- `connection_required` (400): No connection was given and the client has no `default_connection`.\n- `connection_misconfigured` (400): The connection is missing settings needed to talk to its provider.\n- `passwordless_unavailable` (400): No passwordless connection is configured or enabled for this client.\n- `ambiguous_connection` (400): Several connections match; pass `connection_id`.\n- `invalid_redirect_uri` (400): The redirect URI is not registered for the client.\n- `origin_not_allowed` (403): The request `Origin` is not in the client's Allowed Web Origins.\n- `audience_not_found` (403): The `audience` does not name an API registered in this account.\n- `system_resource` (403): The resource is managed by Faable and cannot be modified or deleted.\n- `invalid_request` (400): A required OAuth parameter is missing or two of them are incompatible. `message` says which.\n- `invalid_device_code` (400): The device or user code is invalid or expired.\n- `provider_error` (400): The upstream identity provider returned an error. The suffix is the provider’s own code, when it sent one: `provider_error:bad_refresh_token` (the user must re-authorize), `provider_error:incorrect_client_credentials` (our configuration, the user can do nothing). `details.provider_error_description` carries the provider’s sentence.\n- `identity_already_linked` (409): That external identity is already linked to another user.\n- `identity_link_denied` (409): That external identity cannot be linked to this user.\n- `identity_conflict` (409): The user already has a linked identity for this connection.\n- `identity_orphaned` (400): The identity pointed at a user that no longer exists; it was removed. Sign in again.\n- `no_provider_token` (400): The identity holds no provider access token.\n- `no_refresh_token` (400): The identity holds no provider refresh token, so it cannot be refreshed.\n- `action_unavailable` (401): The Action that paused this login is disabled or belongs elsewhere.\n- `login_flow_misconfigured` (500): The login flow of this account cannot run. `message` carries the node error.\n- `mfa_required` (403): The login needs a second factor that this flow cannot collect, or one is still pending on the session.\n- `step_up_required` (403): Confirm an existing factor before changing your factors.\n- `interaction_required` (403): An Action asked for a redirect on a non-interactive flow.\n- `passkey_login_disabled` (400): Sign in with a passkey is not enabled for this client.\n- `mfa_pending` (401): A second-factor challenge is pending; answer it before continuing.\n- `mfa_invalid_code` (401): The authenticator code did not verify.\n- `mfa_invalid_recovery_code` (401): The recovery code did not verify.\n- `too_many_attempts` (429): Too many wrong codes. Wait a few minutes and try again.\n- `totp_not_allowed` (401): This account does not accept authenticator apps.\n- `no_usable_factor` (400): The user has no confirmed second factor to challenge.\n- `factor_not_found` (400): No factor with that id belongs to this user.\n- `factor_already_confirmed` (400): The factor was already confirmed.\n- `invalid_factor` (400): The factor cannot be verified (no secret material).\n- `session_missing` (401): The session that started this login no longer exists.\n- `passkey_verification_failed` (400): The WebAuthn response could not be verified.\n- `no_passkey_enrolled` (400): The user has no passkey to sign in with.\n- `malformed_credential` (400): The WebAuthn credential is malformed.\n- `unknown_passkey` (401): The passkey is not enrolled for this user.\n- `invalid_passkey` (401): The passkey assertion did not verify.\n- `invite_not_found` (404): No invite with that id in this account.\n- `invite_used` (400): The invite was already accepted.\n- `already_member` (400): The user is already a member of the team.\n- `not_a_member` (404): The user is not a member of the team.\n- `role_not_found` (404): No role with that id in this account.\n- `invalid_role` (400): The role belongs to another account.\n- `flow_not_found` (400): The login flow does not exist in this account.\n- `revision_not_found` (404): The revision is not in the flow history.",
|
|
6939
|
+
"description": "Machine-readable error code. One HTTP status per code.\n\n- `bad_request` (400): The request is malformed. `message` says what is wrong.\n- `validation_error` (400): The body, query or path failed schema validation. `details.issues` lists each failing field.\n- `unauthorized` (401): The request carries no valid credentials.\n- `payment_required` (402): The feature is not included in the current plan.\n- `forbidden` (403): The credentials are valid but do not allow this operation.\n- `not_found` (404): The resource does not exist in this account.\n- `method_not_allowed` (405): The HTTP method is not supported on this path.\n- `conflict` (409): The request conflicts with the current state of the resource.\n- `payload_too_large` (413): The request body exceeds the size limit.\n- `unsupported_media_type` (415): The `Content-Type` is not accepted by this endpoint.\n- `unprocessable_entity` (422): The request is well-formed but cannot be processed.\n- `too_many_requests` (429): Rate limit exceeded. Honour the `Retry-After` header.\n- `internal_error` (500): Unexpected server error. Retry later; the request id is logged.\n- `already_exists` (400): A resource with the same unique field already exists (for a user, usually `email`). `details.fields` names the field.\n- `invalid_id` (400): The id in the path is not a valid id for this resource.\n- `account_not_found` (404): No Auth Account matches the request (domain, header or token).\n- `invalid_query` (400): The `?query=` FaableQL expression could not be parsed.\n- `search_not_supported` (400): This resource does not support `?search=`.\n- `invalid_expand` (400): An `?expand=` path is not allowed on this resource.\n- `access_denied` (401): The caller may not access this row (ownership or machine-to-machine restriction).\n- `insufficient_scope` (403): The token lacks a scope this operation requires. `message` names it.\n- `team_required` (400): An Auth Account must belong to a project (team).\n- `account_limit_reached` (409): The project already has the maximum number of Auth Accounts.\n- `invalid_project_id` (400): The project id is not of the form `project_<hex>` or `team_<hex>`.\n- `account_transfer_refused` (409): The Auth Account cannot be moved to that project. `details.blockers` lists why.\n- `plan_required` (402): The setting requires a higher plan. `message` says which.\n- `not_logged_in` (401): There is no signed-in session for this request.\n- `invalid_token` (401): The bearer token is missing, malformed, expired or has no subject.\n- `not_owner` (403): The caller may only perform this operation on their own user.\n- `user_suspended` (403): The user is suspended and cannot sign in or be modified.\n- `invalid_credentials` (400): The email/username or password is incorrect.\n- `login_denied` (401): A post-login Action denied the sign-in. `message` carries the reason it gave. On token grants it is a 403 with `error: invalid_grant`.\n- `signup_denied` (403): A pre-signup Action or an active block denied the sign-up. `message` carries the reason.\n- `client_credentials_denied` (401): An Action denied the client_credentials grant. `message` carries the reason.\n- `signup_disabled` (403): Self-service sign-up is disabled on this connection.\n- `email_taken` (409): Another user in this account already uses that email.\n- `invalid_email` (400): The email address is not valid.\n- `same_email` (400): The new email is the same as the current one.\n- `user_has_no_email` (400): The operation needs an email but the user has none.\n- `password_too_weak` (400): The password does not meet the connection policy. `message` lists each unmet rule.\n- `invalid_code` (400): The verification code is wrong, expired or already used.\n- `invalid_phone` (400): The phone number is not E.164 and could not be resolved with the account default country. Include the country code.\n- `phone_changed` (400): The phone on the user changed after the code was sent. Start again.\n- `phone_already_verified` (409): The user already has a verified phone; the number cannot be swapped from the screen.\n- `sms_unavailable` (409): This account cannot send SMS right now. The suffix says why: `sms_unavailable:plan`, `:quota`, `:provider`.\n- `sms_failed` (409): The SMS provider rejected the message.\n- `invalid_state` (400): The `state` is missing, expired, or does not describe a resumable step.\n- `state_mismatch` (401): The `state` belongs to another account, session, client or ceremony.\n- `invalid_ticket` (400): The ticket does not exist or is not the kind this endpoint accepts.\n- `ticket_used` (400): The ticket was already consumed.\n- `ticket_expired` (400): The ticket is past its expiry.\n- `ticket_not_found` (404): No ticket with that id belongs to this user.\n- `credential_not_found` (404): The user has no password credential on this connection.\n- `invalid_link` (400): The magic link is malformed.\n- `expired_link` (400): The magic link token was not found or has expired.\n- `invalid_otp` (401): The one-time password is wrong or expired.\n- `invalid_client` (400): The `client_id` in the request does not name a client of this account.\n- `client_not_found` (404): No client with that `client_id`.\n- `client_mismatch` (401): The client belongs to a different account.\n- `invalid_client_metadata` (400): Dynamic client registration rejected a field (RFC 7591). `message` names it.\n- `invalid_connection` (400): The connection does not exist, is disabled, or is not of the type this flow needs.\n- `connection_required` (400): No connection was given and the client has no `default_connection`.\n- `connection_misconfigured` (400): The connection is missing settings needed to talk to its provider.\n- `passwordless_unavailable` (400): No passwordless connection is configured or enabled for this client.\n- `ambiguous_connection` (400): Several connections match; pass `connection_id`.\n- `invalid_redirect_uri` (400): The redirect URI is not registered for the client.\n- `origin_not_allowed` (403): The request `Origin` is not in the client's Allowed Web Origins.\n- `audience_not_found` (403): The `audience` does not name an API registered in this account.\n- `system_resource` (403): The resource is managed by Faable and cannot be modified or deleted.\n- `invalid_request` (400): A required OAuth parameter is missing or two of them are incompatible. `message` says which.\n- `invalid_device_code` (400): The device or user code is invalid or expired.\n- `provider_error` (400): The upstream identity provider returned an error. The suffix is the provider’s own code, when it sent one: `provider_error:bad_refresh_token` (the user must re-authorize), `provider_error:incorrect_client_credentials` (our configuration, the user can do nothing). `details.provider_error_description` carries the provider’s sentence.\n- `identity_already_linked` (409): That external identity is already linked to another user.\n- `identity_link_denied` (409): That external identity cannot be linked to this user.\n- `identity_conflict` (409): The user already has a linked identity for this connection.\n- `identity_orphaned` (400): The identity pointed at a user that no longer exists; it was removed. Sign in again.\n- `no_provider_token` (400): The identity holds no provider access token.\n- `no_refresh_token` (400): The identity holds no provider refresh token, so it cannot be refreshed.\n- `action_unavailable` (401): The Action that paused this login is disabled or belongs elsewhere.\n- `login_flow_misconfigured` (500): The login flow of this account cannot run. `message` carries the node error.\n- `mfa_required` (403): The login needs a second factor that this flow cannot collect, or one is still pending on the session.\n- `step_up_required` (403): Confirm an existing factor before changing your factors.\n- `interaction_required` (403): An Action asked for a redirect on a non-interactive flow.\n- `passkey_login_disabled` (400): Sign in with a passkey is not enabled for this client.\n- `mfa_pending` (401): A second-factor challenge is pending; answer it before continuing.\n- `mfa_invalid_code` (401): The authenticator code did not verify.\n- `mfa_invalid_recovery_code` (401): The recovery code did not verify.\n- `too_many_attempts` (429): Too many wrong codes. Wait a few minutes and try again.\n- `totp_not_allowed` (401): This account does not accept authenticator apps.\n- `no_usable_factor` (400): The user has no confirmed second factor to challenge.\n- `factor_not_found` (400): No factor with that id belongs to this user.\n- `factor_already_confirmed` (400): The factor was already confirmed.\n- `invalid_factor` (400): The factor cannot be verified (no secret material).\n- `session_missing` (401): The session that started this login no longer exists.\n- `passkey_verification_failed` (400): The WebAuthn response could not be verified.\n- `no_passkey_enrolled` (400): The user has no passkey to sign in with.\n- `malformed_credential` (400): The WebAuthn credential is malformed.\n- `unknown_passkey` (401): The passkey is not enrolled for this user.\n- `invalid_passkey` (401): The passkey assertion did not verify.\n- `invite_not_found` (404): No invite with that id in this account.\n- `invite_used` (400): The invite was already accepted.\n- `already_member` (400): The user is already a member of the team.\n- `not_a_member` (404): The user is not a member of the team.\n- `role_not_found` (404): No role with that id in this account.\n- `invalid_role` (400): The role belongs to another account.\n- `flow_not_found` (400): The login flow does not exist in this account.\n- `revision_not_found` (404): The revision is not in the flow history.",
|
|
6824
6940
|
"enum": [
|
|
6825
6941
|
"bad_request",
|
|
6826
6942
|
"validation_error",
|
|
@@ -6845,6 +6961,8 @@
|
|
|
6845
6961
|
"insufficient_scope",
|
|
6846
6962
|
"team_required",
|
|
6847
6963
|
"account_limit_reached",
|
|
6964
|
+
"invalid_project_id",
|
|
6965
|
+
"account_transfer_refused",
|
|
6848
6966
|
"plan_required",
|
|
6849
6967
|
"not_logged_in",
|
|
6850
6968
|
"invalid_token",
|
|
@@ -11826,6 +11944,341 @@
|
|
|
11826
11944
|
}
|
|
11827
11945
|
}
|
|
11828
11946
|
},
|
|
11947
|
+
"/account/{account_id}/transfer": {
|
|
11948
|
+
"post": {
|
|
11949
|
+
"operationId": "account/transfer",
|
|
11950
|
+
"summary": "Move an Account to another project",
|
|
11951
|
+
"tags": [
|
|
11952
|
+
"account"
|
|
11953
|
+
],
|
|
11954
|
+
"description": "Re-parents an Auth Account (tenant) under another Faable project. Only `Account.team` changes: the tenant keeps its id, slug, `*.auth.faable.link` domain, clients and secrets, and end-user logins are unaffected. `dry_run` returns the plan (what rides along + blockers) without writing. Platform credentials only. See arch/auth/tenant-project-transfer.md.",
|
|
11955
|
+
"requestBody": {
|
|
11956
|
+
"required": true,
|
|
11957
|
+
"content": {
|
|
11958
|
+
"application/json": {
|
|
11959
|
+
"schema": {
|
|
11960
|
+
"type": "object",
|
|
11961
|
+
"required": [
|
|
11962
|
+
"to_project",
|
|
11963
|
+
"reason"
|
|
11964
|
+
],
|
|
11965
|
+
"properties": {
|
|
11966
|
+
"to_project": {
|
|
11967
|
+
"type": "string",
|
|
11968
|
+
"description": "Destination project (`project_<hex>`) or its team id (`team_<hex>`) — both spellings are accepted."
|
|
11969
|
+
},
|
|
11970
|
+
"reason": {
|
|
11971
|
+
"type": "string",
|
|
11972
|
+
"minLength": 3,
|
|
11973
|
+
"maxLength": 500,
|
|
11974
|
+
"description": "Why the tenant is being moved. Recorded in the tenant's log and in ours."
|
|
11975
|
+
},
|
|
11976
|
+
"dry_run": {
|
|
11977
|
+
"type": "boolean",
|
|
11978
|
+
"default": false,
|
|
11979
|
+
"description": "Return the plan (what rides along + blockers) without writing."
|
|
11980
|
+
},
|
|
11981
|
+
"allow_over_cap": {
|
|
11982
|
+
"type": "boolean",
|
|
11983
|
+
"default": false,
|
|
11984
|
+
"description": "Move even if the destination ends up above the per-project cap on Auth Accounts."
|
|
11985
|
+
}
|
|
11986
|
+
},
|
|
11987
|
+
"additionalProperties": false
|
|
11988
|
+
}
|
|
11989
|
+
}
|
|
11990
|
+
}
|
|
11991
|
+
},
|
|
11992
|
+
"parameters": [
|
|
11993
|
+
{
|
|
11994
|
+
"schema": {
|
|
11995
|
+
"type": "string"
|
|
11996
|
+
},
|
|
11997
|
+
"in": "path",
|
|
11998
|
+
"name": "account_id",
|
|
11999
|
+
"required": true
|
|
12000
|
+
}
|
|
12001
|
+
],
|
|
12002
|
+
"security": [
|
|
12003
|
+
{
|
|
12004
|
+
"bearerAuth": []
|
|
12005
|
+
}
|
|
12006
|
+
],
|
|
12007
|
+
"responses": {
|
|
12008
|
+
"200": {
|
|
12009
|
+
"description": "Default Response",
|
|
12010
|
+
"content": {
|
|
12011
|
+
"application/json": {
|
|
12012
|
+
"schema": {
|
|
12013
|
+
"type": "object",
|
|
12014
|
+
"required": [
|
|
12015
|
+
"moved",
|
|
12016
|
+
"account_id",
|
|
12017
|
+
"account_name",
|
|
12018
|
+
"slug",
|
|
12019
|
+
"domain",
|
|
12020
|
+
"from_project",
|
|
12021
|
+
"to_project",
|
|
12022
|
+
"target_tenants_before",
|
|
12023
|
+
"moves_with_it",
|
|
12024
|
+
"blockers"
|
|
12025
|
+
],
|
|
12026
|
+
"properties": {
|
|
12027
|
+
"moved": {
|
|
12028
|
+
"type": "boolean"
|
|
12029
|
+
},
|
|
12030
|
+
"account_id": {
|
|
12031
|
+
"type": "string"
|
|
12032
|
+
},
|
|
12033
|
+
"account_name": {
|
|
12034
|
+
"type": "string"
|
|
12035
|
+
},
|
|
12036
|
+
"slug": {
|
|
12037
|
+
"type": "string"
|
|
12038
|
+
},
|
|
12039
|
+
"domain": {
|
|
12040
|
+
"type": "string"
|
|
12041
|
+
},
|
|
12042
|
+
"from_project": {
|
|
12043
|
+
"type": "string"
|
|
12044
|
+
},
|
|
12045
|
+
"to_project": {
|
|
12046
|
+
"type": "string"
|
|
12047
|
+
},
|
|
12048
|
+
"target_tenants_before": {
|
|
12049
|
+
"type": "array",
|
|
12050
|
+
"items": {
|
|
12051
|
+
"type": "object",
|
|
12052
|
+
"required": [
|
|
12053
|
+
"id",
|
|
12054
|
+
"name"
|
|
12055
|
+
],
|
|
12056
|
+
"properties": {
|
|
12057
|
+
"id": {
|
|
12058
|
+
"type": "string"
|
|
12059
|
+
},
|
|
12060
|
+
"name": {
|
|
12061
|
+
"type": "string"
|
|
12062
|
+
}
|
|
12063
|
+
}
|
|
12064
|
+
}
|
|
12065
|
+
},
|
|
12066
|
+
"moves_with_it": {
|
|
12067
|
+
"type": "object",
|
|
12068
|
+
"additionalProperties": {
|
|
12069
|
+
"type": "number"
|
|
12070
|
+
}
|
|
12071
|
+
},
|
|
12072
|
+
"blockers": {
|
|
12073
|
+
"type": "array",
|
|
12074
|
+
"items": {
|
|
12075
|
+
"type": "object",
|
|
12076
|
+
"required": [
|
|
12077
|
+
"code",
|
|
12078
|
+
"detail"
|
|
12079
|
+
],
|
|
12080
|
+
"properties": {
|
|
12081
|
+
"code": {
|
|
12082
|
+
"type": "string"
|
|
12083
|
+
},
|
|
12084
|
+
"detail": {
|
|
12085
|
+
"type": "string"
|
|
12086
|
+
}
|
|
12087
|
+
}
|
|
12088
|
+
}
|
|
12089
|
+
},
|
|
12090
|
+
"tenants_left_in_source": {
|
|
12091
|
+
"type": "number"
|
|
12092
|
+
},
|
|
12093
|
+
"tenants_in_target": {
|
|
12094
|
+
"type": "number"
|
|
12095
|
+
}
|
|
12096
|
+
}
|
|
12097
|
+
}
|
|
12098
|
+
}
|
|
12099
|
+
}
|
|
12100
|
+
},
|
|
12101
|
+
"400": {
|
|
12102
|
+
"description": "`invalid_project_id` — The project id is not of the form `project_<hex>` or `team_<hex>`.\n\n`validation_error` — The body, query or path failed schema validation. `details.issues` lists each failing field.",
|
|
12103
|
+
"content": {
|
|
12104
|
+
"application/json": {
|
|
12105
|
+
"schema": {
|
|
12106
|
+
"allOf": [
|
|
12107
|
+
{
|
|
12108
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
12109
|
+
},
|
|
12110
|
+
{
|
|
12111
|
+
"type": "object",
|
|
12112
|
+
"properties": {
|
|
12113
|
+
"error_code": {
|
|
12114
|
+
"type": "string",
|
|
12115
|
+
"enum": [
|
|
12116
|
+
"invalid_project_id",
|
|
12117
|
+
"validation_error"
|
|
12118
|
+
]
|
|
12119
|
+
}
|
|
12120
|
+
}
|
|
12121
|
+
}
|
|
12122
|
+
]
|
|
12123
|
+
}
|
|
12124
|
+
}
|
|
12125
|
+
}
|
|
12126
|
+
},
|
|
12127
|
+
"401": {
|
|
12128
|
+
"description": "`unauthorized` — The request carries no valid credentials.",
|
|
12129
|
+
"content": {
|
|
12130
|
+
"application/json": {
|
|
12131
|
+
"schema": {
|
|
12132
|
+
"allOf": [
|
|
12133
|
+
{
|
|
12134
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
12135
|
+
},
|
|
12136
|
+
{
|
|
12137
|
+
"type": "object",
|
|
12138
|
+
"properties": {
|
|
12139
|
+
"error_code": {
|
|
12140
|
+
"type": "string",
|
|
12141
|
+
"enum": [
|
|
12142
|
+
"unauthorized"
|
|
12143
|
+
]
|
|
12144
|
+
}
|
|
12145
|
+
}
|
|
12146
|
+
}
|
|
12147
|
+
]
|
|
12148
|
+
}
|
|
12149
|
+
}
|
|
12150
|
+
}
|
|
12151
|
+
},
|
|
12152
|
+
"403": {
|
|
12153
|
+
"description": "`forbidden` — The credentials are valid but do not allow this operation.\n\n`insufficient_scope` — The token lacks a scope this operation requires. `message` names it.\n\n`user_suspended` — The user is suspended and cannot sign in or be modified.",
|
|
12154
|
+
"content": {
|
|
12155
|
+
"application/json": {
|
|
12156
|
+
"schema": {
|
|
12157
|
+
"allOf": [
|
|
12158
|
+
{
|
|
12159
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
12160
|
+
},
|
|
12161
|
+
{
|
|
12162
|
+
"type": "object",
|
|
12163
|
+
"properties": {
|
|
12164
|
+
"error_code": {
|
|
12165
|
+
"type": "string",
|
|
12166
|
+
"enum": [
|
|
12167
|
+
"forbidden",
|
|
12168
|
+
"insufficient_scope",
|
|
12169
|
+
"user_suspended"
|
|
12170
|
+
]
|
|
12171
|
+
}
|
|
12172
|
+
}
|
|
12173
|
+
}
|
|
12174
|
+
]
|
|
12175
|
+
}
|
|
12176
|
+
}
|
|
12177
|
+
}
|
|
12178
|
+
},
|
|
12179
|
+
"404": {
|
|
12180
|
+
"description": "`account_not_found` — No Auth Account matches the request (domain, header or token).",
|
|
12181
|
+
"content": {
|
|
12182
|
+
"application/json": {
|
|
12183
|
+
"schema": {
|
|
12184
|
+
"allOf": [
|
|
12185
|
+
{
|
|
12186
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
12187
|
+
},
|
|
12188
|
+
{
|
|
12189
|
+
"type": "object",
|
|
12190
|
+
"properties": {
|
|
12191
|
+
"error_code": {
|
|
12192
|
+
"type": "string",
|
|
12193
|
+
"enum": [
|
|
12194
|
+
"account_not_found"
|
|
12195
|
+
]
|
|
12196
|
+
}
|
|
12197
|
+
}
|
|
12198
|
+
}
|
|
12199
|
+
]
|
|
12200
|
+
}
|
|
12201
|
+
}
|
|
12202
|
+
}
|
|
12203
|
+
},
|
|
12204
|
+
"409": {
|
|
12205
|
+
"description": "`account_transfer_refused` — The Auth Account cannot be moved to that project. `details.blockers` lists why.",
|
|
12206
|
+
"content": {
|
|
12207
|
+
"application/json": {
|
|
12208
|
+
"schema": {
|
|
12209
|
+
"allOf": [
|
|
12210
|
+
{
|
|
12211
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
12212
|
+
},
|
|
12213
|
+
{
|
|
12214
|
+
"type": "object",
|
|
12215
|
+
"properties": {
|
|
12216
|
+
"error_code": {
|
|
12217
|
+
"type": "string",
|
|
12218
|
+
"enum": [
|
|
12219
|
+
"account_transfer_refused"
|
|
12220
|
+
]
|
|
12221
|
+
}
|
|
12222
|
+
}
|
|
12223
|
+
}
|
|
12224
|
+
]
|
|
12225
|
+
}
|
|
12226
|
+
}
|
|
12227
|
+
}
|
|
12228
|
+
},
|
|
12229
|
+
"429": {
|
|
12230
|
+
"description": "`too_many_requests` — Rate limit exceeded. Honour the `Retry-After` header.",
|
|
12231
|
+
"content": {
|
|
12232
|
+
"application/json": {
|
|
12233
|
+
"schema": {
|
|
12234
|
+
"allOf": [
|
|
12235
|
+
{
|
|
12236
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
12237
|
+
},
|
|
12238
|
+
{
|
|
12239
|
+
"type": "object",
|
|
12240
|
+
"properties": {
|
|
12241
|
+
"error_code": {
|
|
12242
|
+
"type": "string",
|
|
12243
|
+
"enum": [
|
|
12244
|
+
"too_many_requests"
|
|
12245
|
+
]
|
|
12246
|
+
}
|
|
12247
|
+
}
|
|
12248
|
+
}
|
|
12249
|
+
]
|
|
12250
|
+
}
|
|
12251
|
+
}
|
|
12252
|
+
}
|
|
12253
|
+
},
|
|
12254
|
+
"500": {
|
|
12255
|
+
"description": "`internal_error` — Unexpected server error. Retry later; the request id is logged.",
|
|
12256
|
+
"content": {
|
|
12257
|
+
"application/json": {
|
|
12258
|
+
"schema": {
|
|
12259
|
+
"allOf": [
|
|
12260
|
+
{
|
|
12261
|
+
"$ref": "#/components/schemas/ErrorResponse"
|
|
12262
|
+
},
|
|
12263
|
+
{
|
|
12264
|
+
"type": "object",
|
|
12265
|
+
"properties": {
|
|
12266
|
+
"error_code": {
|
|
12267
|
+
"type": "string",
|
|
12268
|
+
"enum": [
|
|
12269
|
+
"internal_error"
|
|
12270
|
+
]
|
|
12271
|
+
}
|
|
12272
|
+
}
|
|
12273
|
+
}
|
|
12274
|
+
]
|
|
12275
|
+
}
|
|
12276
|
+
}
|
|
12277
|
+
}
|
|
12278
|
+
}
|
|
12279
|
+
}
|
|
12280
|
+
}
|
|
12281
|
+
},
|
|
11829
12282
|
"/connection": {
|
|
11830
12283
|
"get": {
|
|
11831
12284
|
"operationId": "connection/list",
|