@foir/sdk 0.24.0 → 0.25.0

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/CHANGELOG.md CHANGED
@@ -108,6 +108,50 @@ nobody asking for `@foir/sdk` gets it early. The push that carries the commit to
108
108
 
109
109
  Changes on `dev` that have not been published to npm.
110
110
 
111
+ ## [0.25.0] — 2026-10-18
112
+
113
+ ### Changed
114
+
115
+ - **`deleteMyAccount` for an account with no password needs a recent sign-in**
116
+ (`@foir/sdk/auth`). `confirm` alone used to be enough. Now it's refused
117
+ unless the user signed in within the last ten minutes, so a stolen session
118
+ can't delete an account. Migration: when it's refused, send the user through
119
+ sign-in again, then call it once more.
120
+
121
+ ### Added
122
+
123
+ - **`organizations.pool`, `organizations.startPool` and `organizations.dropPool`**
124
+ (`@foir/sdk/app`). In an operation, read which pool the people of the
125
+ organisation the run acts in sign in to, start its own pool, or drop it.
126
+ Reading needs `organizations:read`, and the other two `organizations:write`.
127
+ Starting one is refused while anybody of the pool it signs in to now stands
128
+ in it or beneath it, and dropping one while it holds anybody; each refusal
129
+ says how many. Each answers an `AppOrganizationPool`.
130
+ - **`AppOrganizationPool`** (`@foir/sdk/app`, type).
131
+ - **`organizations.provision` makes its first member by address**
132
+ (`@foir/sdk/app`): `firstMember: { email, firstName?, lastName? }`, made in
133
+ the pool that serves the new organisation (its own with `ownPool`). It also
134
+ needs `users:create`.
135
+ - **`leaveMembership`** (`@foir/sdk/auth`). The signed-in person ends their own
136
+ membership where the request stands: the organisation `orgId` names, or the
137
+ project's own. It asks no permission. It's refused where it would leave an
138
+ organisation with nobody who can staff it, or leave them nowhere to sign in,
139
+ since a project's people sign in only where they stand.
140
+ - **`myAddresses`, `addMyAddress`, `proveMyAddress`, `makeMyAddressPrimary`
141
+ and `removeMyAddress`** (`@foir/sdk/auth`), and the **`MyAddress`** type. A
142
+ signed-in person adds an email address to their own account. It's kept only
143
+ once the code it was sent proves it. Adding one asks for their current
144
+ password, or, for an account with none, a sign-in in the last ten minutes.
145
+ An address another account in the project holds isn't added. The address
146
+ the account uses moves only to a proven one, and it can't be removed.
147
+ - **`exportMyData`** (`@foir/sdk/auth`), and the **`MyDataExport`** type. A
148
+ signed-in person takes a copy of their own data: their account, and
149
+ everything deleting it would erase (the records and files they own). It
150
+ holds no password, code or token value.
151
+ - **`renameFactor`** (`@foir/sdk/auth`). A signed-in person renames one of
152
+ their own security keys or passkeys. A name proves nothing, so it asks for
153
+ no step-up.
154
+
111
155
  ## [0.24.0] — 2026-10-18
112
156
 
113
157
  ### Changed
@@ -222,20 +222,42 @@ export interface AppOrganizationProvision {
222
222
  data: Record<string, unknown>;
223
223
  };
224
224
  /**
225
- * The user who becomes its first member. They are given the role the
226
- * project names for an organisation's founder, in its settings: the
227
- * operation chooses who, and the project decides what they hold.
225
+ * Who becomes its first member: a user the project has, by `userId`, or
226
+ * somebody the provision makes by `email` in the pool that serves the new
227
+ * organisation, which is its own with `ownPool`. That is how an organisation
228
+ * that signs its own people in gets its first person; making one also needs
229
+ * `users:create`. They are given the role the project names for an
230
+ * organisation's founder, in its settings: the operation chooses who, and
231
+ * the project decides what they hold.
228
232
  */
229
233
  firstMember?: {
230
234
  userId: string;
235
+ } | {
236
+ email: string;
237
+ firstName?: string;
238
+ lastName?: string;
231
239
  };
232
240
  /**
233
241
  * The organisation signs its own people in, to a pool of its own, apart
234
242
  * from its parent's and the project's. Its descendants share that pool
235
- * unless one of them starts another. Chosen now, when it is made.
243
+ * unless one of them starts another. One that exists already starts one
244
+ * with `organizations.startPool`.
236
245
  */
237
246
  ownPool?: boolean;
238
247
  }
248
+ /**
249
+ * The pool an organisation's people sign in to, and where it comes from: its
250
+ * own, the nearest organisation above it that started one, or the project's.
251
+ */
252
+ export interface AppOrganizationPool {
253
+ organizationId: string;
254
+ poolId: string;
255
+ source: 'OWN' | 'ANCESTOR' | 'PROJECT';
256
+ /** The organisation whose own pool it is. Null for the project's. */
257
+ sourceOrganizationId: string | null;
258
+ /** How many people the pool holds, when it is the organisation's own. Null for any other. */
259
+ people: number | null;
260
+ }
239
261
  /**
240
262
  * Who a consent change is for: a user whose id the app holds, or an
241
263
  * address.
@@ -556,6 +578,32 @@ export interface AppClient {
556
578
  name: string;
557
579
  }[];
558
580
  }>;
581
+ /**
582
+ * Which pool the people of the organisation this run acts in sign in to.
583
+ * Needs `organizations:read`. Like every call here it takes no
584
+ * organisation: the run acts in the one whoever triggered it stands in.
585
+ */
586
+ pool(): Promise<AppOrganizationPool>;
587
+ /**
588
+ * Start the own pool of the organisation this run acts in, which it and
589
+ * everything beneath it sign their people in to. Needs
590
+ * `organizations:write`. Refused while
591
+ * anybody of the pool it signs in to now holds a membership in it or
592
+ * beneath it, or an invitation there is open to that pool, and the
593
+ * refusal says how many: nobody is moved between pools, so those
594
+ * memberships are removed first and those people sign up again in the
595
+ * new pool. Its apps, and those beneath it, then sign their people in
596
+ * there, and anybody signed in through them is signed out. Safe to run
597
+ * again: it answers the pool it has.
598
+ */
599
+ startPool(): Promise<AppOrganizationPool>;
600
+ /**
601
+ * Drop the own pool of the organisation this run acts in, so it signs its
602
+ * people in to the pool above it. Needs `organizations:write`. Refused
603
+ * while the pool holds anybody or an invitation is open to it: dropping a
604
+ * pool deletes nobody.
605
+ */
606
+ dropPool(): Promise<AppOrganizationPool>;
559
607
  };
560
608
  notifications: {
561
609
  /** Tell a user something. Needs `notifications:write.named`. */
@@ -21,7 +21,7 @@
21
21
  * The manifest's own messages are on `@foir/sdk/app/contract`.
22
22
  */
23
23
  export { createAppClient } from './client';
24
- export type { AppBinding, AppClient, AppClientConfig, AppConsentChange, AppConsentSubject, AppUser, AppUserEraseResult, AppUserList, AppUserSaveResult, AppFieldMapping, AppInstallConfig, AppNotification, AppOperationStart, AppOrganizationProvision, AppRecord, AppRecordList, AppStartedOperation, AppStatusReport, AppSyncDirection, AppUpsertResult, AppWhoami, } from './client';
24
+ export type { AppBinding, AppClient, AppClientConfig, AppConsentChange, AppConsentSubject, AppUser, AppUserEraseResult, AppUserList, AppUserSaveResult, AppFieldMapping, AppInstallConfig, AppNotification, AppOperationStart, AppOrganizationPool, AppOrganizationProvision, AppRecord, AppRecordList, AppStartedOperation, AppStatusReport, AppSyncDirection, AppUpsertResult, AppWhoami, } from './client';
25
25
  export { appUserEmailUnavailableOf, appUserUnlinkedOf, appLookupConflictOf, isAppFieldWithheld } from './errors';
26
26
  export type { AppUserEmailUnavailableReason, AppLookupConflict } from './errors';
27
27
  export { appModelFieldName, appModelTypeName, appSelectorEnumValue } from './naming';
package/dist/app.js CHANGED
@@ -352,6 +352,20 @@ function createAppClient(config) {
352
352
  const refuse = (message) => {
353
353
  throw new FoirRequestError(`[foir] ${message}`);
354
354
  };
355
+ const POOL_FIELDS = "organizationId poolId source sourceOrganizationId people";
356
+ async function poolOf(name, document) {
357
+ const answer = await field(name, document, {});
358
+ if (!answer?.poolId || !answer.organizationId || answer.source !== "OWN" && answer.source !== "ANCESTOR" && answer.source !== "PROJECT") {
359
+ return refuse(`${name} reported no error and answered no pool`);
360
+ }
361
+ return {
362
+ organizationId: answer.organizationId,
363
+ poolId: answer.poolId,
364
+ source: answer.source,
365
+ sourceOrganizationId: answer.sourceOrganizationId ?? null,
366
+ people: answer.people ?? null
367
+ };
368
+ }
355
369
  let surface;
356
370
  function served() {
357
371
  surface ??= withFoirRetry(async () => {
@@ -825,9 +839,20 @@ function createAppClient(config) {
825
839
  if (settings.modelKey.trim() === "") return refuse("an organisation's settings name the model they are a record of");
826
840
  input.settings = { modelKey: settings.modelKey.trim(), data: settings.data };
827
841
  }
828
- if (organization.firstMember !== void 0) {
829
- if (organization.firstMember.userId === "") return refuse("a first member names a user");
830
- input.firstMember = { userId: organization.firstMember.userId };
842
+ const first = organization.firstMember;
843
+ if (first !== void 0) {
844
+ if ("email" in first) {
845
+ const email = first.email.trim();
846
+ if (email === "") return refuse("a first member made by address names the address");
847
+ input.firstMember = {
848
+ email,
849
+ ...first.firstName !== void 0 ? { firstName: first.firstName } : {},
850
+ ...first.lastName !== void 0 ? { lastName: first.lastName } : {}
851
+ };
852
+ } else {
853
+ if (first.userId === "") return refuse("a first member names a user");
854
+ input.firstMember = { userId: first.userId };
855
+ }
831
856
  }
832
857
  if (organization.ownPool === true) input.ownPool = true;
833
858
  const answered = settings === void 0 ? "organizationId status" : "organizationId settingsRecordId status";
@@ -853,6 +878,15 @@ function createAppClient(config) {
853
878
  deletionScheduledAt: answer.deletionScheduledAt ?? null,
854
879
  organizations: (answer.organizations ?? []).map((o) => ({ id: o.id, name: o.name }))
855
880
  };
881
+ },
882
+ async pool() {
883
+ return poolOf("organizationPool", `query AppOrganizationPool { organizationPool { ${POOL_FIELDS} } }`);
884
+ },
885
+ async startPool() {
886
+ return poolOf("startOrganizationPool", `mutation AppStartOrganizationPool { startOrganizationPool { ${POOL_FIELDS} } }`);
887
+ },
888
+ async dropPool() {
889
+ return poolOf("dropOrganizationPool", `mutation AppDropOrganizationPool { dropOrganizationPool { ${POOL_FIELDS} } }`);
856
890
  }
857
891
  },
858
892
  notifications: {
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import { type FoirEnv } from '../graphql/foir-request';
19
19
  import { type AuthOpName, type AuthOpOptions } from './ops';
20
- import { type AuthConfig, type AuthProviderPublic, type CurrentUser, type AuthResult, type DefaultAuthProvider, type AuthorizedApp, type DeleteAccountResult, type MyOrganization, type MyProfile, type MyProfileChange, type MySession, type MyFactor, type StepUp, type FactorEnrollment, type MySignInMethod, type NewPersonalAccessToken, type ProviderCallbackInput, type ProviderLoginInput, type ProviderLoginResult, type ProviderOTPVerifyInput, type ProviderToken, type SignupContext } from './operations';
20
+ import { type AuthConfig, type AuthProviderPublic, type CurrentUser, type AuthResult, type DefaultAuthProvider, type AuthorizedApp, type DeleteAccountResult, type MyOrganization, type MyProfile, type MyProfileChange, type MySession, type MyAddress, type MyDataExport, type MyFactor, type StepUp, type FactorEnrollment, type MySignInMethod, type NewPersonalAccessToken, type ProviderCallbackInput, type ProviderLoginInput, type ProviderLoginResult, type ProviderOTPVerifyInput, type ProviderToken, type SignupContext } from './operations';
21
21
  import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
22
22
  /** An access token + its rotating refresh token. */
23
23
  export interface FoirAuthTokens {
@@ -191,14 +191,26 @@ export declare function myProviderToken(env: FoirEnv, providerKey: string, optio
191
191
  export declare function logout(env: FoirEnv, options?: AuthOpOptions): Promise<boolean>;
192
192
  /**
193
193
  * Delete the calling user's account and their owned records and files.
194
- * Irreversible. `password` is required for password accounts and omitted for
195
- * provider-only ones; the server enforces the actual re-auth gate and fails
196
- * closed, so omitting it is refused rather than allowed.
194
+ * Irreversible. `password` is required for an account that holds one. An
195
+ * account with none sets `confirm`, on a sign-in made in the last ten minutes:
196
+ * an older one is refused, and the user signs in again. The server enforces
197
+ * the re-auth gate and fails closed.
197
198
  */
198
199
  export declare function deleteMyAccount(env: FoirEnv, vars: {
199
200
  confirm: boolean;
200
201
  password?: string;
201
202
  }, options?: AuthOpOptions): Promise<DeleteAccountResult>;
203
+ /**
204
+ * End the calling user's own membership where the request stands: the
205
+ * organization `orgId` names, or, with none, the project's own. Every role
206
+ * they hold there ends with it; their account and what they made stay.
207
+ * `false` when they held no membership there.
208
+ *
209
+ * Refused where it would leave an organization with nobody who can staff it,
210
+ * or leave them nowhere to sign in: a person keeps one membership in the
211
+ * project, and {@link deleteMyAccount} is how they leave altogether.
212
+ */
213
+ export declare function leaveMembership(env: FoirEnv, options?: AuthOpOptions): Promise<boolean>;
202
214
  /**
203
215
  * Change the calling user's own name, picture or language. It asks no
204
216
  * permission: these are theirs.
@@ -235,6 +247,41 @@ export declare function createPersonalAccessToken(env: FoirEnv, vars: {
235
247
  name: string;
236
248
  expiresInDays: number;
237
249
  }, options?: AuthOpOptions): Promise<NewPersonalAccessToken>;
250
+ /** The email addresses the calling user is known by, the one their account uses first. */
251
+ export declare function myAddresses(env: FoirEnv, options?: AuthOpOptions): Promise<MyAddress[]>;
252
+ /**
253
+ * Send a code to an address the calling user is adding to their account, and
254
+ * answer when it stops working (ISO-8601, ten minutes on). The address is kept
255
+ * by {@link proveMyAddress}. `password` is their current one; an account with
256
+ * none needs a sign-in in the last ten minutes instead. At most five codes an
257
+ * hour.
258
+ */
259
+ export declare function addMyAddress(env: FoirEnv, vars: {
260
+ email: string;
261
+ password?: string;
262
+ }, options?: AuthOpOptions): Promise<string>;
263
+ /**
264
+ * Keep the address a code was sent to, as proven. Refused where another
265
+ * account in the project holds the address: nobody's address is taken.
266
+ */
267
+ export declare function proveMyAddress(env: FoirEnv, vars: {
268
+ email: string;
269
+ code: string;
270
+ }, options?: AuthOpOptions): Promise<MyAddress>;
271
+ /** Make one of the calling user's proven addresses the one their account uses. */
272
+ export declare function makeMyAddressPrimary(env: FoirEnv, email: string, options?: AuthOpOptions): Promise<MyAddress>;
273
+ /**
274
+ * Remove one of the calling user's addresses. The one their account uses
275
+ * stays: make another primary first.
276
+ */
277
+ export declare function removeMyAddress(env: FoirEnv, email: string, options?: AuthOpOptions): Promise<boolean>;
278
+ /**
279
+ * A copy of the calling user's own data: their account (profile, addresses,
280
+ * memberships and roles, sign-in providers, authorised apps, sessions and
281
+ * notification preferences) and everything deleting it would erase, the
282
+ * records and files they own.
283
+ */
284
+ export declare function exportMyData(env: FoirEnv, options?: AuthOpOptions): Promise<MyDataExport>;
238
285
  /** The providers the calling user signs in with. */
239
286
  export declare function mySignInMethods(env: FoirEnv, options?: AuthOpOptions): Promise<MySignInMethod[]>;
240
287
  /**
@@ -295,6 +342,15 @@ export declare function removeFactor(env: FoirEnv, vars: {
295
342
  kind: string;
296
343
  id: string;
297
344
  }, options?: AuthOpOptions): Promise<boolean>;
345
+ /**
346
+ * Rename one of the calling user's security keys or passkeys. A name proves
347
+ * nothing and admits nobody, so no step-up is asked.
348
+ */
349
+ export declare function renameFactor(env: FoirEnv, vars: {
350
+ kind: 'security_key' | 'passkey';
351
+ id: string;
352
+ name: string;
353
+ }, options?: AuthOpOptions): Promise<MyFactor>;
298
354
  /**
299
355
  * Make the calling user new recovery codes, with an elevated handle from
300
356
  * {@link completeStepUp}. They replace any held and are answered here once.
@@ -10,7 +10,7 @@
10
10
  * the caller's own manifest advertises, through the same op transport
11
11
  * `@foir/sdk/data` uses, so `graphql` is not on this module's path at all.
12
12
  */
13
- export { login, register, requestOTP, loginWithOTP, refreshTokens, loginWithProvider, providerCallback, providerVerifyOTP, providerSignInRefusalOf, signInRefusalOf, confirmProviderLink, resendProviderLinkCode, getAuthProviders, getAuthConfig, getDefaultAuthProvider, signupContext, joinWaitlist, requestPasswordReset, resetPassword, updatePassword, currentUser, myProviderToken, logout, deleteMyAccount, updateMyProfile, myAuthorizedApps, revokeAuthorizedApp, mySessions, endMySession, signOutEverywhere, createPersonalAccessToken, mySignInMethods, connectSignInMethod, disconnectSignInMethod, myFactors, beginStepUp, completeStepUp, beginFactorEnrollment, completeFactorEnrollment, removeFactor, makeRecoveryCodes, myOrganizations, registerOrganization, saveSession, clearSession, getSessionToken, getSessionUser, signInWithPassword, signUpWithPassword, signInWithOTP, resetPasswordAndSignIn, refreshSession, refreshSessionOnce, signOut, authedRequest, authedOp, requireAuth, } from './auth';
13
+ export { login, register, requestOTP, loginWithOTP, refreshTokens, loginWithProvider, providerCallback, providerVerifyOTP, providerSignInRefusalOf, signInRefusalOf, confirmProviderLink, resendProviderLinkCode, getAuthProviders, getAuthConfig, getDefaultAuthProvider, signupContext, joinWaitlist, requestPasswordReset, resetPassword, updatePassword, currentUser, myProviderToken, logout, deleteMyAccount, leaveMembership, updateMyProfile, myAuthorizedApps, revokeAuthorizedApp, mySessions, endMySession, myAddresses, addMyAddress, proveMyAddress, makeMyAddressPrimary, removeMyAddress, exportMyData, signOutEverywhere, createPersonalAccessToken, mySignInMethods, connectSignInMethod, disconnectSignInMethod, myFactors, beginStepUp, completeStepUp, beginFactorEnrollment, completeFactorEnrollment, removeFactor, renameFactor, makeRecoveryCodes, myOrganizations, registerOrganization, saveSession, clearSession, getSessionToken, getSessionUser, signInWithPassword, signUpWithPassword, signInWithOTP, resetPasswordAndSignIn, refreshSession, refreshSessionOnce, signOut, authedRequest, authedOp, requireAuth, } from './auth';
14
14
  export type { FoirAuthTokens, FoirUser, SessionAdapter, RequireAuthOptions, } from './auth';
15
15
  export { userAccess, getSessionAccess, hasRole, hasScope, requireRole, requireScope, FoirAccessDeniedError, } from './access';
16
16
  export type { FoirAccess, FoirAccessDenial } from './access';
@@ -21,4 +21,4 @@ export { hostedLoginUrl, hostedLogoutUrl, fetchHostedSession, hostedSignInNotice
21
21
  export type { HostedLoginConfig, HostedSession, HostedSessionResult, HostedSignInNotice } from './hosted';
22
22
  export { createFoirSessionClient } from './session-client';
23
23
  export type { FoirSessionClient, FoirSessionConfig, FoirSessionUser, } from './session-client';
24
- export type { AuthResult, ProviderLoginResult, AuthProviderPublic, ProviderLoginInput, ProviderCallbackInput, ProviderOTPVerifyInput, SignupContext, SignupMode, AuthConfig, AuthConfigProvider, DefaultAuthProvider, CurrentUser, ProviderToken, ProviderTokenRefresh, DeleteAccountResult, MyOrganization, MyProfile, MyProfileChange, AuthorizedApp, MySession, NewPersonalAccessToken, MySignInMethod, MyFactor, StepUp, FactorEnrollment, } from './operations';
24
+ export type { AuthResult, ProviderLoginResult, AuthProviderPublic, ProviderLoginInput, ProviderCallbackInput, ProviderOTPVerifyInput, SignupContext, SignupMode, AuthConfig, AuthConfigProvider, DefaultAuthProvider, CurrentUser, ProviderToken, ProviderTokenRefresh, DeleteAccountResult, MyOrganization, MyProfile, MyProfileChange, AuthorizedApp, MySession, MyAddress, MyDataExport, NewPersonalAccessToken, MySignInMethod, MyFactor, StepUp, FactorEnrollment, } from './operations';
@@ -200,6 +200,61 @@ export interface MySession {
200
200
  /** Whether it is the session making the request. */
201
201
  current: boolean;
202
202
  }
203
+ /** An email address the calling user is known by. */
204
+ export interface MyAddress {
205
+ email: string;
206
+ /** Whether it is the address their account uses: shown for them, and where mail to them goes. */
207
+ primary: boolean;
208
+ /** Whether they proved they hold it. Every address they added is proven. */
209
+ proven: boolean;
210
+ /** ISO-8601. */
211
+ addedAt: string | null;
212
+ }
213
+ /**
214
+ * The calling user's copy of their own data, the `foir.my-data.v1` document:
215
+ * their account and everything deleting it would erase. No password, code or
216
+ * token value is in it.
217
+ */
218
+ export interface MyDataExport {
219
+ format: 'foir.my-data.v1';
220
+ /** ISO-8601. */
221
+ exportedAt: string;
222
+ account: Record<string, unknown> & {
223
+ id: string;
224
+ pool: string;
225
+ poolKind: string;
226
+ status: string;
227
+ };
228
+ addresses: Array<{
229
+ email: string;
230
+ primary: boolean;
231
+ proven: boolean;
232
+ addedAt?: string;
233
+ }>;
234
+ memberships: Array<Record<string, unknown> & {
235
+ roles: string[];
236
+ }>;
237
+ signInMethods: Array<Record<string, unknown>>;
238
+ authorizedApps: Array<Record<string, unknown>>;
239
+ sessions: Array<Record<string, unknown>>;
240
+ notificationPreferences: Array<Record<string, unknown>>;
241
+ /** The records the user owns, each with the content it holds now. */
242
+ records: Array<{
243
+ id: string;
244
+ model: string;
245
+ key?: string;
246
+ project: string;
247
+ data: Record<string, unknown>;
248
+ }>;
249
+ /** The files the user owns; their bytes are fetched from `url`. */
250
+ files: Array<{
251
+ id: string;
252
+ name: string;
253
+ mimeType: string;
254
+ size: number;
255
+ url: string;
256
+ }>;
257
+ }
203
258
  /** A personal access token just made: its value is shown here once. */
204
259
  export interface NewPersonalAccessToken {
205
260
  token: MySession;
@@ -56,12 +56,19 @@ export declare const AUTH_OPS: {
56
56
  readonly resetPassword: "resetPassword";
57
57
  readonly updatePassword: "updatePassword";
58
58
  readonly deleteMyAccount: "deleteMyAccount";
59
+ readonly leaveMembership: "leaveMembership";
59
60
  readonly updateMyProfile: "updateMyProfile";
60
61
  readonly myAuthorizedApps: "myAuthorizedApps";
61
62
  readonly revokeAuthorizedApp: "revokeAuthorizedApp";
62
63
  readonly mySessions: "mySessions";
63
64
  readonly endMySession: "endMySession";
64
65
  readonly signOutEverywhere: "signOutEverywhere";
66
+ readonly myAddresses: "myAddresses";
67
+ readonly addMyAddress: "addMyAddress";
68
+ readonly proveMyAddress: "proveMyAddress";
69
+ readonly makeMyAddressPrimary: "makeMyAddressPrimary";
70
+ readonly removeMyAddress: "removeMyAddress";
71
+ readonly exportMyData: "exportMyData";
65
72
  readonly createPersonalAccessToken: "createPersonalAccessToken";
66
73
  readonly mySignInMethods: "mySignInMethods";
67
74
  readonly connectSignInMethod: "connectSignInMethod";
@@ -72,6 +79,7 @@ export declare const AUTH_OPS: {
72
79
  readonly beginFactorEnrollment: "beginFactorEnrollment";
73
80
  readonly completeFactorEnrollment: "completeFactorEnrollment";
74
81
  readonly removeFactor: "removeFactor";
82
+ readonly renameFactor: "renameFactor";
75
83
  readonly makeRecoveryCodes: "makeRecoveryCodes";
76
84
  readonly myOrganizations: "myOrganizations";
77
85
  readonly registerOrganization: "registerOrganization";
package/dist/auth.js CHANGED
@@ -1094,6 +1094,8 @@ var AUTH_OPS = {
1094
1094
  resetPassword: "resetPassword",
1095
1095
  updatePassword: "updatePassword",
1096
1096
  deleteMyAccount: "deleteMyAccount",
1097
+ // Ending their own membership where the request stands.
1098
+ leaveMembership: "leaveMembership",
1097
1099
  // The user's own profile, and the apps they have agreed may act for them.
1098
1100
  updateMyProfile: "updateMyProfile",
1099
1101
  myAuthorizedApps: "myAuthorizedApps",
@@ -1103,6 +1105,14 @@ var AUTH_OPS = {
1103
1105
  mySessions: "mySessions",
1104
1106
  endMySession: "endMySession",
1105
1107
  signOutEverywhere: "signOutEverywhere",
1108
+ // Their email addresses: one added is kept once the code it was sent proves it.
1109
+ myAddresses: "myAddresses",
1110
+ addMyAddress: "addMyAddress",
1111
+ proveMyAddress: "proveMyAddress",
1112
+ makeMyAddressPrimary: "makeMyAddressPrimary",
1113
+ removeMyAddress: "removeMyAddress",
1114
+ // A copy of their own data.
1115
+ exportMyData: "exportMyData",
1106
1116
  createPersonalAccessToken: "createPersonalAccessToken",
1107
1117
  mySignInMethods: "mySignInMethods",
1108
1118
  connectSignInMethod: "connectSignInMethod",
@@ -1114,6 +1124,7 @@ var AUTH_OPS = {
1114
1124
  beginFactorEnrollment: "beginFactorEnrollment",
1115
1125
  completeFactorEnrollment: "completeFactorEnrollment",
1116
1126
  removeFactor: "removeFactor",
1127
+ renameFactor: "renameFactor",
1117
1128
  makeRecoveryCodes: "makeRecoveryCodes",
1118
1129
  // The organizations the caller may stand in. Nothing selects one: a request
1119
1130
  // names the organization it acts in (`orgId` or `orgUrl` below), and the
@@ -1282,6 +1293,9 @@ async function logout(env, options) {
1282
1293
  async function deleteMyAccount(env, vars, options) {
1283
1294
  return authOp(env, AUTH_OPS.deleteMyAccount, vars, options);
1284
1295
  }
1296
+ async function leaveMembership(env, options) {
1297
+ return authOp(env, AUTH_OPS.leaveMembership, void 0, options);
1298
+ }
1285
1299
  async function updateMyProfile(env, change, options) {
1286
1300
  return authOp(env, AUTH_OPS.updateMyProfile, change, options);
1287
1301
  }
@@ -1303,6 +1317,24 @@ async function signOutEverywhere(env, vars = {}, options) {
1303
1317
  async function createPersonalAccessToken(env, vars, options) {
1304
1318
  return authOp(env, AUTH_OPS.createPersonalAccessToken, vars, options);
1305
1319
  }
1320
+ async function myAddresses(env, options) {
1321
+ return authOp(env, AUTH_OPS.myAddresses, void 0, options);
1322
+ }
1323
+ async function addMyAddress(env, vars, options) {
1324
+ return authOp(env, AUTH_OPS.addMyAddress, vars, options);
1325
+ }
1326
+ async function proveMyAddress(env, vars, options) {
1327
+ return authOp(env, AUTH_OPS.proveMyAddress, vars, options);
1328
+ }
1329
+ async function makeMyAddressPrimary(env, email, options) {
1330
+ return authOp(env, AUTH_OPS.makeMyAddressPrimary, { email }, options);
1331
+ }
1332
+ async function removeMyAddress(env, email, options) {
1333
+ return authOp(env, AUTH_OPS.removeMyAddress, { email }, options);
1334
+ }
1335
+ async function exportMyData(env, options) {
1336
+ return authOp(env, AUTH_OPS.exportMyData, void 0, options);
1337
+ }
1306
1338
  async function mySignInMethods(env, options) {
1307
1339
  return authOp(env, AUTH_OPS.mySignInMethods, void 0, options);
1308
1340
  }
@@ -1330,6 +1362,9 @@ async function completeFactorEnrollment(env, vars, options) {
1330
1362
  async function removeFactor(env, vars, options) {
1331
1363
  return authOp(env, AUTH_OPS.removeFactor, vars, options);
1332
1364
  }
1365
+ async function renameFactor(env, vars, options) {
1366
+ return authOp(env, AUTH_OPS.renameFactor, vars, options);
1367
+ }
1333
1368
  async function makeRecoveryCodes(env, elevatedHandle, options) {
1334
1369
  return authOp(env, AUTH_OPS.makeRecoveryCodes, { elevatedHandle }, options);
1335
1370
  }
@@ -2007,6 +2042,7 @@ export {
2007
2042
  FoirAccessDeniedError,
2008
2043
  FoirAuthDowngradedError,
2009
2044
  FoirSessionExpiredError,
2045
+ addMyAddress,
2010
2046
  authedOp,
2011
2047
  authedRequest,
2012
2048
  beginFactorEnrollment,
@@ -2022,6 +2058,7 @@ export {
2022
2058
  deleteMyAccount,
2023
2059
  disconnectSignInMethod,
2024
2060
  endMySession,
2061
+ exportMyData,
2025
2062
  fetchHostedSession,
2026
2063
  getAuthConfig,
2027
2064
  getAuthProviders,
@@ -2035,17 +2072,21 @@ export {
2035
2072
  hostedLogoutUrl,
2036
2073
  hostedSignInNoticeOf,
2037
2074
  joinWaitlist,
2075
+ leaveMembership,
2038
2076
  login,
2039
2077
  loginWithOTP,
2040
2078
  loginWithProvider,
2041
2079
  logout,
2080
+ makeMyAddressPrimary,
2042
2081
  makeRecoveryCodes,
2082
+ myAddresses,
2043
2083
  myAuthorizedApps,
2044
2084
  myFactors,
2045
2085
  myOrganizations,
2046
2086
  myProviderToken,
2047
2087
  mySessions,
2048
2088
  mySignInMethods,
2089
+ proveMyAddress,
2049
2090
  providerCallback,
2050
2091
  providerSignInRefusalOf,
2051
2092
  providerVerifyOTP,
@@ -2055,6 +2096,8 @@ export {
2055
2096
  register,
2056
2097
  registerOrganization,
2057
2098
  removeFactor,
2099
+ removeMyAddress,
2100
+ renameFactor,
2058
2101
  requestOTP,
2059
2102
  requestPasswordReset,
2060
2103
  requireAuth,
package/dist/next.js CHANGED
@@ -974,6 +974,8 @@ var AUTH_OPS = {
974
974
  resetPassword: "resetPassword",
975
975
  updatePassword: "updatePassword",
976
976
  deleteMyAccount: "deleteMyAccount",
977
+ // Ending their own membership where the request stands.
978
+ leaveMembership: "leaveMembership",
977
979
  // The user's own profile, and the apps they have agreed may act for them.
978
980
  updateMyProfile: "updateMyProfile",
979
981
  myAuthorizedApps: "myAuthorizedApps",
@@ -983,6 +985,14 @@ var AUTH_OPS = {
983
985
  mySessions: "mySessions",
984
986
  endMySession: "endMySession",
985
987
  signOutEverywhere: "signOutEverywhere",
988
+ // Their email addresses: one added is kept once the code it was sent proves it.
989
+ myAddresses: "myAddresses",
990
+ addMyAddress: "addMyAddress",
991
+ proveMyAddress: "proveMyAddress",
992
+ makeMyAddressPrimary: "makeMyAddressPrimary",
993
+ removeMyAddress: "removeMyAddress",
994
+ // A copy of their own data.
995
+ exportMyData: "exportMyData",
986
996
  createPersonalAccessToken: "createPersonalAccessToken",
987
997
  mySignInMethods: "mySignInMethods",
988
998
  connectSignInMethod: "connectSignInMethod",
@@ -994,6 +1004,7 @@ var AUTH_OPS = {
994
1004
  beginFactorEnrollment: "beginFactorEnrollment",
995
1005
  completeFactorEnrollment: "completeFactorEnrollment",
996
1006
  removeFactor: "removeFactor",
1007
+ renameFactor: "renameFactor",
997
1008
  makeRecoveryCodes: "makeRecoveryCodes",
998
1009
  // The organizations the caller may stand in. Nothing selects one: a request
999
1010
  // names the organization it acts in (`orgId` or `orgUrl` below), and the
package/dist/push.js CHANGED
@@ -1094,6 +1094,8 @@ var AUTH_OPS = {
1094
1094
  resetPassword: "resetPassword",
1095
1095
  updatePassword: "updatePassword",
1096
1096
  deleteMyAccount: "deleteMyAccount",
1097
+ // Ending their own membership where the request stands.
1098
+ leaveMembership: "leaveMembership",
1097
1099
  // The user's own profile, and the apps they have agreed may act for them.
1098
1100
  updateMyProfile: "updateMyProfile",
1099
1101
  myAuthorizedApps: "myAuthorizedApps",
@@ -1103,6 +1105,14 @@ var AUTH_OPS = {
1103
1105
  mySessions: "mySessions",
1104
1106
  endMySession: "endMySession",
1105
1107
  signOutEverywhere: "signOutEverywhere",
1108
+ // Their email addresses: one added is kept once the code it was sent proves it.
1109
+ myAddresses: "myAddresses",
1110
+ addMyAddress: "addMyAddress",
1111
+ proveMyAddress: "proveMyAddress",
1112
+ makeMyAddressPrimary: "makeMyAddressPrimary",
1113
+ removeMyAddress: "removeMyAddress",
1114
+ // A copy of their own data.
1115
+ exportMyData: "exportMyData",
1106
1116
  createPersonalAccessToken: "createPersonalAccessToken",
1107
1117
  mySignInMethods: "mySignInMethods",
1108
1118
  connectSignInMethod: "connectSignInMethod",
@@ -1114,6 +1124,7 @@ var AUTH_OPS = {
1114
1124
  beginFactorEnrollment: "beginFactorEnrollment",
1115
1125
  completeFactorEnrollment: "completeFactorEnrollment",
1116
1126
  removeFactor: "removeFactor",
1127
+ renameFactor: "renameFactor",
1117
1128
  makeRecoveryCodes: "makeRecoveryCodes",
1118
1129
  // The organizations the caller may stand in. Nothing selects one: a request
1119
1130
  // names the organization it acts in (`orgId` or `orgUrl` below), and the
package/dist/react.js CHANGED
@@ -968,6 +968,8 @@ var AUTH_OPS = {
968
968
  resetPassword: "resetPassword",
969
969
  updatePassword: "updatePassword",
970
970
  deleteMyAccount: "deleteMyAccount",
971
+ // Ending their own membership where the request stands.
972
+ leaveMembership: "leaveMembership",
971
973
  // The user's own profile, and the apps they have agreed may act for them.
972
974
  updateMyProfile: "updateMyProfile",
973
975
  myAuthorizedApps: "myAuthorizedApps",
@@ -977,6 +979,14 @@ var AUTH_OPS = {
977
979
  mySessions: "mySessions",
978
980
  endMySession: "endMySession",
979
981
  signOutEverywhere: "signOutEverywhere",
982
+ // Their email addresses: one added is kept once the code it was sent proves it.
983
+ myAddresses: "myAddresses",
984
+ addMyAddress: "addMyAddress",
985
+ proveMyAddress: "proveMyAddress",
986
+ makeMyAddressPrimary: "makeMyAddressPrimary",
987
+ removeMyAddress: "removeMyAddress",
988
+ // A copy of their own data.
989
+ exportMyData: "exportMyData",
980
990
  createPersonalAccessToken: "createPersonalAccessToken",
981
991
  mySignInMethods: "mySignInMethods",
982
992
  connectSignInMethod: "connectSignInMethod",
@@ -988,6 +998,7 @@ var AUTH_OPS = {
988
998
  beginFactorEnrollment: "beginFactorEnrollment",
989
999
  completeFactorEnrollment: "completeFactorEnrollment",
990
1000
  removeFactor: "removeFactor",
1001
+ renameFactor: "renameFactor",
991
1002
  makeRecoveryCodes: "makeRecoveryCodes",
992
1003
  // The organizations the caller may stand in. Nothing selects one: a request
993
1004
  // names the organization it acts in (`orgId` or `orgUrl` below), and the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foir/sdk",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "description": "Official Foir SDK — editor iframe client + server-side platform helpers",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -177,8 +177,8 @@
177
177
  "ws": "^8.18.0",
178
178
  "y-websocket": "^3.0.0",
179
179
  "yjs": "^13.6.30",
180
- "@foir/proto-ts": "0.109.0",
181
- "@foir/access-vocab": "0.0.0"
180
+ "@foir/access-vocab": "0.0.0",
181
+ "@foir/proto-ts": "0.109.0"
182
182
  },
183
183
  "engines": {
184
184
  "node": ">=18.0.0"