@datalayer/agent-runtimes 0.0.5 → 0.0.8
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 +150 -22
- package/lib/components/chat/components/AgentDetails.d.ts +15 -2
- package/lib/components/chat/components/AgentDetails.js +9 -93
- package/lib/components/chat/components/AgentIdentity.d.ts +92 -0
- package/lib/components/chat/components/AgentIdentity.js +318 -0
- package/lib/components/chat/components/Chat.d.ts +24 -1
- package/lib/components/chat/components/Chat.js +41 -19
- package/lib/components/chat/components/ChatFloating.d.ts +6 -1
- package/lib/components/chat/components/ChatFloating.js +12 -6
- package/lib/components/chat/components/ContextDistribution.d.ts +47 -0
- package/lib/components/chat/components/ContextDistribution.js +146 -0
- package/lib/components/chat/components/ContextUsage.d.ts +33 -0
- package/lib/components/chat/components/ContextUsage.js +127 -0
- package/lib/components/chat/components/base/ChatBase.d.ts +51 -1
- package/lib/components/chat/components/base/ChatBase.js +278 -74
- package/lib/components/chat/components/display/ToolCallDisplay.d.ts +16 -2
- package/lib/components/chat/components/display/ToolCallDisplay.js +148 -6
- package/lib/components/chat/components/display/index.d.ts +1 -1
- package/lib/components/chat/components/display/index.js +1 -1
- package/lib/components/chat/components/elements/ChatInputPrompt.d.ts +12 -1
- package/lib/components/chat/components/elements/ChatInputPrompt.js +8 -3
- package/lib/components/chat/components/index.d.ts +3 -0
- package/lib/components/chat/components/index.js +3 -0
- package/lib/components/chat/components/parts/ToolPart.d.ts +1 -1
- package/lib/components/chat/components/parts/ToolPart.js +142 -6
- package/lib/components/chat/index.d.ts +1 -1
- package/lib/components/chat/index.js +1 -1
- package/lib/components/chat/protocols/A2AAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/A2AAdapter.js +13 -2
- package/lib/components/chat/protocols/ACPAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/ACPAdapter.js +13 -2
- package/lib/components/chat/protocols/AGUIAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/AGUIAdapter.js +19 -1
- package/lib/components/chat/protocols/VercelAIAdapter.d.ts +7 -0
- package/lib/components/chat/protocols/VercelAIAdapter.js +19 -0
- package/lib/components/chat/types/execution.d.ts +78 -0
- package/lib/components/chat/types/execution.js +64 -0
- package/lib/components/chat/types/index.d.ts +1 -0
- package/lib/components/chat/types/index.js +1 -0
- package/lib/components/chat/types/protocol.d.ts +9 -0
- package/lib/components/ui/pagination.d.ts +2 -2
- package/lib/components/ui/pagination.js +4 -4
- package/lib/components/ui/resizable.d.ts +4 -4
- package/lib/components/ui/resizable.js +4 -4
- package/lib/examples/A2UiRestaurantExample.js +2 -2
- package/lib/examples/AgUiAgenticExample.js +2 -2
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -2
- package/lib/examples/AgUiHaikuGenUIExample.js +2 -2
- package/lib/examples/AgUiHumanInTheLoopExample.js +2 -2
- package/lib/examples/AgUiSharedStateExample.js +2 -2
- package/lib/examples/AgUiToolsBasedGenUIExample.js +2 -2
- package/lib/examples/AgentRuntimeCustomExample.js +2 -2
- package/lib/examples/AgentRuntimeLexical2Example.js +2 -1
- package/lib/examples/AgentRuntimeLexicalExample.js +5 -2
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +4 -2
- package/lib/examples/AgentRuntimeNotebookExample.js +1 -1
- package/lib/examples/AgentRuntimeStandaloneExample.js +2 -2
- package/lib/examples/AgentSpaceFormExample.d.ts +70 -2
- package/lib/examples/AgentSpaceFormExample.js +204 -35
- package/lib/examples/CopilotKitLexicalExample.js +2 -1
- package/lib/examples/components/AgentConfiguration.d.ts +37 -0
- package/lib/examples/components/AgentConfiguration.js +239 -8
- package/lib/examples/components/Header.d.ts +0 -2
- package/lib/examples/components/Header.js +2 -16
- package/lib/examples/components/LexicalEditor.js +2 -1
- package/lib/examples/components/MockFileBrowser.js +6 -2
- package/lib/examples/components/index.d.ts +0 -1
- package/lib/examples/components/index.js +0 -1
- package/lib/examples/example-selector.js +0 -1
- package/lib/examples/index.d.ts +0 -1
- package/lib/examples/index.js +0 -1
- package/lib/examples/lexical/editorConfig.d.ts +3 -2
- package/lib/examples/lexical/editorConfig.js +7 -1
- package/lib/examples/lexical/initial-content.json +2210 -0
- package/lib/examples/main.js +15 -1
- package/lib/identity/IdentityConnect.d.ts +90 -0
- package/lib/identity/IdentityConnect.js +316 -0
- package/lib/identity/OAuthCallback.d.ts +58 -0
- package/lib/identity/OAuthCallback.js +223 -0
- package/lib/identity/dcr.d.ts +257 -0
- package/lib/identity/dcr.js +282 -0
- package/lib/identity/identityStore.d.ts +72 -0
- package/lib/identity/identityStore.js +529 -0
- package/lib/identity/index.d.ts +46 -0
- package/lib/identity/index.js +17 -0
- package/lib/identity/pkce.d.ts +30 -0
- package/lib/identity/pkce.js +65 -0
- package/lib/identity/types.d.ts +293 -0
- package/lib/identity/types.js +73 -0
- package/lib/identity/useIdentity.d.ts +108 -0
- package/lib/identity/useIdentity.js +323 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/lib/utils.js +1 -1
- package/lib/renderers/a2ui/lib/utils.js +1 -1
- package/lib/runtime/index.d.ts +35 -0
- package/lib/runtime/index.js +40 -0
- package/lib/runtime/runtimeStore.d.ts +77 -0
- package/lib/runtime/runtimeStore.js +184 -0
- package/lib/runtime/types.d.ts +84 -0
- package/lib/runtime/types.js +15 -0
- package/lib/runtime/useAgentConnection.d.ts +46 -0
- package/lib/runtime/useAgentConnection.js +112 -0
- package/lib/runtime/useAgentRuntime.d.ts +94 -0
- package/lib/runtime/useAgentRuntime.js +125 -0
- package/lib/test-setup.d.ts +1 -1
- package/lib/test-setup.js +1 -0
- package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.js +32 -1
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.d.ts +6 -0
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.js +16 -17
- package/package.json +20 -7
- package/patches/@datalayer+jupyter-lexical+1.0.8.patch +11628 -0
- package/patches/@datalayer+jupyter-react+2.0.2.patch +5338 -0
- package/lib/examples/AgentSpaceHomeExample.d.ts +0 -8
- package/lib/examples/AgentSpaceHomeExample.js +0 -171
- package/lib/examples/components/AgentsDataTable.d.ts +0 -13
- package/lib/examples/components/AgentsDataTable.js +0 -74
- package/lib/examples/components/Rating.d.ts +0 -14
- package/lib/examples/components/Rating.js +0 -12
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
7
|
+
import { Box, Text, Spinner, Flash, Button } from '@primer/react';
|
|
8
|
+
import { CheckCircleFillIcon, AlertIcon, XCircleIcon, } from '@primer/octicons-react';
|
|
9
|
+
import { useIdentityStore } from './identityStore';
|
|
10
|
+
/**
|
|
11
|
+
* OAuth callback handler component.
|
|
12
|
+
*
|
|
13
|
+
* This component should be rendered on the OAuth callback URL (e.g., /oauth/callback).
|
|
14
|
+
* It handles the authorization code exchange and token storage.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* // For redirect flow - mount at /oauth/callback
|
|
18
|
+
* <Route path="/oauth/callback" element={<OAuthCallback redirectUrl="/" />} />
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // For popup flow - mount at /oauth/callback
|
|
22
|
+
* <Route path="/oauth/callback" element={<OAuthCallback autoClose />} />
|
|
23
|
+
*/
|
|
24
|
+
export const OAuthCallback = ({ successMessage = 'Account connected successfully!', errorMessagePrefix = 'Failed to connect account', autoClose, autoCloseDelay = 1500, onSuccess, onError, redirectUrl, showCloseButton = true, }) => {
|
|
25
|
+
const [status, setStatus] = useState('processing');
|
|
26
|
+
const [error, setError] = useState(null);
|
|
27
|
+
const [provider, setProvider] = useState(null);
|
|
28
|
+
const [storeHydrated, setStoreHydrated] = useState(false);
|
|
29
|
+
const completeAuthorization = useIdentityStore(state => state.completeAuthorization);
|
|
30
|
+
const pendingAuth = useIdentityStore(state => state.pendingAuthorization);
|
|
31
|
+
// Detect if we're in a popup
|
|
32
|
+
const isPopup = window.opener !== null;
|
|
33
|
+
// Determine auto-close behavior
|
|
34
|
+
const shouldAutoClose = autoClose ?? isPopup;
|
|
35
|
+
// Wait for Zustand store to hydrate from localStorage
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
// Check if store has rehydrated by checking for any data or with a small delay
|
|
38
|
+
const checkHydration = () => {
|
|
39
|
+
// Give zustand-persist time to hydrate from localStorage
|
|
40
|
+
const stored = localStorage.getItem('agent-runtimes-identity');
|
|
41
|
+
if (stored) {
|
|
42
|
+
// Store exists - give it a moment to hydrate
|
|
43
|
+
setTimeout(() => setStoreHydrated(true), 50);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// No stored data, proceed immediately
|
|
47
|
+
setStoreHydrated(true);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
checkHydration();
|
|
51
|
+
}, []);
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
// Wait for store to hydrate before processing callback
|
|
54
|
+
if (!storeHydrated)
|
|
55
|
+
return;
|
|
56
|
+
const handleCallback = async () => {
|
|
57
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
58
|
+
const code = urlParams.get('code');
|
|
59
|
+
const state = urlParams.get('state');
|
|
60
|
+
const errorParam = urlParams.get('error');
|
|
61
|
+
const errorDescription = urlParams.get('error_description');
|
|
62
|
+
// Handle OAuth error response
|
|
63
|
+
if (errorParam) {
|
|
64
|
+
const errorMsg = errorDescription || errorParam;
|
|
65
|
+
setError(errorMsg);
|
|
66
|
+
setStatus('error');
|
|
67
|
+
onError?.(new Error(errorMsg));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
// Validate required parameters
|
|
71
|
+
if (!code || !state) {
|
|
72
|
+
const errorMsg = 'Missing authorization code or state parameter';
|
|
73
|
+
setError(errorMsg);
|
|
74
|
+
setStatus('error');
|
|
75
|
+
onError?.(new Error(errorMsg));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Validate state matches pending authorization
|
|
79
|
+
if (!pendingAuth || pendingAuth.state !== state) {
|
|
80
|
+
const errorMsg = 'Invalid state parameter - possible CSRF attack';
|
|
81
|
+
setError(errorMsg);
|
|
82
|
+
setStatus('error');
|
|
83
|
+
onError?.(new Error(errorMsg));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setProvider(pendingAuth.provider);
|
|
87
|
+
try {
|
|
88
|
+
// Complete the authorization - this returns the identity
|
|
89
|
+
const identity = await completeAuthorization({
|
|
90
|
+
code,
|
|
91
|
+
state,
|
|
92
|
+
});
|
|
93
|
+
setStatus('success');
|
|
94
|
+
onSuccess?.(pendingAuth.provider);
|
|
95
|
+
// Handle popup flow - notify parent and close
|
|
96
|
+
if (isPopup && window.opener) {
|
|
97
|
+
// Small delay to ensure localStorage is fully written by Zustand persist
|
|
98
|
+
// before notifying the parent window
|
|
99
|
+
setTimeout(() => {
|
|
100
|
+
console.log('[OAuthCallback] Posting success message to parent with identity');
|
|
101
|
+
// Post message to parent window - include identity so parent doesn't need to read from localStorage
|
|
102
|
+
window.opener.postMessage({
|
|
103
|
+
type: 'oauth-callback-success',
|
|
104
|
+
provider: pendingAuth.provider,
|
|
105
|
+
identity: identity,
|
|
106
|
+
}, window.location.origin);
|
|
107
|
+
if (shouldAutoClose) {
|
|
108
|
+
setTimeout(() => {
|
|
109
|
+
window.close();
|
|
110
|
+
}, autoCloseDelay);
|
|
111
|
+
}
|
|
112
|
+
}, 50);
|
|
113
|
+
}
|
|
114
|
+
// Handle redirect flow
|
|
115
|
+
else if (redirectUrl) {
|
|
116
|
+
if (shouldAutoClose) {
|
|
117
|
+
setTimeout(() => {
|
|
118
|
+
window.location.href = redirectUrl;
|
|
119
|
+
}, autoCloseDelay);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
const errorMsg = err instanceof Error ? err.message : 'Unknown error occurred';
|
|
125
|
+
setError(errorMsg);
|
|
126
|
+
setStatus('error');
|
|
127
|
+
onError?.(err instanceof Error ? err : new Error(errorMsg));
|
|
128
|
+
// Notify popup parent of error
|
|
129
|
+
if (isPopup && window.opener) {
|
|
130
|
+
window.opener.postMessage({
|
|
131
|
+
type: 'oauth-callback-error',
|
|
132
|
+
error: errorMsg,
|
|
133
|
+
provider: pendingAuth.provider,
|
|
134
|
+
}, window.location.origin);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
handleCallback();
|
|
139
|
+
}, [
|
|
140
|
+
storeHydrated,
|
|
141
|
+
completeAuthorization,
|
|
142
|
+
pendingAuth,
|
|
143
|
+
onSuccess,
|
|
144
|
+
onError,
|
|
145
|
+
shouldAutoClose,
|
|
146
|
+
autoCloseDelay,
|
|
147
|
+
redirectUrl,
|
|
148
|
+
isPopup,
|
|
149
|
+
]);
|
|
150
|
+
const handleClose = () => {
|
|
151
|
+
if (isPopup) {
|
|
152
|
+
window.close();
|
|
153
|
+
}
|
|
154
|
+
else if (redirectUrl) {
|
|
155
|
+
window.location.href = redirectUrl;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
return (_jsx(Box, { sx: {
|
|
159
|
+
display: 'flex',
|
|
160
|
+
flexDirection: 'column',
|
|
161
|
+
alignItems: 'center',
|
|
162
|
+
justifyContent: 'center',
|
|
163
|
+
minHeight: '100vh',
|
|
164
|
+
padding: 4,
|
|
165
|
+
backgroundColor: 'canvas.default',
|
|
166
|
+
}, children: _jsxs(Box, { sx: {
|
|
167
|
+
maxWidth: 400,
|
|
168
|
+
width: '100%',
|
|
169
|
+
padding: 4,
|
|
170
|
+
borderRadius: 2,
|
|
171
|
+
border: '1px solid',
|
|
172
|
+
borderColor: 'border.default',
|
|
173
|
+
backgroundColor: 'canvas.subtle',
|
|
174
|
+
textAlign: 'center',
|
|
175
|
+
}, children: [status === 'processing' && (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: {
|
|
176
|
+
display: 'block',
|
|
177
|
+
marginTop: 3,
|
|
178
|
+
fontSize: 2,
|
|
179
|
+
fontWeight: 'bold',
|
|
180
|
+
}, children: "Connecting your account..." }), _jsx(Text, { sx: { display: 'block', marginTop: 2, color: 'fg.muted' }, children: "Please wait while we complete the authorization." })] })), status === 'success' && (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
|
|
181
|
+
width: 64,
|
|
182
|
+
height: 64,
|
|
183
|
+
borderRadius: '50%',
|
|
184
|
+
backgroundColor: 'success.subtle',
|
|
185
|
+
display: 'flex',
|
|
186
|
+
alignItems: 'center',
|
|
187
|
+
justifyContent: 'center',
|
|
188
|
+
margin: '0 auto',
|
|
189
|
+
}, children: _jsx(Box, { sx: { color: 'success.fg' }, children: _jsx(CheckCircleFillIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
|
|
190
|
+
display: 'block',
|
|
191
|
+
marginTop: 3,
|
|
192
|
+
fontSize: 2,
|
|
193
|
+
fontWeight: 'bold',
|
|
194
|
+
color: 'success.fg',
|
|
195
|
+
}, children: successMessage }), provider && (_jsxs(Text, { sx: { display: 'block', marginTop: 2, color: 'fg.muted' }, children: ["Your ", provider, " account has been connected."] })), shouldAutoClose && (_jsx(Text, { sx: {
|
|
196
|
+
display: 'block',
|
|
197
|
+
marginTop: 3,
|
|
198
|
+
fontSize: 0,
|
|
199
|
+
color: 'fg.muted',
|
|
200
|
+
}, children: isPopup
|
|
201
|
+
? 'This window will close automatically...'
|
|
202
|
+
: 'Redirecting...' })), showCloseButton && !shouldAutoClose && (_jsx(Button, { variant: "primary", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Continue' }))] })), status === 'error' && (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
|
|
203
|
+
width: 64,
|
|
204
|
+
height: 64,
|
|
205
|
+
borderRadius: '50%',
|
|
206
|
+
backgroundColor: 'danger.subtle',
|
|
207
|
+
display: 'flex',
|
|
208
|
+
alignItems: 'center',
|
|
209
|
+
justifyContent: 'center',
|
|
210
|
+
margin: '0 auto',
|
|
211
|
+
}, children: _jsx(Box, { sx: { color: 'danger.fg' }, children: _jsx(XCircleIcon, { size: 32 }) }) }), _jsx(Text, { sx: {
|
|
212
|
+
display: 'block',
|
|
213
|
+
marginTop: 3,
|
|
214
|
+
fontSize: 2,
|
|
215
|
+
fontWeight: 'bold',
|
|
216
|
+
color: 'danger.fg',
|
|
217
|
+
}, children: "Connection Failed" }), _jsxs(Flash, { variant: "danger", sx: { marginTop: 3, textAlign: 'left' }, children: [_jsx(Box, { as: "span", sx: {
|
|
218
|
+
mr: 2,
|
|
219
|
+
display: 'inline-flex',
|
|
220
|
+
verticalAlign: 'text-bottom',
|
|
221
|
+
}, children: _jsx(AlertIcon, { size: 16 }) }), errorMessagePrefix, ": ", error] }), showCloseButton && (_jsx(Button, { variant: "danger", onClick: handleClose, sx: { marginTop: 3 }, children: isPopup ? 'Close' : 'Go Back' }))] }))] }) }));
|
|
222
|
+
};
|
|
223
|
+
export default OAuthCallback;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic Client Registration (DCR) for OAuth 2.1
|
|
3
|
+
*
|
|
4
|
+
* Implements RFC 7591 - OAuth 2.0 Dynamic Client Registration Protocol
|
|
5
|
+
* https://oauth.net/2/dynamic-client-registration/
|
|
6
|
+
*
|
|
7
|
+
* DCR allows OAuth clients to register themselves dynamically without
|
|
8
|
+
* manual setup, which is essential for AI agents that need to connect
|
|
9
|
+
* to OAuth providers discovered at runtime.
|
|
10
|
+
*
|
|
11
|
+
* @module identity/dcr
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* OAuth 2.0 Authorization Server Metadata
|
|
15
|
+
* Based on RFC 8414
|
|
16
|
+
*/
|
|
17
|
+
export interface AuthorizationServerMetadata {
|
|
18
|
+
/** The authorization server's issuer identifier */
|
|
19
|
+
issuer: string;
|
|
20
|
+
/** URL of the authorization endpoint */
|
|
21
|
+
authorization_endpoint: string;
|
|
22
|
+
/** URL of the token endpoint */
|
|
23
|
+
token_endpoint: string;
|
|
24
|
+
/** URL of the registration endpoint (for DCR) */
|
|
25
|
+
registration_endpoint?: string;
|
|
26
|
+
/** URL of the token revocation endpoint */
|
|
27
|
+
revocation_endpoint?: string;
|
|
28
|
+
/** URL of the userinfo endpoint (OpenID Connect) */
|
|
29
|
+
userinfo_endpoint?: string;
|
|
30
|
+
/** URL of the JWKS endpoint */
|
|
31
|
+
jwks_uri?: string;
|
|
32
|
+
/** Supported response types */
|
|
33
|
+
response_types_supported: string[];
|
|
34
|
+
/** Supported grant types */
|
|
35
|
+
grant_types_supported?: string[];
|
|
36
|
+
/** Supported scopes */
|
|
37
|
+
scopes_supported?: string[];
|
|
38
|
+
/** Supported token endpoint auth methods */
|
|
39
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
40
|
+
/** Supported code challenge methods (PKCE) */
|
|
41
|
+
code_challenge_methods_supported?: string[];
|
|
42
|
+
/** Additional metadata */
|
|
43
|
+
[key: string]: unknown;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Client registration request per RFC 7591
|
|
47
|
+
*/
|
|
48
|
+
export interface ClientRegistrationRequest {
|
|
49
|
+
/** Array of redirection URI strings */
|
|
50
|
+
redirect_uris: string[];
|
|
51
|
+
/** Requested authentication method for the token endpoint */
|
|
52
|
+
token_endpoint_auth_method?: 'none' | 'client_secret_basic' | 'client_secret_post' | 'private_key_jwt';
|
|
53
|
+
/** Array of grant types the client will use */
|
|
54
|
+
grant_types?: string[];
|
|
55
|
+
/** Array of response types the client will use */
|
|
56
|
+
response_types?: string[];
|
|
57
|
+
/** Human-readable name of the client */
|
|
58
|
+
client_name?: string;
|
|
59
|
+
/** URL of the client's home page */
|
|
60
|
+
client_uri?: string;
|
|
61
|
+
/** URL of the client's logo */
|
|
62
|
+
logo_uri?: string;
|
|
63
|
+
/** Space-separated list of scope values */
|
|
64
|
+
scope?: string;
|
|
65
|
+
/** Array of email addresses of people responsible for this client */
|
|
66
|
+
contacts?: string[];
|
|
67
|
+
/** URL of the terms of service */
|
|
68
|
+
tos_uri?: string;
|
|
69
|
+
/** URL of the privacy policy */
|
|
70
|
+
policy_uri?: string;
|
|
71
|
+
/** URL of the JWKS for the client (for private_key_jwt) */
|
|
72
|
+
jwks_uri?: string;
|
|
73
|
+
/** JWKS document (inline, alternative to jwks_uri) */
|
|
74
|
+
jwks?: {
|
|
75
|
+
keys: unknown[];
|
|
76
|
+
};
|
|
77
|
+
/** Software identifier (for software statement) */
|
|
78
|
+
software_id?: string;
|
|
79
|
+
/** Software version */
|
|
80
|
+
software_version?: string;
|
|
81
|
+
/** Software statement JWT */
|
|
82
|
+
software_statement?: string;
|
|
83
|
+
/** Additional registration parameters */
|
|
84
|
+
[key: string]: unknown;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Client registration response per RFC 7591
|
|
88
|
+
*/
|
|
89
|
+
export interface ClientRegistrationResponse {
|
|
90
|
+
/** OAuth 2.0 client identifier */
|
|
91
|
+
client_id: string;
|
|
92
|
+
/** OAuth 2.0 client secret (if confidential client) */
|
|
93
|
+
client_secret?: string;
|
|
94
|
+
/** Time at which the client identifier was issued (Unix timestamp) */
|
|
95
|
+
client_id_issued_at?: number;
|
|
96
|
+
/** Time at which the client secret will expire (Unix timestamp, 0 = never) */
|
|
97
|
+
client_secret_expires_at?: number;
|
|
98
|
+
/** Registration access token (for client configuration endpoint) */
|
|
99
|
+
registration_access_token?: string;
|
|
100
|
+
/** Location of the client configuration endpoint */
|
|
101
|
+
registration_client_uri?: string;
|
|
102
|
+
/** All other fields from the registration request echoed back */
|
|
103
|
+
redirect_uris: string[];
|
|
104
|
+
token_endpoint_auth_method?: string;
|
|
105
|
+
grant_types?: string[];
|
|
106
|
+
response_types?: string[];
|
|
107
|
+
client_name?: string;
|
|
108
|
+
client_uri?: string;
|
|
109
|
+
logo_uri?: string;
|
|
110
|
+
scope?: string;
|
|
111
|
+
contacts?: string[];
|
|
112
|
+
tos_uri?: string;
|
|
113
|
+
policy_uri?: string;
|
|
114
|
+
jwks_uri?: string;
|
|
115
|
+
jwks?: {
|
|
116
|
+
keys: unknown[];
|
|
117
|
+
};
|
|
118
|
+
software_id?: string;
|
|
119
|
+
software_version?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* DCR error response per RFC 7591
|
|
123
|
+
*/
|
|
124
|
+
export interface ClientRegistrationError {
|
|
125
|
+
/** Error code */
|
|
126
|
+
error: 'invalid_redirect_uri' | 'invalid_client_metadata' | 'invalid_software_statement' | 'unapproved_software_statement' | string;
|
|
127
|
+
/** Human-readable error description */
|
|
128
|
+
error_description?: string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Stored DCR client information
|
|
132
|
+
*/
|
|
133
|
+
export interface DynamicClient {
|
|
134
|
+
/** Provider/issuer identifier */
|
|
135
|
+
issuer: string;
|
|
136
|
+
/** Registered client ID */
|
|
137
|
+
clientId: string;
|
|
138
|
+
/** Registered client secret (if any) */
|
|
139
|
+
clientSecret?: string;
|
|
140
|
+
/** Client secret expiration (if any) */
|
|
141
|
+
clientSecretExpiresAt?: number;
|
|
142
|
+
/** Registration access token (for updates) */
|
|
143
|
+
registrationAccessToken?: string;
|
|
144
|
+
/** Registration client URI (for updates) */
|
|
145
|
+
registrationClientUri?: string;
|
|
146
|
+
/** Registration timestamp */
|
|
147
|
+
registeredAt: number;
|
|
148
|
+
/** Configured redirect URIs */
|
|
149
|
+
redirectUris: string[];
|
|
150
|
+
/** Granted scopes */
|
|
151
|
+
scopes: string[];
|
|
152
|
+
/** Server metadata */
|
|
153
|
+
serverMetadata: AuthorizationServerMetadata;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Discover OAuth authorization server metadata
|
|
157
|
+
*
|
|
158
|
+
* @param issuerUrl - The issuer URL (e.g., https://accounts.google.com)
|
|
159
|
+
* @returns Authorization server metadata or null if not found
|
|
160
|
+
*/
|
|
161
|
+
export declare function discoverAuthorizationServer(issuerUrl: string): Promise<AuthorizationServerMetadata | null>;
|
|
162
|
+
/**
|
|
163
|
+
* Check if an authorization server supports Dynamic Client Registration
|
|
164
|
+
*
|
|
165
|
+
* @param metadata - Authorization server metadata
|
|
166
|
+
* @returns True if DCR is supported
|
|
167
|
+
*/
|
|
168
|
+
export declare function supportsDCR(metadata: AuthorizationServerMetadata): boolean;
|
|
169
|
+
/**
|
|
170
|
+
* Register a new OAuth client dynamically
|
|
171
|
+
*
|
|
172
|
+
* @param registrationEndpoint - The DCR endpoint URL
|
|
173
|
+
* @param request - Client registration request
|
|
174
|
+
* @param accessToken - Optional access token (for protected registration endpoints)
|
|
175
|
+
* @returns Client registration response
|
|
176
|
+
* @throws Error if registration fails
|
|
177
|
+
*/
|
|
178
|
+
export declare function registerClient(registrationEndpoint: string, request: ClientRegistrationRequest, accessToken?: string): Promise<ClientRegistrationResponse>;
|
|
179
|
+
/**
|
|
180
|
+
* Update an existing client registration
|
|
181
|
+
*
|
|
182
|
+
* @param registrationClientUri - The client configuration endpoint
|
|
183
|
+
* @param registrationAccessToken - The registration access token
|
|
184
|
+
* @param updates - Fields to update
|
|
185
|
+
* @returns Updated client registration
|
|
186
|
+
*/
|
|
187
|
+
export declare function updateClientRegistration(registrationClientUri: string, registrationAccessToken: string, updates: Partial<ClientRegistrationRequest>): Promise<ClientRegistrationResponse>;
|
|
188
|
+
/**
|
|
189
|
+
* Delete a client registration
|
|
190
|
+
*
|
|
191
|
+
* @param registrationClientUri - The client configuration endpoint
|
|
192
|
+
* @param registrationAccessToken - The registration access token
|
|
193
|
+
*/
|
|
194
|
+
export declare function deleteClientRegistration(registrationClientUri: string, registrationAccessToken: string): Promise<void>;
|
|
195
|
+
/**
|
|
196
|
+
* Get or create a dynamic client for an OAuth provider
|
|
197
|
+
*
|
|
198
|
+
* This is the main entry point for DCR. It:
|
|
199
|
+
* 1. Checks if we already have a registered client for this issuer
|
|
200
|
+
* 2. If not, discovers the authorization server metadata
|
|
201
|
+
* 3. If DCR is supported, registers a new client
|
|
202
|
+
* 4. Stores the client for future use
|
|
203
|
+
*
|
|
204
|
+
* @param issuerUrl - The OAuth provider's issuer URL
|
|
205
|
+
* @param options - Registration options
|
|
206
|
+
* @returns The dynamic client information
|
|
207
|
+
* @throws Error if DCR is not supported or registration fails
|
|
208
|
+
*/
|
|
209
|
+
export declare function getOrCreateDynamicClient(issuerUrl: string, options: {
|
|
210
|
+
/** Application name */
|
|
211
|
+
clientName?: string;
|
|
212
|
+
/** Redirect URIs */
|
|
213
|
+
redirectUris: string[];
|
|
214
|
+
/** Requested scopes */
|
|
215
|
+
scopes?: string[];
|
|
216
|
+
/** Force re-registration even if client exists */
|
|
217
|
+
forceNew?: boolean;
|
|
218
|
+
/** Optional initial access token for protected endpoints */
|
|
219
|
+
initialAccessToken?: string;
|
|
220
|
+
}): Promise<DynamicClient>;
|
|
221
|
+
/**
|
|
222
|
+
* Load a dynamic client from storage
|
|
223
|
+
*/
|
|
224
|
+
export declare function loadDynamicClient(issuer: string): DynamicClient | null;
|
|
225
|
+
/**
|
|
226
|
+
* Save a dynamic client to storage
|
|
227
|
+
*/
|
|
228
|
+
export declare function saveDynamicClient(client: DynamicClient): void;
|
|
229
|
+
/**
|
|
230
|
+
* Remove a dynamic client from storage
|
|
231
|
+
*/
|
|
232
|
+
export declare function removeDynamicClient(issuer: string): void;
|
|
233
|
+
/**
|
|
234
|
+
* Get all stored dynamic clients
|
|
235
|
+
*/
|
|
236
|
+
export declare function getAllDynamicClients(): DynamicClient[];
|
|
237
|
+
/**
|
|
238
|
+
* Clear all stored dynamic clients
|
|
239
|
+
*/
|
|
240
|
+
export declare function clearAllDynamicClients(): void;
|
|
241
|
+
/**
|
|
242
|
+
* Build OAuth provider config from a dynamic client
|
|
243
|
+
*
|
|
244
|
+
* This converts a DynamicClient into an OAuthProviderConfig that can be
|
|
245
|
+
* used with the rest of the identity system.
|
|
246
|
+
*/
|
|
247
|
+
export declare function dynamicClientToProviderConfig(client: DynamicClient, displayName?: string): {
|
|
248
|
+
provider: string;
|
|
249
|
+
displayName: string;
|
|
250
|
+
clientId: string;
|
|
251
|
+
authorizationUrl: string;
|
|
252
|
+
tokenUrl: string;
|
|
253
|
+
userInfoUrl?: string;
|
|
254
|
+
revocationUrl?: string;
|
|
255
|
+
defaultScopes: string[];
|
|
256
|
+
redirectUri: string;
|
|
257
|
+
};
|