@foir/sdk 0.25.0 → 0.26.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 +23 -0
- package/dist/auth/hosted.d.ts +14 -3
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/session-client.d.ts +7 -2
- package/dist/auth-session.js +2 -1
- package/dist/auth.js +9 -3
- package/dist/placement/index.d.ts +17 -0
- package/dist/placement.js +16 -3
- package/dist/react/FoirProvider.d.ts +5 -4
- package/dist/react.js +6 -3
- package/dist/server.js +3 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -108,6 +108,29 @@ 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.26.0] — 2026-10-19
|
|
112
|
+
|
|
113
|
+
### Changed
|
|
114
|
+
|
|
115
|
+
- **`session.request` in `@foir/sdk/placement` throws `PlacementRequestFailed`.**
|
|
116
|
+
Its message says each distinct refusal once, where it repeated a read
|
|
117
|
+
refused on a field once per row, and its `errors` keeps every error with its
|
|
118
|
+
`path`. It is still an `Error`, so a caller that reads `message` is
|
|
119
|
+
unaffected.
|
|
120
|
+
|
|
121
|
+
### Added
|
|
122
|
+
|
|
123
|
+
- **A hosted sign-in can name the organization it is for** (`@foir/sdk/auth`,
|
|
124
|
+
`@foir/sdk/react`): `hostedLoginUrl(config, returnTo, { org })`, a session
|
|
125
|
+
client's `signInUrl(returnTo, { org })` and the provider's
|
|
126
|
+
`hostedSignInUrl(returnTo, { org })`. Use it when one auth client serves an
|
|
127
|
+
address per organization. The login domain's front door passes it on, and
|
|
128
|
+
the sign-in takes that organization's branding, providers and return
|
|
129
|
+
addresses. The platform refuses an organization other than the one the
|
|
130
|
+
domain or app is bound to, one of another project, and one that is not
|
|
131
|
+
active.
|
|
132
|
+
- **`HostedLoginOptions`** (`@foir/sdk/auth`, type).
|
|
133
|
+
|
|
111
134
|
## [0.25.0] — 2026-10-18
|
|
112
135
|
|
|
113
136
|
### Changed
|
package/dist/auth/hosted.d.ts
CHANGED
|
@@ -27,11 +27,22 @@ export interface HostedLoginConfig {
|
|
|
27
27
|
*/
|
|
28
28
|
clientId?: string;
|
|
29
29
|
}
|
|
30
|
+
/** What a sign-in started at the hosted front door is for. */
|
|
31
|
+
export interface HostedLoginOptions {
|
|
32
|
+
/**
|
|
33
|
+
* The organization the person signs in to, when one auth client serves an
|
|
34
|
+
* address per organization. It decides the branding, the pool, and which
|
|
35
|
+
* addresses the person may come back to. The platform refuses an
|
|
36
|
+
* organization other than the one the login domain or app is bound to, one
|
|
37
|
+
* of another project, and one that is not active.
|
|
38
|
+
*/
|
|
39
|
+
org?: string;
|
|
40
|
+
}
|
|
30
41
|
/**
|
|
31
|
-
* Build the redirect URL to the hosted front door, forwarding
|
|
32
|
-
*
|
|
42
|
+
* Build the redirect URL to the hosted front door, forwarding an absolute
|
|
43
|
+
* `returnTo` and, where the app names one, the organization the sign-in is for.
|
|
33
44
|
*/
|
|
34
|
-
export declare function hostedLoginUrl(config: HostedLoginConfig, returnTo?: string): string;
|
|
45
|
+
export declare function hostedLoginUrl(config: HostedLoginConfig, returnTo?: string, options?: HostedLoginOptions): string;
|
|
35
46
|
/**
|
|
36
47
|
* Build the redirect URL that ENDS the hosted session — the mirror of
|
|
37
48
|
* `hostedLoginUrl`, and the only thing that actually signs a user out on
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export { FoirAuthDowngradedError, FoirSessionExpiredError } from '../graphql/foi
|
|
|
18
18
|
export { AUTH_OPS } from './ops';
|
|
19
19
|
export type { AuthOpName, AuthOpOptions } from './ops';
|
|
20
20
|
export { hostedLoginUrl, hostedLogoutUrl, fetchHostedSession, hostedSignInNoticeOf } from './hosted';
|
|
21
|
-
export type { HostedLoginConfig, HostedSession, HostedSessionResult, HostedSignInNotice } from './hosted';
|
|
21
|
+
export type { HostedLoginConfig, HostedLoginOptions, HostedSession, HostedSessionResult, HostedSignInNotice } from './hosted';
|
|
22
22
|
export { createFoirSessionClient } from './session-client';
|
|
23
23
|
export type { FoirSessionClient, FoirSessionConfig, FoirSessionUser, } from './session-client';
|
|
24
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';
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* api.foir.dev but a browser cannot reach them there — the cookie would be
|
|
28
28
|
* cross-site, and that CORS surface deliberately refuses credentials.
|
|
29
29
|
*/
|
|
30
|
+
import type { HostedLoginOptions } from './hosted';
|
|
30
31
|
export interface FoirSessionConfig {
|
|
31
32
|
/**
|
|
32
33
|
* Your verified custom login domain, e.g. `https://login.acme.com`. Must share
|
|
@@ -66,8 +67,12 @@ export interface FoirSessionClient {
|
|
|
66
67
|
getUser(): Promise<FoirSessionUser | null>;
|
|
67
68
|
/** Revoke the session server-side and clear the cookie. Idempotent. */
|
|
68
69
|
signOut(): Promise<void>;
|
|
69
|
-
/**
|
|
70
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Where to send the browser to sign in. Name the organization the sign-in is
|
|
72
|
+
* for with `options.org` when one auth client serves an address per
|
|
73
|
+
* organization.
|
|
74
|
+
*/
|
|
75
|
+
signInUrl(returnTo?: string, options?: HostedLoginOptions): string;
|
|
71
76
|
/** Observe session changes. Returns an unsubscribe function. */
|
|
72
77
|
subscribe(listener: (user: FoirSessionUser | null) => void): () => void;
|
|
73
78
|
/** Cancel the refresh timer. Call on unmount. */
|
package/dist/auth-session.js
CHANGED
|
@@ -113,10 +113,11 @@ function createFoirSessionClient(config) {
|
|
|
113
113
|
forget();
|
|
114
114
|
config.onSignOut?.();
|
|
115
115
|
},
|
|
116
|
-
signInUrl(returnTo) {
|
|
116
|
+
signInUrl(returnTo, options = {}) {
|
|
117
117
|
const dest = new URL(trimSlash(config.loginOrigin));
|
|
118
118
|
const target = returnTo ?? (typeof window !== "undefined" ? window.location.href : void 0);
|
|
119
119
|
if (target && target !== "/") dest.searchParams.set("returnTo", target);
|
|
120
|
+
if (options.org) dest.searchParams.set("org", options.org);
|
|
120
121
|
return dest.toString();
|
|
121
122
|
},
|
|
122
123
|
subscribe(listener) {
|
package/dist/auth.js
CHANGED
|
@@ -1567,6 +1567,8 @@ var GRANT_TABLE = [
|
|
|
1567
1567
|
["authclients:write", "none", [], []],
|
|
1568
1568
|
["domains:read", "none", [], []],
|
|
1569
1569
|
["domains:write", "none", [], []],
|
|
1570
|
+
["loginpages:read", "none", [], []],
|
|
1571
|
+
["loginpages:write", "none", [], []],
|
|
1570
1572
|
["secrets:read", "none", [], []],
|
|
1571
1573
|
["secrets:list", "none", [], []],
|
|
1572
1574
|
["secrets:put", "none", [], []],
|
|
@@ -1604,7 +1606,7 @@ var GRANT_TABLE = [
|
|
|
1604
1606
|
["projects:read", "none", [], []],
|
|
1605
1607
|
["projects:write", "none", [], []],
|
|
1606
1608
|
["project:stand", "none", [], []],
|
|
1607
|
-
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
1609
|
+
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "loginpages:read", "loginpages:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
1608
1610
|
["projects:create", "none", [], []],
|
|
1609
1611
|
["projects:delete", "none", [], []],
|
|
1610
1612
|
["tenants:read", "none", [], []],
|
|
@@ -1797,11 +1799,14 @@ async function requireScope(adapter, env, scope) {
|
|
|
1797
1799
|
var DEFAULT_COOKIE_NAME = "foir_session";
|
|
1798
1800
|
var DEFAULT_SESSION_PATH = "/session/token";
|
|
1799
1801
|
var DEFAULT_END_SESSION_PATH = "/session/end-session";
|
|
1800
|
-
function hostedLoginUrl(config, returnTo) {
|
|
1802
|
+
function hostedLoginUrl(config, returnTo, options = {}) {
|
|
1801
1803
|
const dest = new URL(config.loginOrigin);
|
|
1802
1804
|
if (returnTo && returnTo !== "/") {
|
|
1803
1805
|
dest.searchParams.set("returnTo", returnTo);
|
|
1804
1806
|
}
|
|
1807
|
+
if (options.org) {
|
|
1808
|
+
dest.searchParams.set("org", options.org);
|
|
1809
|
+
}
|
|
1805
1810
|
return dest.toString();
|
|
1806
1811
|
}
|
|
1807
1812
|
function hostedLogoutUrl(config, clientId, returnTo) {
|
|
@@ -2017,10 +2022,11 @@ function createFoirSessionClient(config) {
|
|
|
2017
2022
|
forget();
|
|
2018
2023
|
config.onSignOut?.();
|
|
2019
2024
|
},
|
|
2020
|
-
signInUrl(returnTo) {
|
|
2025
|
+
signInUrl(returnTo, options = {}) {
|
|
2021
2026
|
const dest = new URL(trimSlash(config.loginOrigin));
|
|
2022
2027
|
const target = returnTo ?? (typeof window !== "undefined" ? window.location.href : void 0);
|
|
2023
2028
|
if (target && target !== "/") dest.searchParams.set("returnTo", target);
|
|
2029
|
+
if (options.org) dest.searchParams.set("org", options.org);
|
|
2024
2030
|
return dest.toString();
|
|
2025
2031
|
},
|
|
2026
2032
|
subscribe(listener) {
|
|
@@ -113,6 +113,23 @@ export declare function placementFrameAncestors(origins: readonly string[]): str
|
|
|
113
113
|
export declare class PlacementRefused extends Error {
|
|
114
114
|
constructor(reason: string);
|
|
115
115
|
}
|
|
116
|
+
/** One error of a GraphQL answer, as Foir's API sends it. */
|
|
117
|
+
export interface PlacementRequestError {
|
|
118
|
+
message: string;
|
|
119
|
+
path?: (string | number)[];
|
|
120
|
+
extensions?: Record<string, unknown>;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A request the page made on its token that Foir's API refused or failed.
|
|
124
|
+
* The message says each distinct refusal once: a read refused on a field is
|
|
125
|
+
* answered once per row, and one missing grant over five hundred rows would
|
|
126
|
+
* otherwise read five hundred times. `errors` keeps every one, with its path.
|
|
127
|
+
*/
|
|
128
|
+
export declare class PlacementRequestFailed extends Error {
|
|
129
|
+
readonly errors: PlacementRequestError[];
|
|
130
|
+
readonly status: number;
|
|
131
|
+
constructor(errors: PlacementRequestError[], status: number);
|
|
132
|
+
}
|
|
116
133
|
export interface ConnectPlacementOptions {
|
|
117
134
|
/** Foir's API, e.g. `https://api.foir.dev`. */
|
|
118
135
|
apiUrl: string;
|
package/dist/placement.js
CHANGED
|
@@ -41,6 +41,8 @@ var GRANT_TABLE = [
|
|
|
41
41
|
["authclients:write", "none", [], []],
|
|
42
42
|
["domains:read", "none", [], []],
|
|
43
43
|
["domains:write", "none", [], []],
|
|
44
|
+
["loginpages:read", "none", [], []],
|
|
45
|
+
["loginpages:write", "none", [], []],
|
|
44
46
|
["secrets:read", "none", [], []],
|
|
45
47
|
["secrets:list", "none", [], []],
|
|
46
48
|
["secrets:put", "none", [], []],
|
|
@@ -78,7 +80,7 @@ var GRANT_TABLE = [
|
|
|
78
80
|
["projects:read", "none", [], []],
|
|
79
81
|
["projects:write", "none", [], []],
|
|
80
82
|
["project:stand", "none", [], []],
|
|
81
|
-
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
83
|
+
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "loginpages:read", "loginpages:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
82
84
|
["projects:create", "none", [], []],
|
|
83
85
|
["projects:delete", "none", [], []],
|
|
84
86
|
["tenants:read", "none", [], []],
|
|
@@ -266,6 +268,17 @@ var PlacementRefused = class extends Error {
|
|
|
266
268
|
this.name = "PlacementRefused";
|
|
267
269
|
}
|
|
268
270
|
};
|
|
271
|
+
var PlacementRequestFailed = class extends Error {
|
|
272
|
+
errors;
|
|
273
|
+
status;
|
|
274
|
+
constructor(errors, status) {
|
|
275
|
+
const said = [...new Set(errors.map((e) => e.message))];
|
|
276
|
+
super(`[foir] placement request failed: ${said.length > 0 ? said.join("; ") : `HTTP ${status}`}`);
|
|
277
|
+
this.name = "PlacementRequestFailed";
|
|
278
|
+
this.errors = errors;
|
|
279
|
+
this.status = status;
|
|
280
|
+
}
|
|
281
|
+
};
|
|
269
282
|
function isHostMessage(data) {
|
|
270
283
|
if (typeof data !== "object" || data === null) return false;
|
|
271
284
|
const t = data.type;
|
|
@@ -325,8 +338,7 @@ function connectPlacement(options) {
|
|
|
325
338
|
});
|
|
326
339
|
const body = await res.json().catch(() => ({}));
|
|
327
340
|
if (!res.ok || body.errors && body.errors.length > 0) {
|
|
328
|
-
|
|
329
|
-
throw new Error(`[foir] placement request failed: ${messages}`);
|
|
341
|
+
throw new PlacementRequestFailed(body.errors ?? [], res.status);
|
|
330
342
|
}
|
|
331
343
|
return body.data;
|
|
332
344
|
},
|
|
@@ -381,6 +393,7 @@ export {
|
|
|
381
393
|
FOIR_CONSOLE_ORIGINS,
|
|
382
394
|
PLACEMENT_MESSAGE,
|
|
383
395
|
PlacementRefused,
|
|
396
|
+
PlacementRequestFailed,
|
|
384
397
|
connectPlacement,
|
|
385
398
|
placementFrameAncestors
|
|
386
399
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
import type { AuthProviderPublic, FoirAccess, FoirUser, FoirSessionConfig, SessionAdapter } from '../auth';
|
|
2
|
+
import type { AuthProviderPublic, FoirAccess, FoirUser, FoirSessionConfig, HostedLoginOptions, SessionAdapter } from '../auth';
|
|
3
3
|
import type { ProviderCallbackInput, ProviderLoginInput } from '../auth';
|
|
4
4
|
import type { FoirEnv } from '../graphql/foir-request';
|
|
5
5
|
/** Where the session hydration stands. */
|
|
@@ -53,9 +53,10 @@ export interface FoirContextValue {
|
|
|
53
53
|
/**
|
|
54
54
|
* In `hostedSession` mode, where to send the browser to sign in — sign-in is a
|
|
55
55
|
* redirect to your Foir login domain, not an in-page form. Null in token mode,
|
|
56
|
-
* where you call {@link FoirContextValue.signIn} instead.
|
|
56
|
+
* where you call {@link FoirContextValue.signIn} instead. `options.org` names
|
|
57
|
+
* the organization the sign-in is for.
|
|
57
58
|
*/
|
|
58
|
-
hostedSignInUrl: ((returnTo?: string) => string) | null;
|
|
59
|
+
hostedSignInUrl: ((returnTo?: string, options?: HostedLoginOptions) => string) | null;
|
|
59
60
|
}
|
|
60
61
|
export interface FoirProviderProps {
|
|
61
62
|
/** API config: `{ PLATFORM_API_URL, PLATFORM_API_KEY }` (a publishable key). */
|
|
@@ -151,5 +152,5 @@ export declare function useFoirAuth(): {
|
|
|
151
152
|
refresh: () => Promise<boolean>;
|
|
152
153
|
getToken: () => Promise<string | null>;
|
|
153
154
|
getProviders: () => Promise<AuthProviderPublic[]>;
|
|
154
|
-
hostedSignInUrl: ((returnTo?: string) => string) | null;
|
|
155
|
+
hostedSignInUrl: ((returnTo?: string, options?: HostedLoginOptions) => string) | null;
|
|
155
156
|
};
|
package/dist/react.js
CHANGED
|
@@ -1248,6 +1248,8 @@ var GRANT_TABLE = [
|
|
|
1248
1248
|
["authclients:write", "none", [], []],
|
|
1249
1249
|
["domains:read", "none", [], []],
|
|
1250
1250
|
["domains:write", "none", [], []],
|
|
1251
|
+
["loginpages:read", "none", [], []],
|
|
1252
|
+
["loginpages:write", "none", [], []],
|
|
1251
1253
|
["secrets:read", "none", [], []],
|
|
1252
1254
|
["secrets:list", "none", [], []],
|
|
1253
1255
|
["secrets:put", "none", [], []],
|
|
@@ -1285,7 +1287,7 @@ var GRANT_TABLE = [
|
|
|
1285
1287
|
["projects:read", "none", [], []],
|
|
1286
1288
|
["projects:write", "none", [], []],
|
|
1287
1289
|
["project:stand", "none", [], []],
|
|
1288
|
-
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
1290
|
+
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "loginpages:read", "loginpages:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
1289
1291
|
["projects:create", "none", [], []],
|
|
1290
1292
|
["projects:delete", "none", [], []],
|
|
1291
1293
|
["tenants:read", "none", [], []],
|
|
@@ -1549,10 +1551,11 @@ function createFoirSessionClient(config) {
|
|
|
1549
1551
|
forget();
|
|
1550
1552
|
config.onSignOut?.();
|
|
1551
1553
|
},
|
|
1552
|
-
signInUrl(returnTo) {
|
|
1554
|
+
signInUrl(returnTo, options = {}) {
|
|
1553
1555
|
const dest = new URL(trimSlash(config.loginOrigin));
|
|
1554
1556
|
const target = returnTo ?? (typeof window !== "undefined" ? window.location.href : void 0);
|
|
1555
1557
|
if (target && target !== "/") dest.searchParams.set("returnTo", target);
|
|
1558
|
+
if (options.org) dest.searchParams.set("org", options.org);
|
|
1556
1559
|
return dest.toString();
|
|
1557
1560
|
},
|
|
1558
1561
|
subscribe(listener) {
|
|
@@ -1779,7 +1782,7 @@ function FoirProvider({
|
|
|
1779
1782
|
}, [refresh, loadAccess, accessWasRead]);
|
|
1780
1783
|
const getProviders = useCallback(() => getAuthProviders(envRef.current), []);
|
|
1781
1784
|
const hostedSignInUrl = useMemo(
|
|
1782
|
-
() => hosted ? (returnTo) => hosted.signInUrl(returnTo) : null,
|
|
1785
|
+
() => hosted ? (returnTo, options) => hosted.signInUrl(returnTo, options) : null,
|
|
1783
1786
|
[hosted]
|
|
1784
1787
|
);
|
|
1785
1788
|
const value = useMemo(
|
package/dist/server.js
CHANGED
|
@@ -115,6 +115,8 @@ var GRANT_TABLE = [
|
|
|
115
115
|
["authclients:write", "none", [], []],
|
|
116
116
|
["domains:read", "none", [], []],
|
|
117
117
|
["domains:write", "none", [], []],
|
|
118
|
+
["loginpages:read", "none", [], []],
|
|
119
|
+
["loginpages:write", "none", [], []],
|
|
118
120
|
["secrets:read", "none", [], []],
|
|
119
121
|
["secrets:list", "none", [], []],
|
|
120
122
|
["secrets:put", "none", [], []],
|
|
@@ -152,7 +154,7 @@ var GRANT_TABLE = [
|
|
|
152
154
|
["projects:read", "none", [], []],
|
|
153
155
|
["projects:write", "none", [], []],
|
|
154
156
|
["project:stand", "none", [], []],
|
|
155
|
-
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
157
|
+
["project:manage", "none", [], ["project:stand", "records:read.all", "records:create", "records:write.all", "records:delete.all", "records:publish.all", "records:attribute", "search:read", "embeddings:read", "embeddings:write", "schemas:read", "drafts:read", "files:read.all", "files:write.all", "files:delete.all", "users:read.all", "identities:read", "users:create", "identities:delete", "users:write.all", "users:setup", "users:delete.all", "notifications:read.all", "notifications:write.all", "notifications:consent", "pushcredentials:read", "pushcredentials:write", "notes:read.all", "notes:write.all", "notes:create", "approvals:read", "approvals:write", "rooms:read", "rooms:write", "presence:read", "operations:read", "operations:execute", "operations:write", "appconfig:read", "schedules:read", "schedules:write", "hooks:read", "hooks:write", "auth:login_with_foir", "authclients:read", "authclients:write", "domains:read", "domains:write", "loginpages:read", "loginpages:write", "secrets:read", "secrets:list", "secrets:put", "secrets:delete", "appsecrets:read", "appsecrets:list", "appsecrets:put", "appsecrets:delete", "usersecrets:read", "usersecrets:list", "usersecrets:put", "usersecrets:delete", "opsecrets:read", "opsecrets:write", "settings:read", "settings:write", "designtokens:read", "designtokens:write", "models:read", "models:write", "configs:read", "configs:write", "signinproviders:read", "signinproviders:write", "apps:read", "apps:write", "events:read", "targeting:debug", "visitors:forward", "apikeys:read", "apikeys:write", "organizations:read", "organizations:create", "organizations:delete", "organizations:write", "organizations:reach", "members:read", "members:write", "roles:read", "roles:write", "projects:read", "projects:write", "audit:read"]],
|
|
156
158
|
["projects:create", "none", [], []],
|
|
157
159
|
["projects:delete", "none", [], []],
|
|
158
160
|
["tenants:read", "none", [], []],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foir/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Official Foir SDK — editor iframe client + server-side platform helpers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"blurhash": "^2.0.5",
|
|
169
169
|
"graphql": "^16.10.0",
|
|
170
170
|
"hls.js": "^1.6.16",
|
|
171
|
-
"jsdom": "^
|
|
171
|
+
"jsdom": "^28.1.0",
|
|
172
172
|
"react": "^19.2.0",
|
|
173
173
|
"react-dom": "^19.2.0",
|
|
174
174
|
"tsup": "^8.5.1",
|