@faable/auth-sdk 1.3.13 → 1.3.14

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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  <p align="center">
2
2
  <a href="https://faable.com">
3
- <h1 align="center">Faable Auth SDK Client</h1>
3
+ <h1 align="center">Faable Auth SDK</h1>
4
4
  </a>
5
- <p align="center">Faable Auth management and auth API Client</p>
5
+ <p align="center">Server-side client for the FaableAuth administrative REST API.</p>
6
6
  </p>
7
7
 
8
8
  <p align="center">
@@ -11,54 +11,176 @@
11
11
  </a>
12
12
  </p>
13
13
 
14
- Programmatically perform FaableAuth administrative tasks though our REST API.
14
+ Programmatically manage FaableAuth users, teams, connections and clients through the FaableAuth REST API.
15
15
 
16
- > ⚠️ Use this library in server side only. Otherwise administrative credentials may be exposed.
16
+ > ⚠️ **Server-side only.** This SDK uses administrative credentials. Never ship it to a browser or any untrusted runtime.
17
+
18
+ ---
17
19
 
18
20
  ## Install
19
21
 
20
22
  ```bash
21
- npm install @faable/auth-sdk
23
+ npm install @faable/auth-sdk
22
24
  ```
23
25
 
24
- ## Config
26
+ ## Authentication
27
+
28
+ The SDK accepts any auth strategy from [`@faable/sdk-base`](https://www.npmjs.com/package/@faable/sdk-base). Two strategies are typically used:
29
+
30
+ ### Client credentials (recommended)
31
+
32
+ Reads `FAABLE_CLIENT_ID`, `FAABLE_CLIENT_SECRET` and `FAABLE_DOMAIN` from the environment by default:
25
33
 
26
- ```js
34
+ ```ts
27
35
  import { FaableAuthApi } from "@faable/auth-sdk";
28
36
  import { createClientCredentials } from "@faable/sdk-base";
29
37
 
30
- const auth = createClientCredentials();
38
+ const api = FaableAuthApi.create({
39
+ auth: createClientCredentials(),
40
+ team_id: "team_xxxxxxxxxxxxxxxxxxxxxxxx",
41
+ });
42
+ ```
43
+
44
+ You may also pass credentials explicitly:
45
+
46
+ ```ts
47
+ const auth = createClientCredentials({
48
+ client_id: process.env.FAABLE_CLIENT_ID!,
49
+ client_secret: process.env.FAABLE_CLIENT_SECRET!,
50
+ domain: "faable.auth.faable.link",
51
+ });
52
+ ```
53
+
54
+ ### API key
55
+
56
+ ```ts
57
+ import { FaableAuthApi } from "@faable/auth-sdk";
58
+ import { createApikeyAuth } from "@faable/sdk-base";
31
59
 
32
60
  const api = FaableAuthApi.create({
33
- auth,
34
- team: "<faable_team_id>",
61
+ auth: createApikeyAuth("fak_xxxxxxxxxxxxxxxx"),
62
+ team_id: "team_xxxxxxxxxxxxxxxxxxxxxxxx",
35
63
  });
36
64
  ```
37
65
 
66
+ ### Constructor options
67
+
68
+ | Option | Type | Description |
69
+ | ------------ | -------- | -------------------------------------------------------------------------------------------- |
70
+ | `auth` | strategy | Auth strategy from `@faable/sdk-base`. Required. |
71
+ | `team_id` | string | Scopes calls to a specific team (sent as `x-faable-team` header). |
72
+ | `account_id` | string | Scopes calls to a specific FaableAuth account (sent as `x-faableauth-account` header). |
73
+ | `domain` | string | Override the API host. Defaults to `https://faable.auth.faable.link`. |
74
+ | `debug` | boolean | Enables verbose logging in the underlying fetcher. |
75
+
76
+ ---
77
+
38
78
  ## Usage
39
79
 
40
- Get user:
80
+ ### Users
81
+
82
+ ```ts
83
+ // Get a user
84
+ const user = await api.getUser("user_xxx");
85
+
86
+ // Create a user
87
+ const created = await api.createUser({
88
+ email: "demo@example.com",
89
+ password: "•••••••••",
90
+ });
41
91
 
42
- ```js
43
- const user = await api.getUser("<user_id>");
92
+ // Update a user
93
+ const updated = await api.updateUser("user_xxx", { phone: "+34XXXXXXXXX" });
94
+
95
+ // List users (paginated) — first page of 30
96
+ const firstPage = await api.listUsers().first();
97
+
98
+ // Filter by email
99
+ const matches = await api.listUsers({ email: "demo@example.com" }).first();
100
+
101
+ // Iterate every page
102
+ for await (const page of api.listUsers()) {
103
+ for (const user of page) {
104
+ // ...
105
+ }
106
+ }
44
107
  ```
45
108
 
46
- Update user:
109
+ ### User metadata
47
110
 
48
- ```js
49
- const updated_user = await api.updateUser("<user_id>", {
50
- phone: "+34XXXXXXXXX",
111
+ ```ts
112
+ const metadata = await api.getUserMetadata("user_xxx");
113
+
114
+ await api.setUserMetadata("user_xxx", {
115
+ onboarded: true,
116
+ plan: "pro",
51
117
  });
52
118
  ```
53
119
 
54
- List users:
120
+ ### Teams
121
+
122
+ ```ts
123
+ const team = await api.getTeam("team_xxx");
124
+
125
+ const newTeam = await api.createTeam({ name: "Acme Inc." });
55
126
 
56
- ```js
57
- // Returns first page of latest 30 users
58
- const users = await api.listUsers().first();
127
+ await api.deleteTeam("team_xxx");
128
+
129
+ const myTeams = await api.listTeams({ user_id: "user_xxx" }).first();
59
130
  ```
60
131
 
61
- ```js
62
- // Query users with email=demo@example.com
63
- const users = await api.listUsers({ email: "demo@example.com" }).first();
132
+ ### Team members
133
+
134
+ ```ts
135
+ const members = await api.listTeamMembers({ query: "alice" }).first();
136
+
137
+ const isMember = await api.isUserMemberOfTeam("user_xxx", "team_xxx");
64
138
  ```
139
+
140
+ ### Connections
141
+
142
+ ```ts
143
+ const connections = await api.listConections().first();
144
+ const connection = await api.getConection("conn_xxx");
145
+ ```
146
+
147
+ ### Clients
148
+
149
+ ```ts
150
+ const clients = await api.listClients().first();
151
+ const client = await api.getClient("client_xxx");
152
+ ```
153
+
154
+ ### Current account
155
+
156
+ ```ts
157
+ const account = await api.currentAccount();
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Pagination
163
+
164
+ List methods return a paginator. Use `.first()` to grab the first page or iterate with `for await ... of` to walk all pages:
165
+
166
+ ```ts
167
+ const paginator = api.listUsers();
168
+
169
+ const firstPage = await paginator.first();
170
+
171
+ for await (const page of paginator) {
172
+ // each `page` is an array of items
173
+ }
174
+ ```
175
+
176
+ ## Types
177
+
178
+ All response shapes are generated from the OpenAPI spec and re-exported from the package root:
179
+
180
+ ```ts
181
+ import type { User, Team, TeamMember, Connection, Client } from "@faable/auth-sdk";
182
+ ```
183
+
184
+ ## License
185
+
186
+ MIT
@@ -28,6 +28,7 @@ export declare class FaableAuthApi extends FaableApi {
28
28
  team?: string | null | undefined;
29
29
  notification_settings: {
30
30
  welcome_email_enabled: boolean;
31
+ verify_email_auto_send: boolean;
31
32
  };
32
33
  email_change_verification_mode?: "new_only" | "old_and_new" | undefined;
33
34
  email_oauth_sync_policy?: "preserve_manual" | "always_sync" | undefined;
@@ -47,9 +48,13 @@ export declare class FaableAuthApi extends FaableApi {
47
48
  nickname?: string | null | undefined;
48
49
  email?: string | null | undefined;
49
50
  email_verified: boolean;
51
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
52
+ email_verified_at?: string | null | undefined;
50
53
  email_change_locked_at?: string | null | undefined;
51
54
  phone?: string | null | undefined;
52
55
  phone_verified: boolean;
56
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
57
+ phone_verified_at?: string | null | undefined;
53
58
  country_iso?: string | null | undefined;
54
59
  birth_date?: string | null | undefined;
55
60
  gender?: string | null | undefined;
@@ -92,9 +97,13 @@ export declare class FaableAuthApi extends FaableApi {
92
97
  nickname?: string | null | undefined;
93
98
  email?: string | null | undefined;
94
99
  email_verified: boolean;
100
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
101
+ email_verified_at?: string | null | undefined;
95
102
  email_change_locked_at?: string | null | undefined;
96
103
  phone?: string | null | undefined;
97
104
  phone_verified: boolean;
105
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
106
+ phone_verified_at?: string | null | undefined;
98
107
  country_iso?: string | null | undefined;
99
108
  birth_date?: string | null | undefined;
100
109
  gender?: string | null | undefined;
@@ -140,9 +149,13 @@ export declare class FaableAuthApi extends FaableApi {
140
149
  nickname?: string | null | undefined;
141
150
  email?: string | null | undefined;
142
151
  email_verified: boolean;
152
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
153
+ email_verified_at?: string | null | undefined;
143
154
  email_change_locked_at?: string | null | undefined;
144
155
  phone?: string | null | undefined;
145
156
  phone_verified: boolean;
157
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
158
+ phone_verified_at?: string | null | undefined;
146
159
  country_iso?: string | null | undefined;
147
160
  birth_date?: string | null | undefined;
148
161
  gender?: string | null | undefined;
@@ -186,9 +199,13 @@ export declare class FaableAuthApi extends FaableApi {
186
199
  nickname?: string | null | undefined;
187
200
  email?: string | null | undefined;
188
201
  email_verified: boolean;
202
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
203
+ email_verified_at?: string | null | undefined;
189
204
  email_change_locked_at?: string | null | undefined;
190
205
  phone?: string | null | undefined;
191
206
  phone_verified: boolean;
207
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
208
+ phone_verified_at?: string | null | undefined;
192
209
  country_iso?: string | null | undefined;
193
210
  birth_date?: string | null | undefined;
194
211
  gender?: string | null | undefined;
@@ -231,9 +248,13 @@ export declare class FaableAuthApi extends FaableApi {
231
248
  nickname?: string | null | undefined;
232
249
  email?: string | null | undefined;
233
250
  email_verified: boolean;
251
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
252
+ email_verified_at?: string | null | undefined;
234
253
  email_change_locked_at?: string | null | undefined;
235
254
  phone?: string | null | undefined;
236
255
  phone_verified: boolean;
256
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
257
+ phone_verified_at?: string | null | undefined;
237
258
  country_iso?: string | null | undefined;
238
259
  birth_date?: string | null | undefined;
239
260
  gender?: string | null | undefined;
@@ -276,9 +297,13 @@ export declare class FaableAuthApi extends FaableApi {
276
297
  nickname?: string | null | undefined;
277
298
  email?: string | null | undefined;
278
299
  email_verified: boolean;
300
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
301
+ email_verified_at?: string | null | undefined;
279
302
  email_change_locked_at?: string | null | undefined;
280
303
  phone?: string | null | undefined;
281
304
  phone_verified: boolean;
305
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null | undefined;
306
+ phone_verified_at?: string | null | undefined;
282
307
  country_iso?: string | null | undefined;
283
308
  birth_date?: string | null | undefined;
284
309
  gender?: string | null | undefined;
@@ -447,6 +472,8 @@ export declare class FaableAuthApi extends FaableApi {
447
472
  authorize_params: {
448
473
  [key: string]: string;
449
474
  };
475
+ readonly is_using_default_credentials: boolean;
476
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | undefined;
450
477
  account: string;
451
478
  metadata: {
452
479
  [key: string]: unknown;
@@ -472,6 +499,8 @@ export declare class FaableAuthApi extends FaableApi {
472
499
  authorize_params: {
473
500
  [key: string]: string;
474
501
  };
502
+ readonly is_using_default_credentials: boolean;
503
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | undefined;
475
504
  account: string;
476
505
  metadata: {
477
506
  [key: string]: unknown;
@@ -500,6 +529,8 @@ export declare class FaableAuthApi extends FaableApi {
500
529
  authorize_params: {
501
530
  [key: string]: string;
502
531
  };
532
+ readonly is_using_default_credentials: boolean;
533
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | undefined;
503
534
  account: string;
504
535
  metadata: {
505
536
  [key: string]: unknown;
@@ -526,6 +557,8 @@ export declare class FaableAuthApi extends FaableApi {
526
557
  authorize_params: {
527
558
  [key: string]: string;
528
559
  };
560
+ readonly is_using_default_credentials: boolean;
561
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | undefined;
529
562
  account: string;
530
563
  metadata: {
531
564
  [key: string]: unknown;
@@ -657,6 +690,8 @@ export declare class FaableAuthApi extends FaableApi {
657
690
  authorize_params: {
658
691
  [key: string]: string;
659
692
  };
693
+ readonly is_using_default_credentials: boolean;
694
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | undefined;
660
695
  account: string;
661
696
  metadata: {
662
697
  [key: string]: unknown;
@@ -132,7 +132,11 @@ export interface paths {
132
132
  */
133
133
  get: operations["connection/get"];
134
134
  put?: never;
135
- post?: never;
135
+ /**
136
+ * Update Connections in Account
137
+ * @description Update Connections in Account
138
+ */
139
+ post: operations["connection/update"];
136
140
  /**
137
141
  * Delete Connection in Account
138
142
  * @description Delete Connection in Account
@@ -180,7 +184,11 @@ export interface paths {
180
184
  */
181
185
  get: operations["client/get"];
182
186
  put?: never;
183
- post?: never;
187
+ /**
188
+ * Update Clients in Account
189
+ * @description Update Clients in Account
190
+ */
191
+ post: operations["client/update"];
184
192
  /**
185
193
  * Delete Client in Account
186
194
  * @description Delete Client in Account
@@ -191,6 +199,26 @@ export interface paths {
191
199
  patch?: never;
192
200
  trace?: never;
193
201
  };
202
+ "/client/{client_id}/rotate-secret": {
203
+ parameters: {
204
+ query?: never;
205
+ header?: never;
206
+ path?: never;
207
+ cookie?: never;
208
+ };
209
+ get?: never;
210
+ put?: never;
211
+ /**
212
+ * Rotate a Client's secret
213
+ * @description Generates a fresh `client_secret` for the given Client and persists it. The previous secret is invalidated immediately — there is no grace period. Returns the full Client; the dashboard must surface the new secret to the admin once. Existing client_credentials / authorization_code integrations using the old secret will start failing at the token endpoint immediately after this call.
214
+ */
215
+ post: operations["client/rotateSecret"];
216
+ delete?: never;
217
+ options?: never;
218
+ head?: never;
219
+ patch?: never;
220
+ trace?: never;
221
+ };
194
222
  "/user": {
195
223
  parameters: {
196
224
  query?: never;
@@ -283,6 +311,46 @@ export interface paths {
283
311
  patch?: never;
284
312
  trace?: never;
285
313
  };
314
+ "/user/{user_id}/verify-email/start": {
315
+ parameters: {
316
+ query?: never;
317
+ header?: never;
318
+ path?: never;
319
+ cookie?: never;
320
+ };
321
+ get?: never;
322
+ put?: never;
323
+ /**
324
+ * Start the user's email verification flow
325
+ * @description Initiates the email-verification flow for the given user. Creates a `verify_email` Ticket and queues the verification email. Idempotent — returns `{status:'already_verified'}` without emitting a ticket if the user is already verified. Re-authentication is not required: an active session/Bearer is enough.
326
+ */
327
+ post: operations["user/verifyEmailStart"];
328
+ delete?: never;
329
+ options?: never;
330
+ head?: never;
331
+ patch?: never;
332
+ trace?: never;
333
+ };
334
+ "/verify-email": {
335
+ parameters: {
336
+ query?: never;
337
+ header?: never;
338
+ path?: never;
339
+ cookie?: never;
340
+ };
341
+ /**
342
+ * Verify a verify-email ticket and mark the user verified
343
+ * @description Entry point for the link sent to the user. Consumes the ticket, sets `email_verified=true` with `email_verified_method='verification_flow'`. Redirects to the `redirect_uri` supplied at start with `?status=verified|already_verified` appended; falls back to `/flow/verify-email-done` on the auth host when no `redirect_uri` was given. Invalid/expired tickets redirect to the same fallback with `?status=invalid_link` or `?status=expired`.
344
+ */
345
+ get: operations["user_verify_email_confirm"];
346
+ put?: never;
347
+ post?: never;
348
+ delete?: never;
349
+ options?: never;
350
+ head?: never;
351
+ patch?: never;
352
+ trace?: never;
353
+ };
286
354
  "/identity": {
287
355
  parameters: {
288
356
  query?: never;
@@ -564,7 +632,7 @@ export interface paths {
564
632
  };
565
633
  /**
566
634
  * List Team Members
567
- * @description List all Users that belong to the given Team in the current Account.
635
+ * @description List all Users that belong to the given Team in the current Account. Supports `?expand=user,team,roles` to inline referenced rows.
568
636
  */
569
637
  get: operations["team/listMembers"];
570
638
  put?: never;
@@ -1438,6 +1506,11 @@ export interface components {
1438
1506
  * @default false
1439
1507
  */
1440
1508
  welcome_email_enabled: boolean;
1509
+ /**
1510
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
1511
+ * @default false
1512
+ */
1513
+ verify_email_auto_send: boolean;
1441
1514
  };
1442
1515
  /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
1443
1516
  email_change_verification_mode?: "new_only" | "old_and_new";
@@ -1461,16 +1534,14 @@ export interface components {
1461
1534
  * @default false
1462
1535
  */
1463
1536
  welcome_email_enabled: boolean;
1537
+ /**
1538
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
1539
+ * @default false
1540
+ */
1541
+ verify_email_auto_send: boolean;
1464
1542
  };
1465
1543
  /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
1466
1544
  EmailChangeVerificationMode: "new_only" | "old_and_new";
1467
- /**
1468
- * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
1469
- *
1470
- * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
1471
- * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
1472
- */
1473
- EmailOAuthSyncPolicy: "preserve_manual" | "always_sync";
1474
1545
  /** @description Connection */
1475
1546
  Connection: {
1476
1547
  /** @description Connection ID */
@@ -1506,6 +1577,10 @@ export interface components {
1506
1577
  authorize_params: {
1507
1578
  [key: string]: string;
1508
1579
  };
1580
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
1581
+ readonly is_using_default_credentials: boolean;
1582
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
1583
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
1509
1584
  /** @description Object is related with this account */
1510
1585
  account: string;
1511
1586
  /**
@@ -1549,6 +1624,13 @@ export interface components {
1549
1624
  authorize_params: {
1550
1625
  [key: string]: string;
1551
1626
  };
1627
+ /**
1628
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
1629
+ *
1630
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
1631
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
1632
+ */
1633
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
1552
1634
  /** @description Add Metadata */
1553
1635
  metadata?: {
1554
1636
  [key: string]: unknown;
@@ -1558,6 +1640,29 @@ export interface components {
1558
1640
  ConnectionMetadataCreate: {
1559
1641
  [key: string]: unknown;
1560
1642
  };
1643
+ /** @description Partial update for a Connection. Only the supplied fields are modified. `connection_type` is intentionally excluded — changing it would orphan every identity already linked to this connection. */
1644
+ ConnectionUpdate: {
1645
+ connection_name?: string;
1646
+ enabled?: boolean;
1647
+ enabled_clients?: string[];
1648
+ scope?: string[];
1649
+ client_id?: string;
1650
+ client_secret?: string;
1651
+ issuer?: string;
1652
+ authorize_url?: string;
1653
+ token_url?: string;
1654
+ userinfo_url?: string;
1655
+ jwks_url?: string;
1656
+ response_type?: string;
1657
+ /**
1658
+ * @description Authorize params
1659
+ * @default {}
1660
+ */
1661
+ authorize_params: {
1662
+ [key: string]: string;
1663
+ };
1664
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | null;
1665
+ };
1561
1666
  /** @description Client */
1562
1667
  Client: {
1563
1668
  /** @description Client ID */
@@ -1623,6 +1728,36 @@ export interface components {
1623
1728
  ClientMetadataCreate: {
1624
1729
  [key: string]: unknown;
1625
1730
  };
1731
+ /** @description Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added. */
1732
+ ClientUpdate: {
1733
+ /** @description Human-readable client name shown in consent screens. */
1734
+ name?: string;
1735
+ /** @description Free-form description for internal admin use. */
1736
+ description?: string;
1737
+ /** @description Whitelist of allowed OAuth `redirect_uri` values. */
1738
+ callbacks?: string[];
1739
+ /** @description Whitelist of allowed `post_logout_redirect_uri` values. */
1740
+ logout_urls?: string[];
1741
+ refresh_token?: {
1742
+ /** @enum {unknown} */
1743
+ expiration_mode: "expire" | "not-expire";
1744
+ infinite_token_lifetime: boolean;
1745
+ token_lifetime: number;
1746
+ };
1747
+ client_uri?: string | null;
1748
+ logo_uri?: string | null;
1749
+ tos_uri?: string | null;
1750
+ policy_uri?: string | null;
1751
+ contacts?: string[];
1752
+ grant_types?: string[];
1753
+ response_types?: string[];
1754
+ token_endpoint_auth_method?: string;
1755
+ application_type?: string;
1756
+ software_id?: string | null;
1757
+ software_version?: string | null;
1758
+ frontchannel_logout_uri?: string | null;
1759
+ frontchannel_logout_session_required?: boolean;
1760
+ };
1626
1761
  /** @description User */
1627
1762
  User: {
1628
1763
  /** @description User ID */
@@ -1646,12 +1781,20 @@ export interface components {
1646
1781
  * @default false
1647
1782
  */
1648
1783
  email_verified: boolean;
1784
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
1785
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
1786
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
1787
+ email_verified_at?: string | null;
1649
1788
  /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
1650
1789
  email_change_locked_at?: string | null;
1651
1790
  /** @description contact phone number */
1652
1791
  phone?: string | null;
1653
1792
  /** @description phone is verified */
1654
1793
  phone_verified: boolean;
1794
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
1795
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
1796
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
1797
+ phone_verified_at?: string | null;
1655
1798
  /** @description country iso code */
1656
1799
  country_iso?: string | null;
1657
1800
  /** @description user birth_date */
@@ -1792,12 +1935,16 @@ export interface components {
1792
1935
  given_name?: string;
1793
1936
  /** @description family name */
1794
1937
  family_name?: string;
1795
- /** @description contact email */
1938
+ /** @description Contact email. Changing the email to a new value automatically resets `email_verified` to false (and clears `email_verified_method` / `email_verified_at`) unless the same patch sets `email_verified` explicitly. The override is the documented way to import a pre-verified user from another IdP. */
1796
1939
  email?: string;
1940
+ /** @description Flip the email verification flag. Setting `true` marks the email as verified by the admin (`email_verified_method=manual`). Setting `false` clears the verification metadata. */
1941
+ email_verified?: boolean;
1797
1942
  /** @description New password for this user */
1798
1943
  password?: string;
1799
- /** @description contact phone number */
1944
+ /** @description Contact phone number. Changing it to a new value automatically resets `phone_verified` to false (and clears `phone_verified_method` / `phone_verified_at`) unless the same patch sets `phone_verified` explicitly. */
1800
1945
  phone?: string;
1946
+ /** @description Flip the phone verification flag. Setting `true` marks the phone as verified by the admin (`phone_verified_method=manual`). */
1947
+ phone_verified?: boolean;
1801
1948
  /** @description user country as iso string */
1802
1949
  country_iso?: string;
1803
1950
  /** @description user birth_date */
@@ -2559,6 +2706,17 @@ export interface components {
2559
2706
  message?: string;
2560
2707
  /** @description Type-specific structured payload */
2561
2708
  data?: unknown;
2709
+ user?: components["schemas"]["User"] | string | unknown;
2710
+ client?: components["schemas"]["Client"] | string | unknown;
2711
+ connection?: components["schemas"]["Connection"] | string | unknown;
2712
+ team?: components["schemas"]["Team"] | string | unknown;
2713
+ identity?: components["schemas"]["Identity"] | string | unknown;
2714
+ ticket?: string;
2715
+ /**
2716
+ * Format: date-time
2717
+ * @description When this log row will be auto-deleted by the Mongo TTL monitor. Absent on rows recorded without `ttl_seconds`.
2718
+ */
2719
+ expires_at?: string;
2562
2720
  /** @description Object is related with this account */
2563
2721
  account: string;
2564
2722
  /**
@@ -2714,6 +2872,18 @@ export interface components {
2714
2872
  callback_hostnames?: string[];
2715
2873
  default_connection?: string | null;
2716
2874
  enabled_locales?: string[];
2875
+ notification_settings?: {
2876
+ /**
2877
+ * @description Send the built-in welcome email on user.created
2878
+ * @default false
2879
+ */
2880
+ welcome_email_enabled: boolean;
2881
+ /**
2882
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
2883
+ * @default false
2884
+ */
2885
+ verify_email_auto_send: boolean;
2886
+ };
2717
2887
  };
2718
2888
  OAuthTokenParams: {
2719
2889
  /** @description Grant Type. https://oauth.net/2/grant-types/ */
@@ -2817,6 +2987,11 @@ export interface operations {
2817
2987
  * @default false
2818
2988
  */
2819
2989
  welcome_email_enabled: boolean;
2990
+ /**
2991
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
2992
+ * @default false
2993
+ */
2994
+ verify_email_auto_send: boolean;
2820
2995
  };
2821
2996
  /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
2822
2997
  email_change_verification_mode?: "new_only" | "old_and_new";
@@ -2923,6 +3098,11 @@ export interface operations {
2923
3098
  * @default false
2924
3099
  */
2925
3100
  welcome_email_enabled: boolean;
3101
+ /**
3102
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3103
+ * @default false
3104
+ */
3105
+ verify_email_auto_send: boolean;
2926
3106
  };
2927
3107
  /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
2928
3108
  email_change_verification_mode?: "new_only" | "old_and_new";
@@ -2984,6 +3164,11 @@ export interface operations {
2984
3164
  * @default false
2985
3165
  */
2986
3166
  welcome_email_enabled: boolean;
3167
+ /**
3168
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3169
+ * @default false
3170
+ */
3171
+ verify_email_auto_send: boolean;
2987
3172
  };
2988
3173
  /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
2989
3174
  email_change_verification_mode?: "new_only" | "old_and_new";
@@ -3021,6 +3206,18 @@ export interface operations {
3021
3206
  callback_hostnames?: string[];
3022
3207
  default_connection?: string | null;
3023
3208
  enabled_locales?: string[];
3209
+ notification_settings?: {
3210
+ /**
3211
+ * @description Send the built-in welcome email on user.created
3212
+ * @default false
3213
+ */
3214
+ welcome_email_enabled?: boolean;
3215
+ /**
3216
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3217
+ * @default false
3218
+ */
3219
+ verify_email_auto_send?: boolean;
3220
+ };
3024
3221
  };
3025
3222
  };
3026
3223
  };
@@ -3053,6 +3250,11 @@ export interface operations {
3053
3250
  * @default false
3054
3251
  */
3055
3252
  welcome_email_enabled: boolean;
3253
+ /**
3254
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3255
+ * @default false
3256
+ */
3257
+ verify_email_auto_send: boolean;
3056
3258
  };
3057
3259
  /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
3058
3260
  email_change_verification_mode?: "new_only" | "old_and_new";
@@ -3123,6 +3325,11 @@ export interface operations {
3123
3325
  * @default false
3124
3326
  */
3125
3327
  welcome_email_enabled: boolean;
3328
+ /**
3329
+ * @description Send a verification email automatically when a user is created with `email_verified=false` and an email address. The link in the email lands on `GET /verify-email?ticket=...` and flips `email_verified=true` with `email_verified_method=verification_flow`. When `false`, verification emails must be requested explicitly via `POST /user/:id/verify-email/start`.
3330
+ * @default false
3331
+ */
3332
+ verify_email_auto_send: boolean;
3126
3333
  };
3127
3334
  /** @description Policy for the user email-change flow. `new_only` (default) sends a single confirmation link to the new email. `old_and_new` requires the user to also click a link sent to the previous email before the swap takes effect — stricter, useful for tenants with higher-risk users. */
3128
3335
  email_change_verification_mode?: "new_only" | "old_and_new";
@@ -3153,6 +3360,8 @@ export interface operations {
3153
3360
  pageSize?: number;
3154
3361
  /** @description Filter using a FaableQL query */
3155
3362
  query?: string;
3363
+ /** @description Full-text search across: `connection_name`, `connection_type`. */
3364
+ q?: string;
3156
3365
  };
3157
3366
  header?: never;
3158
3367
  path?: never;
@@ -3207,6 +3416,13 @@ export interface operations {
3207
3416
  authorize_params?: {
3208
3417
  [key: string]: string;
3209
3418
  };
3419
+ /**
3420
+ * @description Controls what happens to `user.email` on subsequent OAuth/federated logins when the user previously changed their email manually through this auth server (i.e. `user.email_change_locked_at` is set).
3421
+ *
3422
+ * - `preserve_manual` (default): the manually-set email wins. The federated provider's email is ignored on re-sync; `email` and `email_verified` are not touched. The identity link stays valid via `provider_user_id`, so the user can still log in with Google/etc.
3423
+ * - `always_sync`: the federated provider's email is always written back, overwriting any manual change. Useful for tenants whose source of truth for identity is the IdP (corporate SSO, etc.).
3424
+ */
3425
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3210
3426
  /** @description Add Metadata */
3211
3427
  metadata?: {
3212
3428
  [key: string]: unknown;
@@ -3255,6 +3471,10 @@ export interface operations {
3255
3471
  authorize_params: {
3256
3472
  [key: string]: string;
3257
3473
  };
3474
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
3475
+ readonly is_using_default_credentials: boolean;
3476
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
3477
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3258
3478
  /** @description Object is related with this account */
3259
3479
  account: string;
3260
3480
  /**
@@ -3324,6 +3544,109 @@ export interface operations {
3324
3544
  authorize_params: {
3325
3545
  [key: string]: string;
3326
3546
  };
3547
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
3548
+ readonly is_using_default_credentials: boolean;
3549
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
3550
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3551
+ /** @description Object is related with this account */
3552
+ account: string;
3553
+ /**
3554
+ * @description ConnectionMetadata
3555
+ * @default {}
3556
+ */
3557
+ metadata: {
3558
+ [key: string]: unknown;
3559
+ };
3560
+ /** @description Connection creation date */
3561
+ createdAt: string;
3562
+ /** @description Connection updated date */
3563
+ updatedAt?: string;
3564
+ };
3565
+ };
3566
+ };
3567
+ };
3568
+ };
3569
+ "connection/update": {
3570
+ parameters: {
3571
+ query?: never;
3572
+ header?: never;
3573
+ path: {
3574
+ connection_id: string;
3575
+ };
3576
+ cookie?: never;
3577
+ };
3578
+ /** @description Partial update for a Connection. Only the supplied fields are modified. `connection_type` is intentionally excluded — changing it would orphan every identity already linked to this connection. */
3579
+ requestBody: {
3580
+ content: {
3581
+ "application/json": {
3582
+ connection_name?: string;
3583
+ enabled?: boolean;
3584
+ enabled_clients?: string[];
3585
+ scope?: string[];
3586
+ client_id?: string;
3587
+ client_secret?: string;
3588
+ issuer?: string;
3589
+ authorize_url?: string;
3590
+ token_url?: string;
3591
+ userinfo_url?: string;
3592
+ jwks_url?: string;
3593
+ response_type?: string;
3594
+ /**
3595
+ * @description Authorize params
3596
+ * @default {}
3597
+ */
3598
+ authorize_params?: {
3599
+ [key: string]: string;
3600
+ };
3601
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync" | null;
3602
+ };
3603
+ };
3604
+ };
3605
+ responses: {
3606
+ /** @description Connection */
3607
+ 200: {
3608
+ headers: {
3609
+ [name: string]: unknown;
3610
+ };
3611
+ content: {
3612
+ "application/json": {
3613
+ /** @description Connection ID */
3614
+ id: string;
3615
+ connection_name: string;
3616
+ /** @enum {unknown} */
3617
+ connection_type: "database" | "custom" | "github" | "figma" | "google_oauth2" | "oidc" | "passwordless_email";
3618
+ /** @default null */
3619
+ authorize_url: string;
3620
+ /** @default null */
3621
+ token_url: string;
3622
+ /** @default null */
3623
+ userinfo_url: string;
3624
+ /** @default null */
3625
+ client_id: string;
3626
+ /** @default null */
3627
+ client_secret: string;
3628
+ /** @default null */
3629
+ issuer: string;
3630
+ /** @default null */
3631
+ jwks_url: string;
3632
+ /** @default null */
3633
+ response_type: string;
3634
+ enabled: boolean;
3635
+ /** @default null */
3636
+ enabled_clients: string[] | null;
3637
+ /** @default [] */
3638
+ scope: string[];
3639
+ /**
3640
+ * @description Authorize params
3641
+ * @default {}
3642
+ */
3643
+ authorize_params: {
3644
+ [key: string]: string;
3645
+ };
3646
+ /** @description Derived: true when the connection_type has shared Faable defaults AND the tenant has not set its own client_id/client_secret. Read-only — set by the server on every read. */
3647
+ readonly is_using_default_credentials: boolean;
3648
+ /** @description Per-connection override of `Account.email_oauth_sync_policy`. When set on a Connection, takes precedence over the Account-level setting for logins through this IdP. When unset (default), the Account-level policy applies. Use this to allow `always_sync` for a trusted IdP (e.g. corporate SSO) while keeping `preserve_manual` for others within the same tenant. */
3649
+ email_oauth_sync_policy?: "preserve_manual" | "always_sync";
3327
3650
  /** @description Object is related with this account */
3328
3651
  account: string;
3329
3652
  /**
@@ -3373,6 +3696,8 @@ export interface operations {
3373
3696
  pageSize?: number;
3374
3697
  /** @description Filter using a FaableQL query */
3375
3698
  query?: string;
3699
+ /** @description Full-text search across: `name`, `description`, `client_id`. */
3700
+ q?: string;
3376
3701
  };
3377
3702
  header?: never;
3378
3703
  path?: never;
@@ -3534,6 +3859,102 @@ export interface operations {
3534
3859
  };
3535
3860
  };
3536
3861
  };
3862
+ "client/update": {
3863
+ parameters: {
3864
+ query?: never;
3865
+ header?: never;
3866
+ path: {
3867
+ client_id: string;
3868
+ };
3869
+ cookie?: never;
3870
+ };
3871
+ /** @description Partial update for a Client. Only the supplied fields are modified. `client_id` and `client_secret` are not editable through this endpoint to prevent accidental rotation; use a dedicated endpoint when secret rotation is added. */
3872
+ requestBody: {
3873
+ content: {
3874
+ "application/json": {
3875
+ /** @description Human-readable client name shown in consent screens. */
3876
+ name?: string;
3877
+ /** @description Free-form description for internal admin use. */
3878
+ description?: string;
3879
+ /** @description Whitelist of allowed OAuth `redirect_uri` values. */
3880
+ callbacks?: string[];
3881
+ /** @description Whitelist of allowed `post_logout_redirect_uri` values. */
3882
+ logout_urls?: string[];
3883
+ refresh_token?: {
3884
+ /** @enum {unknown} */
3885
+ expiration_mode: "expire" | "not-expire";
3886
+ infinite_token_lifetime: boolean;
3887
+ token_lifetime: number;
3888
+ };
3889
+ client_uri?: string | null;
3890
+ logo_uri?: string | null;
3891
+ tos_uri?: string | null;
3892
+ policy_uri?: string | null;
3893
+ contacts?: string[];
3894
+ grant_types?: string[];
3895
+ response_types?: string[];
3896
+ token_endpoint_auth_method?: string;
3897
+ application_type?: string;
3898
+ software_id?: string | null;
3899
+ software_version?: string | null;
3900
+ frontchannel_logout_uri?: string | null;
3901
+ frontchannel_logout_session_required?: boolean;
3902
+ };
3903
+ };
3904
+ };
3905
+ responses: {
3906
+ /** @description Client */
3907
+ 200: {
3908
+ headers: {
3909
+ [name: string]: unknown;
3910
+ };
3911
+ content: {
3912
+ "application/json": {
3913
+ /** @description Client ID */
3914
+ id: string;
3915
+ name: string;
3916
+ description: string;
3917
+ client_id: string;
3918
+ client_secret: string;
3919
+ callbacks: string[];
3920
+ logout_urls: string[];
3921
+ refresh_token: {
3922
+ /** @enum {unknown} */
3923
+ expiration_mode: "expire" | "not-expire";
3924
+ infinite_token_lifetime: boolean;
3925
+ token_lifetime: number;
3926
+ };
3927
+ client_uri?: string | null;
3928
+ logo_uri?: string | null;
3929
+ tos_uri?: string | null;
3930
+ policy_uri?: string | null;
3931
+ contacts?: string[];
3932
+ grant_types?: string[];
3933
+ response_types?: string[];
3934
+ token_endpoint_auth_method?: string;
3935
+ application_type?: string;
3936
+ software_id?: string | null;
3937
+ software_version?: string | null;
3938
+ frontchannel_logout_uri?: string | null;
3939
+ frontchannel_logout_session_required?: boolean;
3940
+ /** @description Object is related with this account */
3941
+ account: string;
3942
+ /**
3943
+ * @description ClientMetadata
3944
+ * @default {}
3945
+ */
3946
+ metadata: {
3947
+ [key: string]: unknown;
3948
+ };
3949
+ /** @description Client creation date */
3950
+ createdAt: string;
3951
+ /** @description Client updated date */
3952
+ updatedAt?: string;
3953
+ };
3954
+ };
3955
+ };
3956
+ };
3957
+ };
3537
3958
  "client/remove": {
3538
3959
  parameters: {
3539
3960
  query?: never;
@@ -3554,6 +3975,69 @@ export interface operations {
3554
3975
  };
3555
3976
  };
3556
3977
  };
3978
+ "client/rotateSecret": {
3979
+ parameters: {
3980
+ query?: never;
3981
+ header?: never;
3982
+ path: {
3983
+ client_id: string;
3984
+ };
3985
+ cookie?: never;
3986
+ };
3987
+ requestBody?: never;
3988
+ responses: {
3989
+ /** @description Client */
3990
+ 200: {
3991
+ headers: {
3992
+ [name: string]: unknown;
3993
+ };
3994
+ content: {
3995
+ "application/json": {
3996
+ /** @description Client ID */
3997
+ id: string;
3998
+ name: string;
3999
+ description: string;
4000
+ client_id: string;
4001
+ client_secret: string;
4002
+ callbacks: string[];
4003
+ logout_urls: string[];
4004
+ refresh_token: {
4005
+ /** @enum {unknown} */
4006
+ expiration_mode: "expire" | "not-expire";
4007
+ infinite_token_lifetime: boolean;
4008
+ token_lifetime: number;
4009
+ };
4010
+ client_uri?: string | null;
4011
+ logo_uri?: string | null;
4012
+ tos_uri?: string | null;
4013
+ policy_uri?: string | null;
4014
+ contacts?: string[];
4015
+ grant_types?: string[];
4016
+ response_types?: string[];
4017
+ token_endpoint_auth_method?: string;
4018
+ application_type?: string;
4019
+ software_id?: string | null;
4020
+ software_version?: string | null;
4021
+ frontchannel_logout_uri?: string | null;
4022
+ frontchannel_logout_session_required?: boolean;
4023
+ /** @description Object is related with this account */
4024
+ account: string;
4025
+ /**
4026
+ * @description ClientMetadata
4027
+ * @default {}
4028
+ */
4029
+ metadata: {
4030
+ [key: string]: unknown;
4031
+ };
4032
+ /** @description Client creation date */
4033
+ createdAt: string;
4034
+ /** @description Client updated date */
4035
+ updatedAt?: string;
4036
+ };
4037
+ };
4038
+ };
4039
+ };
4040
+ };
3557
4041
  "user/list": {
3558
4042
  parameters: {
3559
4043
  query?: {
@@ -3565,6 +4049,8 @@ export interface operations {
3565
4049
  pageSize?: number;
3566
4050
  /** @description Filter using a FaableQL query */
3567
4051
  query?: string;
4052
+ /** @description Full-text search across: `name`, `email`, `phone`. */
4053
+ q?: string;
3568
4054
  };
3569
4055
  header?: never;
3570
4056
  path?: never;
@@ -3657,12 +4143,20 @@ export interface operations {
3657
4143
  * @default false
3658
4144
  */
3659
4145
  email_verified: boolean;
4146
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
4147
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4148
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
4149
+ email_verified_at?: string | null;
3660
4150
  /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
3661
4151
  email_change_locked_at?: string | null;
3662
4152
  /** @description contact phone number */
3663
4153
  phone?: string | null;
3664
4154
  /** @description phone is verified */
3665
4155
  phone_verified: boolean;
4156
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
4157
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4158
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
4159
+ phone_verified_at?: string | null;
3666
4160
  /** @description country iso code */
3667
4161
  country_iso?: string | null;
3668
4162
  /** @description user birth_date */
@@ -3768,12 +4262,20 @@ export interface operations {
3768
4262
  * @default false
3769
4263
  */
3770
4264
  email_verified: boolean;
4265
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
4266
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4267
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
4268
+ email_verified_at?: string | null;
3771
4269
  /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
3772
4270
  email_change_locked_at?: string | null;
3773
4271
  /** @description contact phone number */
3774
4272
  phone?: string | null;
3775
4273
  /** @description phone is verified */
3776
4274
  phone_verified: boolean;
4275
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
4276
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4277
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
4278
+ phone_verified_at?: string | null;
3777
4279
  /** @description country iso code */
3778
4280
  country_iso?: string | null;
3779
4281
  /** @description user birth_date */
@@ -3859,12 +4361,16 @@ export interface operations {
3859
4361
  given_name?: string;
3860
4362
  /** @description family name */
3861
4363
  family_name?: string;
3862
- /** @description contact email */
4364
+ /** @description Contact email. Changing the email to a new value automatically resets `email_verified` to false (and clears `email_verified_method` / `email_verified_at`) unless the same patch sets `email_verified` explicitly. The override is the documented way to import a pre-verified user from another IdP. */
3863
4365
  email?: string;
4366
+ /** @description Flip the email verification flag. Setting `true` marks the email as verified by the admin (`email_verified_method=manual`). Setting `false` clears the verification metadata. */
4367
+ email_verified?: boolean;
3864
4368
  /** @description New password for this user */
3865
4369
  password?: string;
3866
- /** @description contact phone number */
4370
+ /** @description Contact phone number. Changing it to a new value automatically resets `phone_verified` to false (and clears `phone_verified_method` / `phone_verified_at`) unless the same patch sets `phone_verified` explicitly. */
3867
4371
  phone?: string;
4372
+ /** @description Flip the phone verification flag. Setting `true` marks the phone as verified by the admin (`phone_verified_method=manual`). */
4373
+ phone_verified?: boolean;
3868
4374
  /** @description user country as iso string */
3869
4375
  country_iso?: string;
3870
4376
  /** @description user birth_date */
@@ -3913,12 +4419,20 @@ export interface operations {
3913
4419
  * @default false
3914
4420
  */
3915
4421
  email_verified: boolean;
4422
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
4423
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4424
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
4425
+ email_verified_at?: string | null;
3916
4426
  /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
3917
4427
  email_change_locked_at?: string | null;
3918
4428
  /** @description contact phone number */
3919
4429
  phone?: string | null;
3920
4430
  /** @description phone is verified */
3921
4431
  phone_verified: boolean;
4432
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
4433
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
4434
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
4435
+ phone_verified_at?: string | null;
3922
4436
  /** @description country iso code */
3923
4437
  country_iso?: string | null;
3924
4438
  /** @description user birth_date */
@@ -4064,6 +4578,59 @@ export interface operations {
4064
4578
  };
4065
4579
  };
4066
4580
  };
4581
+ "user/verifyEmailStart": {
4582
+ parameters: {
4583
+ query?: never;
4584
+ header?: never;
4585
+ path: {
4586
+ user_id: string;
4587
+ };
4588
+ cookie?: never;
4589
+ };
4590
+ /** @description Optional payload for `POST /user/:user_id/verify-email/start`. Trigger a verification email send for the given user. */
4591
+ requestBody: {
4592
+ content: {
4593
+ "application/json": {
4594
+ /** @description Where to send the user after they click the link. The status of the operation is appended as `?status=verified|already_verified|invalid_link|expired` so the calling app can render the right screen. When omitted, the user lands on the auth host's `/flow/verify-email-done` fallback. */
4595
+ redirect_uri?: string;
4596
+ };
4597
+ };
4598
+ };
4599
+ responses: {
4600
+ /** @description Default Response */
4601
+ 200: {
4602
+ headers: {
4603
+ [name: string]: unknown;
4604
+ };
4605
+ content: {
4606
+ "application/json": {
4607
+ status: "verification_sent" | "already_verified";
4608
+ ticket_id?: string;
4609
+ };
4610
+ };
4611
+ };
4612
+ };
4613
+ };
4614
+ user_verify_email_confirm: {
4615
+ parameters: {
4616
+ query: {
4617
+ ticket: string;
4618
+ };
4619
+ header?: never;
4620
+ path?: never;
4621
+ cookie?: never;
4622
+ };
4623
+ requestBody?: never;
4624
+ responses: {
4625
+ /** @description Default Response */
4626
+ 200: {
4627
+ headers: {
4628
+ [name: string]: unknown;
4629
+ };
4630
+ content?: never;
4631
+ };
4632
+ };
4633
+ };
4067
4634
  "identity/list": {
4068
4635
  parameters: {
4069
4636
  query?: {
@@ -4235,6 +4802,8 @@ export interface operations {
4235
4802
  pageSize?: number;
4236
4803
  /** @description Filter using a FaableQL query */
4237
4804
  query?: string;
4805
+ /** @description Full-text search across: `name`, `description`. */
4806
+ q?: string;
4238
4807
  };
4239
4808
  header?: never;
4240
4809
  path?: never;
@@ -4670,6 +5239,8 @@ export interface operations {
4670
5239
  pageSize?: number;
4671
5240
  /** @description Filter using a FaableQL query */
4672
5241
  query?: string;
5242
+ /** @description Full-text search across: `name`, `slug`. */
5243
+ q?: string;
4673
5244
  };
4674
5245
  header?: never;
4675
5246
  path?: never;
@@ -5073,6 +5644,8 @@ export interface operations {
5073
5644
  next?: string;
5074
5645
  /** @description Size of the results array */
5075
5646
  pageSize?: number;
5647
+ /** @description Expand id-only fields in the response. Accepts repeated params (`expand=user&expand=roles`) or comma-separated (`expand=user,roles`). */
5648
+ expand?: ("user" | "team" | "roles")[];
5076
5649
  };
5077
5650
  header?: never;
5078
5651
  path: {
@@ -5402,6 +5975,8 @@ export interface operations {
5402
5975
  pageSize?: number;
5403
5976
  /** @description Filter using a FaableQL query */
5404
5977
  query?: string;
5978
+ /** @description Full-text search across: `name`, `description`, `identifier`, `slug`. */
5979
+ q?: string;
5405
5980
  };
5406
5981
  header?: never;
5407
5982
  path?: never;
@@ -6316,6 +6891,10 @@ export interface operations {
6316
6891
  pageSize?: number;
6317
6892
  /** @description Filter using a FaableQL query */
6318
6893
  query?: string;
6894
+ /** @description Expand id-only fields in the response. Pass one path per entry (e.g. `?expand=user`). */
6895
+ expand?: ("user" | "client" | "connection" | "team" | "identity")[];
6896
+ /** @description Full-text search across: `message`. */
6897
+ q?: string;
6319
6898
  };
6320
6899
  header?: never;
6321
6900
  path?: never;
@@ -6341,7 +6920,10 @@ export interface operations {
6341
6920
  };
6342
6921
  "log/get": {
6343
6922
  parameters: {
6344
- query?: never;
6923
+ query?: {
6924
+ /** @description Expand id-only fields in the response. Pass one path per entry (e.g. `?expand=user`). */
6925
+ expand?: ("user" | "client" | "connection" | "team" | "identity")[];
6926
+ };
6345
6927
  header?: never;
6346
6928
  path: {
6347
6929
  log_id: string;
@@ -6367,6 +6949,17 @@ export interface operations {
6367
6949
  message?: string;
6368
6950
  /** @description Type-specific structured payload */
6369
6951
  data?: unknown;
6952
+ user?: components["schemas"]["User"] | string | unknown;
6953
+ client?: components["schemas"]["Client"] | string | unknown;
6954
+ connection?: components["schemas"]["Connection"] | string | unknown;
6955
+ team?: components["schemas"]["Team"] | string | unknown;
6956
+ identity?: components["schemas"]["Identity"] | string | unknown;
6957
+ ticket?: string;
6958
+ /**
6959
+ * Format: date-time
6960
+ * @description When this log row will be auto-deleted by the Mongo TTL monitor. Absent on rows recorded without `ttl_seconds`.
6961
+ */
6962
+ expires_at?: string;
6370
6963
  /** @description Object is related with this account */
6371
6964
  account: string;
6372
6965
  /**
@@ -6416,6 +7009,8 @@ export interface operations {
6416
7009
  pageSize?: number;
6417
7010
  /** @description Filter using a FaableQL query */
6418
7011
  query?: string;
7012
+ /** @description Full-text search across: `domain`. */
7013
+ q?: string;
6419
7014
  };
6420
7015
  header?: never;
6421
7016
  path?: never;
@@ -6658,12 +7253,20 @@ export interface operations {
6658
7253
  * @default false
6659
7254
  */
6660
7255
  email_verified: boolean;
7256
+ /** @description How `email_verified` was last set. `manual` — admin flipped the flag via `POST /user/:id`. `verification_flow` — user clicked the verification link. `passwordless_otp` — user completed passwordless OTP login. `team_invite` — user clicked a team invitation link. `email_change` — user confirmed a self-service email change. `federated` — verified by the external IdP on OAuth callback. `null` — the field was cleared (admin un-verified the email). */
7257
+ email_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
7258
+ /** @description ISO 8601 timestamp of when `email_verified` was last flipped to true. */
7259
+ email_verified_at?: string | null;
6661
7260
  /** @description ISO 8601 timestamp of the user's last verified email change. When set, OAuth callbacks will not overwrite `email`/`email_verified` from the federated provider — the manually-chosen email wins. */
6662
7261
  email_change_locked_at?: string | null;
6663
7262
  /** @description contact phone number */
6664
7263
  phone?: string | null;
6665
7264
  /** @description phone is verified */
6666
7265
  phone_verified: boolean;
7266
+ /** @description How `phone_verified` was last set. Same enum as `email_verified_method`. */
7267
+ phone_verified_method?: "manual" | "verification_flow" | "passwordless_otp" | "team_invite" | "email_change" | "federated" | null;
7268
+ /** @description ISO 8601 timestamp of when `phone_verified` was last flipped to true. */
7269
+ phone_verified_at?: string | null;
6667
7270
  /** @description country iso code */
6668
7271
  country_iso?: string | null;
6669
7272
  /** @description user birth_date */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faable/auth-sdk",
3
- "version": "1.3.13",
3
+ "version": "1.3.14",
4
4
  "author": "Marc Pomar <marc@faable.com>",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",