@datalayer/core 1.1.66 → 1.2.10
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 +41 -18
- package/lib/api/constants.d.ts +1 -1
- package/lib/api/constants.js +1 -1
- package/lib/api/contents/attachments.js +3 -7
- package/lib/api/contents/datasets.d.ts +48 -0
- package/lib/api/contents/datasets.js +44 -7
- package/lib/api/contents/runtimeMounts.js +1 -1
- package/lib/api/contents/sandboxUid.d.ts +13 -45
- package/lib/api/contents/sandboxUid.js +14 -65
- package/lib/api/evals/client.d.ts +402 -0
- package/lib/api/evals/client.js +359 -0
- package/lib/api/evals/index.d.ts +10 -0
- package/lib/api/evals/index.js +18 -0
- package/lib/api/evals/request.d.ts +43 -0
- package/lib/api/evals/request.js +67 -0
- package/lib/api/evals/status.d.ts +27 -0
- package/lib/api/evals/status.js +122 -0
- package/lib/api/evals/types.d.ts +1335 -0
- package/lib/api/evals/types.js +5 -0
- package/lib/api/iam/connectedAgents.d.ts +29 -0
- package/lib/api/iam/connectedAgents.js +35 -0
- package/lib/api/iam/identityProviders.d.ts +76 -0
- package/lib/api/iam/identityProviders.js +187 -0
- package/lib/api/iam/index.d.ts +1 -0
- package/lib/api/iam/index.js +1 -0
- package/lib/api/iam/mcpPolicy.d.ts +102 -1
- package/lib/api/iam/mcpPolicy.js +38 -2
- package/lib/api/iam/profile.d.ts +17 -1
- package/lib/api/iam/profile.js +27 -0
- package/lib/api/iam/scimTokens.d.ts +79 -0
- package/lib/api/iam/scimTokens.js +141 -0
- package/lib/api/iam/secrets.js +9 -21
- package/lib/api/iam/trials.d.ts +38 -0
- package/lib/api/iam/trials.js +66 -0
- package/lib/api/index.d.ts +4 -0
- package/lib/api/index.js +4 -0
- package/lib/api/mcp/observability.d.ts +25 -9
- package/lib/api/mcp/observability.js +63 -50
- package/lib/api/orchestration/client.d.ts +53 -0
- package/lib/api/orchestration/client.js +105 -0
- package/lib/api/orchestration/events.d.ts +88 -0
- package/lib/api/orchestration/events.js +245 -0
- package/lib/api/orchestration/generated.d.ts +693 -0
- package/lib/api/orchestration/generated.js +687 -0
- package/lib/api/orchestration/index.d.ts +30 -0
- package/lib/api/orchestration/index.js +34 -0
- package/lib/api/orchestration/lifecycle.d.ts +39 -0
- package/lib/api/orchestration/lifecycle.js +57 -0
- package/lib/api/orchestration/measures.d.ts +55 -0
- package/lib/api/orchestration/measures.js +99 -0
- package/lib/api/otel/dashboards.d.ts +56 -0
- package/lib/api/otel/dashboards.js +50 -0
- package/lib/api/otel/index.d.ts +1 -0
- package/lib/api/otel/index.js +1 -0
- package/lib/api/otel/metrics.d.ts +16 -0
- package/lib/api/otel/metrics.js +15 -0
- package/lib/api/scheduler/client.d.ts +32 -0
- package/lib/api/scheduler/client.js +42 -0
- package/lib/api/scheduler/index.d.ts +8 -0
- package/lib/api/scheduler/index.js +16 -0
- package/lib/api/scheduler/request.d.ts +28 -0
- package/lib/api/scheduler/request.js +50 -0
- package/lib/api/scheduler/types.d.ts +88 -0
- package/lib/api/scheduler/types.js +5 -0
- package/lib/api/spacer/comments.d.ts +97 -0
- package/lib/api/spacer/comments.js +45 -0
- package/lib/api/spacer/index.d.ts +9 -0
- package/lib/api/spacer/index.js +17 -0
- package/lib/api/spacer/notebooks.d.ts +33 -0
- package/lib/api/spacer/notebooks.js +39 -0
- package/lib/api/spacer/request.d.ts +25 -0
- package/lib/api/spacer/request.js +46 -0
- package/lib/api/spacer/spaces.d.ts +68 -0
- package/lib/api/spacer/spaces.js +45 -0
- package/lib/api/utils/validation.d.ts +4 -4
- package/lib/api/utils/validation.js +10 -7
- package/lib/client/constants.d.ts +1 -0
- package/lib/client/constants.js +1 -0
- package/lib/components/animation/AnimatedText.d.ts +1 -44
- package/lib/components/animation/AnimatedText.js +6 -122
- package/lib/components/anonymous/AnonymousKeyExpired.d.ts +56 -0
- package/lib/components/anonymous/AnonymousKeyExpired.js +96 -0
- package/lib/components/anonymous/AnonymousKeyTimer.d.ts +63 -0
- package/lib/components/anonymous/AnonymousKeyTimer.js +140 -0
- package/lib/components/anonymous/index.d.ts +7 -0
- package/lib/components/anonymous/index.js +15 -0
- package/lib/components/avatars/UserAvatar.d.ts +7 -1
- package/lib/components/avatars/UserAvatar.js +15 -1
- package/lib/components/billing/BillingEntitySelect.d.ts +6 -0
- package/lib/components/billing/BillingEntitySelect.js +49 -10
- package/lib/components/billing/eligibility.d.ts +22 -0
- package/lib/components/billing/eligibility.js +27 -0
- package/lib/components/billing/index.d.ts +1 -0
- package/lib/components/billing/index.js +1 -0
- package/lib/components/collaboration/LiveEditorCollaborators.d.ts +5 -0
- package/lib/components/collaboration/LiveEditorCollaborators.js +3 -1
- package/lib/components/display/DatalayerBox.d.ts +2 -3
- package/lib/components/display/DatalayerBox.js +1 -1
- package/lib/components/display/NavLink.js +3 -2
- package/lib/components/labels/StatusLabels.d.ts +2 -10
- package/lib/components/labels/StatusLabels.js +2 -26
- package/lib/components/principal/PrincipalAppearance.d.ts +21 -42
- package/lib/components/principal/PrincipalAppearance.js +232 -174
- package/lib/components/principal/PrincipalAvatar.d.ts +8 -1
- package/lib/components/principal/PrincipalAvatar.js +2 -2
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +8 -1
- package/lib/components/principal/PrincipalDetailsOverlay.js +2 -2
- package/lib/components/screencapture/Screencapture.js +46 -3
- package/lib/components/sharing/ShareAccessComponent.d.ts +45 -4
- package/lib/components/sharing/ShareAccessComponent.js +110 -78
- package/lib/components/sharing/SharingEditor.d.ts +5 -1
- package/lib/components/sharing/SharingEditor.js +9 -4
- package/lib/components/sharing/index.d.ts +1 -0
- package/lib/components/sharing/index.js +1 -0
- package/lib/components/sharing/sandboxSharing.d.ts +26 -0
- package/lib/components/sharing/sandboxSharing.js +41 -0
- package/lib/components/spaces/SpaceDetailsOverlay.d.ts +39 -0
- package/lib/components/spaces/SpaceDetailsOverlay.js +80 -0
- package/lib/components/spaces/SpaceDisplay.d.ts +38 -0
- package/lib/components/spaces/SpaceDisplay.js +92 -0
- package/lib/components/spaces/index.d.ts +4 -0
- package/lib/components/spaces/index.js +7 -0
- package/lib/components/spaces/spaceDisplayModel.d.ts +93 -0
- package/lib/components/spaces/spaceDisplayModel.js +170 -0
- package/lib/hooks/cacheConverters.d.ts +0 -7
- package/lib/hooks/cacheConverters.js +0 -25
- package/lib/hooks/index.d.ts +1 -0
- package/lib/hooks/index.js +1 -0
- package/lib/hooks/useBillingEntityStore.js +3 -0
- package/lib/hooks/useCache.d.ts +168 -25
- package/lib/hooks/useCache.js +1424 -307
- package/lib/hooks/useContents.d.ts +22 -1
- package/lib/hooks/useContents.js +90 -21
- package/lib/hooks/useMcp.d.ts +87 -1
- package/lib/hooks/useMcp.js +247 -12
- package/lib/hooks/useNavigate.d.ts +41 -3
- package/lib/hooks/useNavigate.js +106 -52
- package/lib/hooks/usePrincipalCacheStore.js +3 -0
- package/lib/hooks/usePrincipalStore.js +3 -0
- package/lib/hooks/useSpaceCacheStore.d.ts +50 -0
- package/lib/hooks/useSpaceCacheStore.js +85 -0
- package/lib/models/CreditsDTO.d.ts +6 -5
- package/lib/models/CreditsDTO.js +7 -5
- package/lib/models/McpBinding.d.ts +6 -0
- package/lib/models/Organization.d.ts +69 -0
- package/lib/models/Organization.js +96 -0
- package/lib/models/Secret.d.ts +1 -2
- package/lib/models/Secret.js +2 -18
- package/lib/models/StartedBy.d.ts +34 -0
- package/lib/models/StartedBy.js +36 -0
- package/lib/models/Team.d.ts +2 -0
- package/lib/models/Team.js +2 -0
- package/lib/models/User.d.ts +4 -0
- package/lib/models/User.js +3 -0
- package/lib/models/UserSettings.d.ts +13 -0
- package/lib/models/UserSettings.js +9 -0
- package/lib/models/contents/__fixtures__/v1-contracts.json +158 -30
- package/lib/navigation/components.js +2 -3
- package/lib/routes/publicPaths.js +4 -0
- package/lib/state/index.d.ts +1 -0
- package/lib/state/index.js +1 -0
- package/lib/state/sessionEnd.d.ts +55 -0
- package/lib/state/sessionEnd.js +162 -0
- package/lib/state/substates/CoreState.js +3 -3
- package/lib/state/substates/IAMState.js +7 -0
- package/lib/state/substates/LayoutState.js +12 -0
- package/lib/state/substates/ProfileState.d.ts +1 -0
- package/lib/state/substates/ProfileState.js +1 -0
- package/lib/utils/Lazy.d.ts +20 -0
- package/lib/utils/Lazy.js +32 -6
- package/lib/utils/Screencapture.js +3 -0
- package/lib/utils/WithSuspense.d.ts +11 -1
- package/lib/utils/WithSuspense.js +11 -1
- package/lib/views/mcp/AdmittedClients.d.ts +44 -0
- package/lib/views/mcp/AdmittedClients.js +59 -0
- package/lib/views/mcp/ApprovalQueue.d.ts +66 -0
- package/lib/views/mcp/ApprovalQueue.js +95 -0
- package/lib/views/mcp/ConnectedAgents.js +38 -3
- package/lib/views/mcp/EnterpriseConsole.d.ts +1 -1
- package/lib/views/mcp/EnterpriseConsole.js +23 -1
- package/lib/views/mcp/IdentityProviders.d.ts +33 -0
- package/lib/views/mcp/IdentityProviders.js +299 -0
- package/lib/views/mcp/McpDashboard.js +90 -7
- package/lib/views/mcp/McpObservability.d.ts +30 -1
- package/lib/views/mcp/McpObservability.js +105 -19
- package/lib/views/mcp/NotebookRuns.d.ts +39 -0
- package/lib/views/mcp/NotebookRuns.js +44 -0
- package/lib/views/mcp/OrganizationPolicy.js +2 -1
- package/lib/views/mcp/PersonalPolicy.js +2 -1
- package/lib/views/mcp/PolicyForm.d.ts +17 -1
- package/lib/views/mcp/PolicyForm.js +25 -3
- package/lib/views/mcp/PolicyHistory.d.ts +13 -0
- package/lib/views/mcp/PolicyHistory.js +14 -1
- package/lib/views/mcp/RunDetail.d.ts +87 -0
- package/lib/views/mcp/RunDetail.js +186 -0
- package/lib/views/mcp/ScimProvisioning.d.ts +54 -0
- package/lib/views/mcp/ScimProvisioning.js +173 -0
- package/lib/views/mcp/TeamPolicies.js +66 -5
- package/lib/views/mcp/ToolAccess.d.ts +60 -0
- package/lib/views/mcp/ToolAccess.js +101 -0
- package/lib/views/mcp/TraceTimeline.d.ts +81 -0
- package/lib/views/mcp/TraceTimeline.js +132 -0
- package/lib/views/mcp/index.d.ts +5 -0
- package/lib/views/mcp/index.js +5 -0
- package/lib/views/otel/simpleAuthStore.js +3 -0
- package/lib/views/secrets/SecretEdit.js +3 -2
- package/lib/views/secrets/SecretNew.js +5 -1
- package/package.json +269 -264
- package/scripts/generate-mcp-types.py +1 -1
- package/scripts/generate-orchestration-types.py +920 -0
|
@@ -37,3 +37,32 @@ export declare const disconnectAgent: (token: string, grantUid: string, baseUrl?
|
|
|
37
37
|
success: boolean;
|
|
38
38
|
message?: string;
|
|
39
39
|
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Disconnect every agent this person has connected — sign out everywhere.
|
|
42
|
+
*
|
|
43
|
+
* **This is also how a forced re-consent is done.** A grant *is* the consent,
|
|
44
|
+
* so ending them all sends the next authorization through the consent screen
|
|
45
|
+
* rather than letting it be answered from what was agreed before; there is no
|
|
46
|
+
* separate "ask again" flag to keep in step with this one.
|
|
47
|
+
*
|
|
48
|
+
* Always the caller's own. A person cannot end somebody else's sessions here
|
|
49
|
+
* — an organization taking back what it granted is deprovisioning, which runs
|
|
50
|
+
* when a membership ends.
|
|
51
|
+
*/
|
|
52
|
+
export declare const disconnectEveryAgent: (token: string, baseUrl?: string) => Promise<{
|
|
53
|
+
success: boolean;
|
|
54
|
+
revoked: number;
|
|
55
|
+
message?: string;
|
|
56
|
+
}>;
|
|
57
|
+
/**
|
|
58
|
+
* Disconnect every agent connected while acting for one team.
|
|
59
|
+
*
|
|
60
|
+
* For the people who may manage that team: ending a team's sessions is the
|
|
61
|
+
* same kind of authority as removing somebody from it. It never touches a
|
|
62
|
+
* personal agent or another team's — the same narrowness deprovisioning has.
|
|
63
|
+
*/
|
|
64
|
+
export declare const disconnectEveryAgentInTeam: (token: string, teamUid: string, baseUrl?: string) => Promise<{
|
|
65
|
+
success: boolean;
|
|
66
|
+
revoked: number;
|
|
67
|
+
message?: string;
|
|
68
|
+
}>;
|
|
@@ -50,3 +50,38 @@ export const disconnectAgent = async (token, grantUid, baseUrl = DEFAULT_SERVICE
|
|
|
50
50
|
method: 'DELETE',
|
|
51
51
|
token,
|
|
52
52
|
});
|
|
53
|
+
/**
|
|
54
|
+
* Disconnect every agent this person has connected — sign out everywhere.
|
|
55
|
+
*
|
|
56
|
+
* **This is also how a forced re-consent is done.** A grant *is* the consent,
|
|
57
|
+
* so ending them all sends the next authorization through the consent screen
|
|
58
|
+
* rather than letting it be answered from what was agreed before; there is no
|
|
59
|
+
* separate "ask again" flag to keep in step with this one.
|
|
60
|
+
*
|
|
61
|
+
* Always the caller's own. A person cannot end somebody else's sessions here
|
|
62
|
+
* — an organization taking back what it granted is deprovisioning, which runs
|
|
63
|
+
* when a membership ends.
|
|
64
|
+
*/
|
|
65
|
+
export const disconnectEveryAgent = async (token, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
66
|
+
const response = await requestDatalayerAPI({
|
|
67
|
+
url: connectedAgentsUrl(baseUrl),
|
|
68
|
+
method: 'DELETE',
|
|
69
|
+
token,
|
|
70
|
+
});
|
|
71
|
+
return { ...response, revoked: response.revoked ?? 0 };
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Disconnect every agent connected while acting for one team.
|
|
75
|
+
*
|
|
76
|
+
* For the people who may manage that team: ending a team's sessions is the
|
|
77
|
+
* same kind of authority as removing somebody from it. It never touches a
|
|
78
|
+
* personal agent or another team's — the same narrowness deprovisioning has.
|
|
79
|
+
*/
|
|
80
|
+
export const disconnectEveryAgentInTeam = async (token, teamUid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
81
|
+
const response = await requestDatalayerAPI({
|
|
82
|
+
url: `${baseUrl}${API_BASE_PATHS.IAM}/oauth/teams/${encodeURIComponent(teamUid)}/connected-agents`,
|
|
83
|
+
method: 'DELETE',
|
|
84
|
+
token,
|
|
85
|
+
});
|
|
86
|
+
return { ...response, revoked: response.revoked ?? 0 };
|
|
87
|
+
};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** A role a group mapping may grant, at the organization or at a team. */
|
|
2
|
+
export declare const ORGANIZATION_ROLES: readonly ["organization_owner", "organization_security_auditor", "organization_user_reviewer", "organization_member"];
|
|
3
|
+
export declare const TEAM_ROLES: readonly ["team_owner", "team_member"];
|
|
4
|
+
export type OrganizationRole = (typeof ORGANIZATION_ROLES)[number];
|
|
5
|
+
export type TeamRole = (typeof TEAM_ROLES)[number];
|
|
6
|
+
/** One `groups` claim mapped onto one role, at the organization or a team. */
|
|
7
|
+
export interface RoleMapping {
|
|
8
|
+
/** The group, exactly as the token names it. */
|
|
9
|
+
group: string;
|
|
10
|
+
role: OrganizationRole | TeamRole;
|
|
11
|
+
/** Which team, when `role` is a team role; empty for an organization role. */
|
|
12
|
+
teamUid: string;
|
|
13
|
+
}
|
|
14
|
+
export interface IdentityProvider {
|
|
15
|
+
uid: string;
|
|
16
|
+
orgUid: string;
|
|
17
|
+
name: string;
|
|
18
|
+
protocol: 'oidc';
|
|
19
|
+
issuer: string;
|
|
20
|
+
clientId: string;
|
|
21
|
+
/** The *name* of a secret in this organization's store — never the secret. */
|
|
22
|
+
clientSecretRef: string;
|
|
23
|
+
/** Domains this provider claims. Claiming is free; see `verifiedDomains`. */
|
|
24
|
+
domains: string[];
|
|
25
|
+
/** The claimed domains proved by DNS. Only these route a sign-in. */
|
|
26
|
+
verifiedDomains: string[];
|
|
27
|
+
groupClaim: string;
|
|
28
|
+
/** Whether a sign-in may adopt a Datalayer account that already exists
|
|
29
|
+
* with the asserted address, rather than being refused. Off by default:
|
|
30
|
+
* see the module and provisioning notes for why. */
|
|
31
|
+
allowEmailLinking: boolean;
|
|
32
|
+
roleMappings: RoleMapping[];
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
createdBy?: string;
|
|
35
|
+
createdAt?: string;
|
|
36
|
+
updatedAt?: string;
|
|
37
|
+
version?: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A provider as it is written. Everything but what the route already names
|
|
41
|
+
* and `verifiedDomains` — which is never sent, only ever read: it is set
|
|
42
|
+
* exclusively by `verifyDomain` checking DNS, and a draft that could set it
|
|
43
|
+
* directly would be a way to claim verification without proving anything.
|
|
44
|
+
*/
|
|
45
|
+
export type IdentityProviderDraft = Omit<IdentityProvider, 'uid' | 'orgUid' | 'verifiedDomains' | 'createdBy' | 'createdAt' | 'updatedAt' | 'version'>;
|
|
46
|
+
export interface DomainVerification {
|
|
47
|
+
host: string;
|
|
48
|
+
type: 'TXT';
|
|
49
|
+
value: string;
|
|
50
|
+
}
|
|
51
|
+
/** Raised when the registry refused a provider as written — a bad issuer, an
|
|
52
|
+
* unowned domain, an unknown role in a mapping. The message is IAM's own. */
|
|
53
|
+
export declare class IdentityProviderInvalid extends Error {
|
|
54
|
+
constructor(message: string);
|
|
55
|
+
}
|
|
56
|
+
export declare const listIdentityProviders: (token: string, orgUid: string, baseUrl?: string) => Promise<IdentityProvider[]>;
|
|
57
|
+
export declare const getIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<IdentityProvider>;
|
|
58
|
+
export declare const createIdentityProvider: (token: string, orgUid: string, provider: IdentityProviderDraft, baseUrl?: string) => Promise<IdentityProvider>;
|
|
59
|
+
export declare const updateIdentityProvider: (token: string, orgUid: string, uid: string, provider: IdentityProviderDraft, baseUrl?: string) => Promise<IdentityProvider>;
|
|
60
|
+
export declare const enableIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<IdentityProvider>;
|
|
61
|
+
export declare const disableIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<IdentityProvider>;
|
|
62
|
+
/** Remove a registration outright. Prefer disabling one that has been used:
|
|
63
|
+
* this keeps no trace for the sign-in rows that name it. */
|
|
64
|
+
export declare const deleteIdentityProvider: (token: string, orgUid: string, uid: string, baseUrl?: string) => Promise<void>;
|
|
65
|
+
/** What to publish in DNS to prove this organization holds `domain`. */
|
|
66
|
+
export declare const getDomainVerification: (token: string, orgUid: string, uid: string, domain: string, baseUrl?: string) => Promise<{
|
|
67
|
+
verification: DomainVerification;
|
|
68
|
+
verified: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
/**
|
|
71
|
+
* Check DNS now and, if the record is there, make the domain route sign-in.
|
|
72
|
+
*
|
|
73
|
+
* Until this succeeds the domain routes nothing at all, whatever was typed
|
|
74
|
+
* when the provider was registered.
|
|
75
|
+
*/
|
|
76
|
+
export declare const verifyDomain: (token: string, orgUid: string, uid: string, domain: string, baseUrl?: string) => Promise<IdentityProvider>;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/*
|
|
6
|
+
* Copyright (c) 2023-2026 Datalayer, Inc.
|
|
7
|
+
* Distributed under the terms of the Modified BSD License.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* An organization's own identity provider.
|
|
11
|
+
*
|
|
12
|
+
* Enterprise sign-in used to be one Okta for the whole deployment. This is
|
|
13
|
+
* the registry that replaces it: an organization registers an OIDC provider
|
|
14
|
+
* — issuer, client id, the email domains it claims — and a sign-in is routed
|
|
15
|
+
* to it by domain.
|
|
16
|
+
*
|
|
17
|
+
* **A claim is not proof.** Registering a domain here does not route
|
|
18
|
+
* anything: only a domain proved by a DNS TXT record does, because a domain
|
|
19
|
+
* that only had to be typed would let one organization receive another's
|
|
20
|
+
* sign-ins. `getDomainVerification` reads what to publish; `verifyDomain`
|
|
21
|
+
* checks it and is the only call that turns a claim into a route.
|
|
22
|
+
*
|
|
23
|
+
* **The client secret never appears here.** The record names a secret in the
|
|
24
|
+
* organization's own secret store (`clientSecretRef`); this client never
|
|
25
|
+
* reads or writes a secret's value.
|
|
26
|
+
*
|
|
27
|
+
* @module api/iam/identityProviders
|
|
28
|
+
*/
|
|
29
|
+
import { requestDatalayerAPI } from '../DatalayerApi.js';
|
|
30
|
+
import { API_BASE_PATHS, DEFAULT_SERVICE_URLS } from '../constants.js';
|
|
31
|
+
/** A role a group mapping may grant, at the organization or at a team. */
|
|
32
|
+
export const ORGANIZATION_ROLES = [
|
|
33
|
+
'organization_owner',
|
|
34
|
+
'organization_security_auditor',
|
|
35
|
+
'organization_user_reviewer',
|
|
36
|
+
'organization_member',
|
|
37
|
+
];
|
|
38
|
+
export const TEAM_ROLES = ['team_owner', 'team_member'];
|
|
39
|
+
const roleMappingFromWire = (mapping) => ({
|
|
40
|
+
group: mapping.group ?? '',
|
|
41
|
+
role: mapping.role ?? 'organization_member',
|
|
42
|
+
teamUid: mapping.team_uid ?? '',
|
|
43
|
+
});
|
|
44
|
+
const roleMappingToWire = (mapping) => ({
|
|
45
|
+
group: mapping.group,
|
|
46
|
+
role: mapping.role,
|
|
47
|
+
team_uid: mapping.teamUid,
|
|
48
|
+
});
|
|
49
|
+
const fromWire = (provider) => ({
|
|
50
|
+
uid: provider.uid,
|
|
51
|
+
orgUid: provider.org_uid ?? '',
|
|
52
|
+
name: provider.name ?? '',
|
|
53
|
+
protocol: 'oidc',
|
|
54
|
+
issuer: provider.issuer ?? '',
|
|
55
|
+
clientId: provider.client_id ?? '',
|
|
56
|
+
clientSecretRef: provider.client_secret_ref ?? '',
|
|
57
|
+
domains: provider.domains ?? [],
|
|
58
|
+
verifiedDomains: provider.verified_domains ?? [],
|
|
59
|
+
groupClaim: provider.group_claim ?? 'groups',
|
|
60
|
+
allowEmailLinking: provider.allow_email_linking ?? false,
|
|
61
|
+
roleMappings: (provider.role_mappings ?? []).map(roleMappingFromWire),
|
|
62
|
+
enabled: provider.enabled ?? true,
|
|
63
|
+
createdBy: provider.created_by ?? undefined,
|
|
64
|
+
createdAt: provider.created_at ?? undefined,
|
|
65
|
+
updatedAt: provider.updated_at ?? undefined,
|
|
66
|
+
version: provider.version ?? undefined,
|
|
67
|
+
});
|
|
68
|
+
const toWire = (provider) => ({
|
|
69
|
+
name: provider.name,
|
|
70
|
+
protocol: provider.protocol,
|
|
71
|
+
issuer: provider.issuer,
|
|
72
|
+
client_id: provider.clientId,
|
|
73
|
+
client_secret_ref: provider.clientSecretRef,
|
|
74
|
+
domains: provider.domains,
|
|
75
|
+
group_claim: provider.groupClaim,
|
|
76
|
+
allow_email_linking: provider.allowEmailLinking,
|
|
77
|
+
role_mappings: provider.roleMappings.map(roleMappingToWire),
|
|
78
|
+
enabled: provider.enabled,
|
|
79
|
+
});
|
|
80
|
+
/** Raised when the registry refused a provider as written — a bad issuer, an
|
|
81
|
+
* unowned domain, an unknown role in a mapping. The message is IAM's own. */
|
|
82
|
+
export class IdentityProviderInvalid extends Error {
|
|
83
|
+
constructor(message) {
|
|
84
|
+
super(message);
|
|
85
|
+
this.name = 'IdentityProviderInvalid';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const providersUrl = (baseUrl, orgUid, suffix = '') => `${baseUrl}${API_BASE_PATHS.IAM}/organizations/${encodeURIComponent(orgUid)}/identity-providers${suffix}`;
|
|
89
|
+
export const listIdentityProviders = async (token, orgUid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
90
|
+
const response = await requestDatalayerAPI({
|
|
91
|
+
url: providersUrl(baseUrl, orgUid),
|
|
92
|
+
method: 'GET',
|
|
93
|
+
token,
|
|
94
|
+
});
|
|
95
|
+
return (response.providers ?? []).map(fromWire);
|
|
96
|
+
};
|
|
97
|
+
export const getIdentityProvider = async (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
98
|
+
const response = await requestDatalayerAPI({
|
|
99
|
+
url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}`),
|
|
100
|
+
method: 'GET',
|
|
101
|
+
token,
|
|
102
|
+
});
|
|
103
|
+
return fromWire(response.provider ?? { uid });
|
|
104
|
+
};
|
|
105
|
+
export const createIdentityProvider = async (token, orgUid, provider, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
106
|
+
const response = await withRefusal(() => requestDatalayerAPI({
|
|
107
|
+
url: providersUrl(baseUrl, orgUid),
|
|
108
|
+
method: 'POST',
|
|
109
|
+
token,
|
|
110
|
+
body: toWire(provider),
|
|
111
|
+
}));
|
|
112
|
+
return fromWire(response.provider ?? { uid: '' });
|
|
113
|
+
};
|
|
114
|
+
export const updateIdentityProvider = async (token, orgUid, uid, provider, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
115
|
+
const response = await withRefusal(() => requestDatalayerAPI({
|
|
116
|
+
url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}`),
|
|
117
|
+
method: 'PUT',
|
|
118
|
+
token,
|
|
119
|
+
body: toWire(provider),
|
|
120
|
+
}));
|
|
121
|
+
return fromWire(response.provider ?? { uid });
|
|
122
|
+
};
|
|
123
|
+
const setEnabled = async (token, orgUid, uid, enabled, baseUrl) => {
|
|
124
|
+
const response = await requestDatalayerAPI({
|
|
125
|
+
url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}/${enabled ? 'enable' : 'disable'}`),
|
|
126
|
+
method: 'POST',
|
|
127
|
+
token,
|
|
128
|
+
});
|
|
129
|
+
return fromWire(response.provider ?? { uid });
|
|
130
|
+
};
|
|
131
|
+
export const enableIdentityProvider = (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => setEnabled(token, orgUid, uid, true, baseUrl);
|
|
132
|
+
export const disableIdentityProvider = (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => setEnabled(token, orgUid, uid, false, baseUrl);
|
|
133
|
+
/** Remove a registration outright. Prefer disabling one that has been used:
|
|
134
|
+
* this keeps no trace for the sign-in rows that name it. */
|
|
135
|
+
export const deleteIdentityProvider = async (token, orgUid, uid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
136
|
+
await requestDatalayerAPI({
|
|
137
|
+
url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}`),
|
|
138
|
+
method: 'DELETE',
|
|
139
|
+
token,
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
/** What to publish in DNS to prove this organization holds `domain`. */
|
|
143
|
+
export const getDomainVerification = async (token, orgUid, uid, domain, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
144
|
+
const response = await requestDatalayerAPI({
|
|
145
|
+
url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}/domains/${encodeURIComponent(domain)}/verification`),
|
|
146
|
+
method: 'GET',
|
|
147
|
+
token,
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
verification: response.verification ?? { host: '', type: 'TXT', value: '' },
|
|
151
|
+
verified: response.verified ?? false,
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Check DNS now and, if the record is there, make the domain route sign-in.
|
|
156
|
+
*
|
|
157
|
+
* Until this succeeds the domain routes nothing at all, whatever was typed
|
|
158
|
+
* when the provider was registered.
|
|
159
|
+
*/
|
|
160
|
+
export const verifyDomain = async (token, orgUid, uid, domain, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
161
|
+
const response = await withRefusal(() => requestDatalayerAPI({
|
|
162
|
+
url: providersUrl(baseUrl, orgUid, `/${encodeURIComponent(uid)}/domains/${encodeURIComponent(domain)}/verify`),
|
|
163
|
+
method: 'POST',
|
|
164
|
+
token,
|
|
165
|
+
}));
|
|
166
|
+
return fromWire(response.provider ?? { uid });
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* Turn IAM's `400` into one the form can show beside the field.
|
|
170
|
+
*
|
|
171
|
+
* A `400` here is never a bug in the client: it is the registry saying it
|
|
172
|
+
* refused what was written, and its message names why — an `http` issuer, a
|
|
173
|
+
* domain somebody else already verified, an unknown role in a mapping.
|
|
174
|
+
*/
|
|
175
|
+
const withRefusal = async (call) => {
|
|
176
|
+
try {
|
|
177
|
+
return await call();
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
const candidate = error;
|
|
181
|
+
const status = candidate?.status ?? candidate?.response?.status;
|
|
182
|
+
if (status === 400) {
|
|
183
|
+
throw new IdentityProviderInvalid(candidate.message || 'This identity provider was refused.');
|
|
184
|
+
}
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
};
|
package/lib/api/iam/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * as healthz from './healthz';
|
|
|
12
12
|
export * as usage from './usage';
|
|
13
13
|
export * as secrets from './secrets';
|
|
14
14
|
export * as connectedAgents from './connectedAgents';
|
|
15
|
+
export * as trials from './trials';
|
|
15
16
|
export { login, logout, checkAuth } from './authentication';
|
|
16
17
|
export { getOAuth2AuthzUrl, getOAuth2AuthzUrlForLink, handleGitHubOAuth2Callback, handleLinkedInOAuth2Callback, handleOktaOAuth2Callback, type OAuth2Provider, type OAuth2AuthzUrlResponse, type OAuth2CallbackParams, type OAuth2CallbackResponse, } from './oauth2';
|
|
17
18
|
export { me, whoami } from './profile';
|
package/lib/api/iam/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export * as healthz from './healthz.js';
|
|
|
16
16
|
export * as usage from './usage.js';
|
|
17
17
|
export * as secrets from './secrets.js';
|
|
18
18
|
export * as connectedAgents from './connectedAgents.js';
|
|
19
|
+
export * as trials from './trials.js';
|
|
19
20
|
// For backward compatibility, export the old API structure
|
|
20
21
|
export { login, logout, checkAuth } from './authentication.js';
|
|
21
22
|
export { getOAuth2AuthzUrl, getOAuth2AuthzUrlForLink, handleGitHubOAuth2Callback, handleLinkedInOAuth2Callback, handleOktaOAuth2Callback, } from './oauth2.js';
|
|
@@ -34,6 +34,55 @@ export interface McpPolicyRules {
|
|
|
34
34
|
maxCreditsPerDay?: number;
|
|
35
35
|
/** Sandboxes at once. Counted per scope — a team's counts the team's. */
|
|
36
36
|
maxConcurrentSandboxes?: number;
|
|
37
|
+
/**
|
|
38
|
+
* GPU-hours over the last 30 days. Refuses a launch on a **GPU**
|
|
39
|
+
* environment; a CPU sandbox is unaffected.
|
|
40
|
+
*
|
|
41
|
+
* Not expressible as credits: the credits a GPU hour costs differ per
|
|
42
|
+
* environment, so neither number can be derived from the other.
|
|
43
|
+
*
|
|
44
|
+
* A trailing 30 days, not a calendar month — a limit that resets on the
|
|
45
|
+
* 1st can be spent twice inside 48 hours, once each side of the reset.
|
|
46
|
+
* And it counts **every** GPU-hour billed to the scope, agents' or not:
|
|
47
|
+
* the agent dimension lives on a child document in the ledger and cannot
|
|
48
|
+
* be a clause of the sum. A form must say both.
|
|
49
|
+
*/
|
|
50
|
+
gpuHoursPerMonth?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Bytes stored. Refuses **every** launch when reached, not only one that
|
|
53
|
+
* attaches content — every sandbox can write, so unlike the GPU-hour limit
|
|
54
|
+
* there is nothing to condition on.
|
|
55
|
+
*
|
|
56
|
+
* In **bytes**, not gigabytes. A number whose unit is implied is one
|
|
57
|
+
* somebody eventually reads as the other, and this is compared against a
|
|
58
|
+
* figure Contents reports in bytes; a form converts for the reader.
|
|
59
|
+
*
|
|
60
|
+
* Counted over every live object *version* rather than every object: an
|
|
61
|
+
* object's recorded size is its current version's, and a scope keeping a
|
|
62
|
+
* hundred versions of a one-gigabyte file stores a hundred gigabytes.
|
|
63
|
+
*/
|
|
64
|
+
storageBytes?: number;
|
|
65
|
+
/**
|
|
66
|
+
* How long a connection may go on being refreshed before the person signs
|
|
67
|
+
* in and consents again. Hours, because that is the unit it is set in.
|
|
68
|
+
*
|
|
69
|
+
* Enforced by **IAM**, at its token endpoint, rather than by the gateway:
|
|
70
|
+
* a session's age is a fact about the grant, and the grant is IAM's. The
|
|
71
|
+
* gateway never sees it.
|
|
72
|
+
*/
|
|
73
|
+
sessionMaxHours?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Whether this organization's own identity provider may stand in for the
|
|
76
|
+
* consent screen, for a client it already admits.
|
|
77
|
+
*
|
|
78
|
+
* Narrow by construction, and off unless turned on: it applies only to a
|
|
79
|
+
* session that came through one of this organization's own enabled
|
|
80
|
+
* providers, only for a client named on `allowedClients`, and only when
|
|
81
|
+
* that list is not empty. Every other session still sees the screen.
|
|
82
|
+
*
|
|
83
|
+
* Not "require SSO": it does not stop anybody signing in another way.
|
|
84
|
+
*/
|
|
85
|
+
ssoAdmitsWithoutConsent?: boolean;
|
|
37
86
|
}
|
|
38
87
|
/** A stored layer, with the version a write must carry back. */
|
|
39
88
|
export interface McpPolicy extends McpPolicyRules {
|
|
@@ -52,7 +101,7 @@ export interface McpPolicy extends McpPolicyRules {
|
|
|
52
101
|
* rendered here and unknown to IAM is refused at the write, which reads to
|
|
53
102
|
* the person filling it in as the page being broken.
|
|
54
103
|
*/
|
|
55
|
-
export declare const MCP_POLICY_RULES: readonly ["toolDenylist", "toolAllowlist", "allowedClients", "maxCallsPerMinute", "maxCreditsPerDay", "maxConcurrentSandboxes"];
|
|
104
|
+
export declare const MCP_POLICY_RULES: readonly ["toolDenylist", "toolAllowlist", "allowedClients", "maxCallsPerMinute", "maxCreditsPerDay", "maxConcurrentSandboxes", "gpuHoursPerMonth", "storageBytes", "sessionMaxHours", "ssoAdmitsWithoutConsent"];
|
|
56
105
|
/** Raised when the policy changed between the read and the write. */
|
|
57
106
|
export declare class McpPolicyConflict extends Error {
|
|
58
107
|
constructor(message: string);
|
|
@@ -78,3 +127,55 @@ export declare const setMcpPolicy: (token: string, scope: McpPolicyScope, subjec
|
|
|
78
127
|
}, baseUrl?: string) => Promise<McpPolicy>;
|
|
79
128
|
/** Remove one layer, so it narrows nothing again. */
|
|
80
129
|
export declare const deleteMcpPolicy: (token: string, scope: McpPolicyScope, subjectUid: string, baseUrl?: string) => Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* One `allowedClients` entry, as the server can describe it.
|
|
132
|
+
*
|
|
133
|
+
* Three states, kept apart deliberately — collapsing any two of them is the
|
|
134
|
+
* mistake this shape exists to prevent.
|
|
135
|
+
*/
|
|
136
|
+
export interface AdmittedClient {
|
|
137
|
+
/** Exactly as it is stored, so somebody can find the line they typed. */
|
|
138
|
+
entry: string;
|
|
139
|
+
/**
|
|
140
|
+
* `hostname` admits every client that host publishes and has no document
|
|
141
|
+
* to read. `url` names one client document. `unusable` matches nothing —
|
|
142
|
+
* almost always a URL pasted without its scheme.
|
|
143
|
+
*/
|
|
144
|
+
kind: 'hostname' | 'url' | 'unusable';
|
|
145
|
+
hostname?: string;
|
|
146
|
+
/**
|
|
147
|
+
* Only for `url`. `false` means the document could not be read, which is
|
|
148
|
+
* an entry that silently admits nobody — and reads to the vendor whose
|
|
149
|
+
* agent is refused as a deliberate decision.
|
|
150
|
+
*/
|
|
151
|
+
resolved?: boolean;
|
|
152
|
+
clientName?: string;
|
|
153
|
+
clientHostname?: string;
|
|
154
|
+
clientUri?: string;
|
|
155
|
+
/** Every redirect goes to the reader's own machine. */
|
|
156
|
+
localhostOnly?: boolean;
|
|
157
|
+
/** Why it cannot be read, or what a hostname entry admits. */
|
|
158
|
+
detail?: string;
|
|
159
|
+
}
|
|
160
|
+
export interface AdmittedClients {
|
|
161
|
+
/**
|
|
162
|
+
* Whether this layer names an allowlist **at all**.
|
|
163
|
+
*
|
|
164
|
+
* `false` for an absent or empty list, and it is not a detail: an empty
|
|
165
|
+
* list is not an allowlist, and the gateway admits every client through a
|
|
166
|
+
* layer that has not filled one in. A page rendering "0 clients admitted"
|
|
167
|
+
* over `false` would state the opposite of what is enforced.
|
|
168
|
+
*/
|
|
169
|
+
allowlisted: boolean;
|
|
170
|
+
clients: AdmittedClient[];
|
|
171
|
+
detail?: string;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* What this layer's admitted-client entries actually name.
|
|
175
|
+
*
|
|
176
|
+
* Its own call rather than part of `getMcpPolicy`, because that one is what
|
|
177
|
+
* the gateway reads on every uncached tool call and this may fetch a client
|
|
178
|
+
* document per entry — which is exactly what must never happen on the
|
|
179
|
+
* enforcement path.
|
|
180
|
+
*/
|
|
181
|
+
export declare const getAdmittedClients: (token: string, scope: McpPolicyScope, subjectUid: string, baseUrl?: string) => Promise<AdmittedClients>;
|
package/lib/api/iam/mcpPolicy.js
CHANGED
|
@@ -52,6 +52,10 @@ export const MCP_POLICY_RULES = [
|
|
|
52
52
|
'maxCallsPerMinute',
|
|
53
53
|
'maxCreditsPerDay',
|
|
54
54
|
'maxConcurrentSandboxes',
|
|
55
|
+
'gpuHoursPerMonth',
|
|
56
|
+
'storageBytes',
|
|
57
|
+
'sessionMaxHours',
|
|
58
|
+
'ssoAdmitsWithoutConsent',
|
|
55
59
|
];
|
|
56
60
|
/** Raised when the policy changed between the read and the write. */
|
|
57
61
|
export class McpPolicyConflict extends Error {
|
|
@@ -60,8 +64,9 @@ export class McpPolicyConflict extends Error {
|
|
|
60
64
|
this.name = 'McpPolicyConflict';
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
/** `suffix` is appended verbatim: a query string, or a further path segment. */
|
|
68
|
+
const policyUrl = (baseUrl, scope, subjectUid, suffix = '') => `${baseUrl}${API_BASE_PATHS.IAM}/mcp-policies/${encodeURIComponent(scope)}` +
|
|
69
|
+
`/${encodeURIComponent(subjectUid)}${suffix}`;
|
|
65
70
|
/**
|
|
66
71
|
* One layer's rules, or `null` where nobody has written it.
|
|
67
72
|
*
|
|
@@ -130,3 +135,34 @@ const statusOf = (error) => {
|
|
|
130
135
|
};
|
|
131
136
|
const isNotFound = (error) => statusOf(error) === 404;
|
|
132
137
|
const isConflict = (error) => statusOf(error) === 409;
|
|
138
|
+
const admittedFromWire = (wire) => ({
|
|
139
|
+
entry: wire.entry ?? '',
|
|
140
|
+
kind: wire.kind === 'hostname' || wire.kind === 'url' ? wire.kind : 'unusable',
|
|
141
|
+
hostname: wire.hostname || undefined,
|
|
142
|
+
resolved: wire.resolved,
|
|
143
|
+
clientName: wire.client_name || undefined,
|
|
144
|
+
clientHostname: wire.client_hostname || undefined,
|
|
145
|
+
clientUri: wire.client_uri || undefined,
|
|
146
|
+
localhostOnly: wire.localhost_only,
|
|
147
|
+
detail: wire.detail || undefined,
|
|
148
|
+
});
|
|
149
|
+
/**
|
|
150
|
+
* What this layer's admitted-client entries actually name.
|
|
151
|
+
*
|
|
152
|
+
* Its own call rather than part of `getMcpPolicy`, because that one is what
|
|
153
|
+
* the gateway reads on every uncached tool call and this may fetch a client
|
|
154
|
+
* document per entry — which is exactly what must never happen on the
|
|
155
|
+
* enforcement path.
|
|
156
|
+
*/
|
|
157
|
+
export const getAdmittedClients = async (token, scope, subjectUid, baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
158
|
+
const response = await requestDatalayerAPI({
|
|
159
|
+
url: policyUrl(baseUrl, scope, subjectUid, '/admitted-clients'),
|
|
160
|
+
method: 'GET',
|
|
161
|
+
token,
|
|
162
|
+
});
|
|
163
|
+
return {
|
|
164
|
+
allowlisted: response.allowlisted === true,
|
|
165
|
+
clients: (response.clients ?? []).map(admittedFromWire),
|
|
166
|
+
detail: response.detail || undefined,
|
|
167
|
+
};
|
|
168
|
+
};
|
package/lib/api/iam/profile.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MembershipsResponse, ShareablePrincipalsResponse, UserMeResponse, WhoAmIResponse } from '../../models/IAM';
|
|
1
|
+
import { MembershipsResponse, PrincipalSearchResponse, PrincipalSearchUser, ShareablePrincipalsResponse, UserMeResponse, WhoAmIResponse } from '../../models/IAM';
|
|
2
2
|
/**
|
|
3
3
|
* Get current authenticated user profile
|
|
4
4
|
* @param token - Authentication token (required)
|
|
@@ -28,3 +28,19 @@ export declare const memberships: (token: string, baseUrl?: string) => Promise<M
|
|
|
28
28
|
* @param baseUrl - Base URL for the API (defaults to production IAM URL)
|
|
29
29
|
*/
|
|
30
30
|
export declare const principalsShareable: (token: string, baseUrl?: string) => Promise<ShareablePrincipalsResponse>;
|
|
31
|
+
/**
|
|
32
|
+
* Search the people, teams and organizations the caller may name: what the
|
|
33
|
+
* sharing dialogs search, and whom a comment mentions or assigns (B4-02).
|
|
34
|
+
*
|
|
35
|
+
* @param token - Authentication token (required)
|
|
36
|
+
* @param query - What is typed: part of a handle or of a name
|
|
37
|
+
* @param principalTypes - What to search; people only by default
|
|
38
|
+
* @param baseUrl - Base URL for the API (defaults to production IAM URL)
|
|
39
|
+
*/
|
|
40
|
+
export declare const searchPrincipals: (token: string, query: string, principalTypes?: Array<"user" | "team" | "organization">, baseUrl?: string) => Promise<PrincipalSearchResponse>;
|
|
41
|
+
/** A person `searchPrincipals` found, as a comment or a report names them. */
|
|
42
|
+
export declare const personOfPrincipalUser: (user: PrincipalSearchUser) => {
|
|
43
|
+
uid: string;
|
|
44
|
+
handle: string;
|
|
45
|
+
name: string | null;
|
|
46
|
+
};
|
package/lib/api/iam/profile.js
CHANGED
|
@@ -69,3 +69,30 @@ export const principalsShareable = async (token, baseUrl = DEFAULT_SERVICE_URLS.
|
|
|
69
69
|
token,
|
|
70
70
|
});
|
|
71
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* Search the people, teams and organizations the caller may name: what the
|
|
74
|
+
* sharing dialogs search, and whom a comment mentions or assigns (B4-02).
|
|
75
|
+
*
|
|
76
|
+
* @param token - Authentication token (required)
|
|
77
|
+
* @param query - What is typed: part of a handle or of a name
|
|
78
|
+
* @param principalTypes - What to search; people only by default
|
|
79
|
+
* @param baseUrl - Base URL for the API (defaults to production IAM URL)
|
|
80
|
+
*/
|
|
81
|
+
export const searchPrincipals = async (token, query, principalTypes = ['user'], baseUrl = DEFAULT_SERVICE_URLS.IAM) => {
|
|
82
|
+
validateToken(token);
|
|
83
|
+
return requestDatalayerAPI({
|
|
84
|
+
url: `${baseUrl}${API_BASE_PATHS.IAM}/principals/search`,
|
|
85
|
+
method: 'POST',
|
|
86
|
+
body: { query, principalTypes },
|
|
87
|
+
token,
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
/** A person `searchPrincipals` found, as a comment or a report names them. */
|
|
91
|
+
export const personOfPrincipalUser = (user) => ({
|
|
92
|
+
uid: user.uid,
|
|
93
|
+
handle: user.handle_s,
|
|
94
|
+
name: `${user.first_name_t ?? ''} ${user.last_name_t ?? ''}`.trim() ||
|
|
95
|
+
user.display_name_t ||
|
|
96
|
+
user.display_name ||
|
|
97
|
+
null,
|
|
98
|
+
});
|