@kya-os/consent 0.1.23 → 0.1.24
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/dist/bundle/index.d.ts +44 -0
- package/dist/bundle/shell.d.ts +126 -0
- package/dist/bundle/shell.js +295 -0
- package/dist/bundle/shell.js.map +1 -0
- package/dist/components/consent-button.d.ts +61 -0
- package/dist/components/consent-button.js +177 -0
- package/dist/components/consent-button.js.map +1 -0
- package/dist/components/consent-checkbox.d.ts +61 -0
- package/dist/components/consent-checkbox.js +220 -0
- package/dist/components/consent-checkbox.js.map +1 -0
- package/dist/components/consent-input.d.ts +91 -0
- package/dist/components/consent-input.js +332 -0
- package/dist/components/consent-input.js.map +1 -0
- package/dist/components/consent-oauth-button.d.ts +87 -0
- package/dist/components/consent-oauth-button.js +389 -0
- package/dist/components/consent-oauth-button.js.map +1 -0
- package/dist/components/consent-otp-input.d.ts +92 -0
- package/dist/components/consent-otp-input.js +385 -0
- package/dist/components/consent-otp-input.js.map +1 -0
- package/dist/components/consent-permissions.d.ts +104 -0
- package/dist/components/consent-permissions.js +430 -0
- package/dist/components/consent-permissions.js.map +1 -0
- package/dist/components/consent-shell.d.ts +72 -0
- package/dist/components/consent-shell.js +231 -0
- package/dist/components/consent-shell.js.map +1 -0
- package/dist/components/consent-terms.d.ts +89 -0
- package/dist/components/consent-terms.js +284 -0
- package/dist/components/consent-terms.js.map +1 -0
- package/dist/components/index.d.ts +19 -0
- package/dist/constants/auth-modes.d.ts +59 -0
- package/dist/constants/auth-modes.js +120 -0
- package/dist/constants/auth-modes.js.map +1 -0
- package/dist/constants/colors.d.ts +38 -0
- package/dist/constants/colors.js +37 -0
- package/dist/constants/colors.js.map +1 -0
- package/dist/constants/defaults.d.ts +112 -0
- package/dist/constants/defaults.js +143 -0
- package/dist/constants/defaults.js.map +1 -0
- package/dist/constants/index.d.ts +12 -0
- package/dist/constants/index.js +16 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.d.ts +123 -0
- package/dist/resolution/index.d.ts +12 -0
- package/dist/resolution/index.js +12 -0
- package/dist/resolution/index.js.map +1 -0
- package/dist/resolution/resolve-branding.d.ts +70 -0
- package/dist/resolution/resolve-branding.js +149 -0
- package/dist/resolution/resolve-branding.js.map +1 -0
- package/dist/resolution/resolve-config.d.ts +81 -0
- package/dist/resolution/resolve-config.js +258 -0
- package/dist/resolution/resolve-config.js.map +1 -0
- package/dist/resolution/resolve-copy.d.ts +53 -0
- package/dist/resolution/resolve-copy.js +128 -0
- package/dist/resolution/resolve-copy.js.map +1 -0
- package/dist/schemas/api.schemas.d.ts +122 -122
- package/dist/schemas/api.schemas.js +162 -0
- package/dist/schemas/api.schemas.js.map +1 -0
- package/dist/schemas/branding.schemas.d.ts +100 -0
- package/dist/schemas/branding.schemas.js +54 -0
- package/dist/schemas/branding.schemas.js.map +1 -0
- package/dist/schemas/config.schemas.d.ts +110 -110
- package/dist/schemas/config.schemas.js +141 -0
- package/dist/schemas/config.schemas.js.map +1 -0
- package/dist/schemas/index.d.ts +13 -0
- package/dist/schemas/index.js +13 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/modes.schemas.d.ts +28 -28
- package/dist/schemas/modes.schemas.js +104 -0
- package/dist/schemas/modes.schemas.js.map +1 -0
- package/dist/security/escape.d.ts +114 -0
- package/dist/security/escape.js +197 -0
- package/dist/security/escape.js.map +1 -0
- package/dist/security/index.d.ts +10 -0
- package/dist/security/index.js +10 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/validators.d.ts +98 -0
- package/dist/security/validators.js +199 -0
- package/dist/security/validators.js.map +1 -0
- package/dist/styles/css-variables.d.ts +78 -0
- package/dist/styles/css-variables.js +120 -0
- package/dist/styles/css-variables.js.map +1 -0
- package/dist/styles/index.d.ts +12 -0
- package/dist/styles/index.js +12 -0
- package/dist/styles/index.js.map +1 -0
- package/dist/styles/stylesheet.d.ts +57 -0
- package/dist/styles/stylesheet.js +197 -0
- package/dist/styles/stylesheet.js.map +1 -0
- package/dist/styles/tokens.d.ts +141 -0
- package/dist/styles/tokens.js +180 -0
- package/dist/styles/tokens.js.map +1 -0
- package/dist/templates/base/base-template.d.ts +81 -0
- package/dist/templates/base/base-template.js +278 -0
- package/dist/templates/base/base-template.js.map +1 -0
- package/dist/templates/base/components.d.ts +120 -0
- package/dist/templates/base/components.js +279 -0
- package/dist/templates/base/components.js.map +1 -0
- package/dist/templates/base/index.d.ts +8 -0
- package/dist/templates/base/index.js +8 -0
- package/dist/templates/base/index.js.map +1 -0
- package/dist/templates/index.d.ts +18 -0
- package/dist/templates/index.js +18 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/templates/modes/consent-only.template.d.ts +36 -0
- package/dist/templates/modes/consent-only.template.js +70 -0
- package/dist/templates/modes/consent-only.template.js.map +1 -0
- package/dist/templates/modes/credentials.template.d.ts +65 -0
- package/dist/templates/modes/credentials.template.js +410 -0
- package/dist/templates/modes/credentials.template.js.map +1 -0
- package/dist/templates/modes/index.d.ts +14 -0
- package/dist/templates/modes/index.js +14 -0
- package/dist/templates/modes/index.js.map +1 -0
- package/dist/templates/modes/magic-link.template.d.ts +33 -0
- package/dist/templates/modes/magic-link.template.js +192 -0
- package/dist/templates/modes/magic-link.template.js.map +1 -0
- package/dist/templates/modes/oauth.template.d.ts +32 -0
- package/dist/templates/modes/oauth.template.js +121 -0
- package/dist/templates/modes/oauth.template.js.map +1 -0
- package/dist/templates/modes/otp.template.d.ts +35 -0
- package/dist/templates/modes/otp.template.js +312 -0
- package/dist/templates/modes/otp.template.js.map +1 -0
- package/dist/templates/modes/success.template.d.ts +41 -0
- package/dist/templates/registry.d.ts +68 -0
- package/dist/templates/registry.js +125 -0
- package/dist/templates/registry.js.map +1 -0
- package/dist/types/api.types.d.ts +147 -0
- package/dist/types/api.types.js +9 -0
- package/dist/types/api.types.js.map +1 -0
- package/dist/types/branding.types.d.ts +53 -0
- package/dist/types/branding.types.js +9 -0
- package/dist/types/branding.types.js.map +1 -0
- package/dist/types/config.types.d.ts +201 -0
- package/dist/types/config.types.js +9 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/copy.types.d.ts +109 -0
- package/dist/types/copy.types.js +9 -0
- package/dist/types/copy.types.js.map +1 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.js +15 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/modes.types.d.ts +287 -0
- package/dist/types/modes.types.js +136 -0
- package/dist/types/modes.types.js.map +1 -0
- package/dist/types/page.types.d.ts +120 -0
- package/dist/types/page.types.js +9 -0
- package/dist/types/page.types.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consent Bundle Entry Point
|
|
3
|
+
*
|
|
4
|
+
* This file serves as the entry point for bundling all consent components
|
|
5
|
+
* into a single file (consent.js) that can be served by Workers.
|
|
6
|
+
*
|
|
7
|
+
* When bundled with esbuild, this creates a self-contained script that:
|
|
8
|
+
* 1. Imports Lit and all dependencies
|
|
9
|
+
* 2. Registers all custom elements
|
|
10
|
+
* 3. Makes <mcp-consent> and all sub-components available in the browser
|
|
11
|
+
*
|
|
12
|
+
* Usage in Worker:
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Serve consent.js at /consent.js
|
|
15
|
+
* import CONSENT_BUNDLE from './consent.bundle.js';
|
|
16
|
+
*
|
|
17
|
+
* app.get('/consent.js', () => new Response(CONSENT_BUNDLE, {
|
|
18
|
+
* headers: { 'Content-Type': 'application/javascript' }
|
|
19
|
+
* }));
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @module @kya-os/consent/bundle
|
|
23
|
+
*/
|
|
24
|
+
import '../components/consent-button.js';
|
|
25
|
+
import '../components/consent-checkbox.js';
|
|
26
|
+
import '../components/consent-input.js';
|
|
27
|
+
import '../components/consent-shell.js';
|
|
28
|
+
import '../components/consent-permissions.js';
|
|
29
|
+
import '../components/consent-terms.js';
|
|
30
|
+
import '../components/consent-oauth-button.js';
|
|
31
|
+
import '../components/consent-otp-input.js';
|
|
32
|
+
import '../components/mcp-consent.js';
|
|
33
|
+
export { McpConsent } from '../components/mcp-consent.js';
|
|
34
|
+
export { ConsentButton } from '../components/consent-button.js';
|
|
35
|
+
export { ConsentCheckbox } from '../components/consent-checkbox.js';
|
|
36
|
+
export { ConsentInput } from '../components/consent-input.js';
|
|
37
|
+
export { ConsentShell } from '../components/consent-shell.js';
|
|
38
|
+
export { ConsentPermissions } from '../components/consent-permissions.js';
|
|
39
|
+
export { ConsentTerms } from '../components/consent-terms.js';
|
|
40
|
+
export { ConsentOAuthButton } from '../components/consent-oauth-button.js';
|
|
41
|
+
export { ConsentOTPInput } from '../components/consent-otp-input.js';
|
|
42
|
+
export type { ConsentConfig, ResolvedConsentConfig } from '../types/config.types.js';
|
|
43
|
+
export type { OAuthIdentity } from '../types/api.types.js';
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consent HTML Shell Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates the minimal HTML shell that Workers serve for consent pages.
|
|
5
|
+
* The shell loads the bundled consent.js and renders <mcp-consent>.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* 1. Worker receives consent page request
|
|
9
|
+
* 2. Worker calls generateConsentShell() with config
|
|
10
|
+
* 3. Browser loads HTML, fetches consent.js
|
|
11
|
+
* 4. Lit components render the consent UI
|
|
12
|
+
* 5. Form submission posts back to Worker
|
|
13
|
+
*
|
|
14
|
+
* @module @kya-os/consent/bundle/shell
|
|
15
|
+
*/
|
|
16
|
+
import type { ConsentConfig } from '../types/config.types.js';
|
|
17
|
+
import type { OAuthIdentity } from '../types/api.types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Options for generating the consent HTML shell
|
|
20
|
+
*/
|
|
21
|
+
export interface ConsentShellOptions {
|
|
22
|
+
/** Consent page configuration (from AgentShield remote config) */
|
|
23
|
+
config: ConsentConfig;
|
|
24
|
+
/** Tool being requested */
|
|
25
|
+
tool: string;
|
|
26
|
+
/** Permission scopes requested */
|
|
27
|
+
scopes: string[];
|
|
28
|
+
/** Agent's DID */
|
|
29
|
+
agentDid: string;
|
|
30
|
+
/** Session identifier */
|
|
31
|
+
sessionId: string;
|
|
32
|
+
/** Project identifier */
|
|
33
|
+
projectId: string;
|
|
34
|
+
/** Server URL for form submission */
|
|
35
|
+
serverUrl: string;
|
|
36
|
+
/** OAuth identity if already authenticated */
|
|
37
|
+
oauthIdentity?: OAuthIdentity;
|
|
38
|
+
/** Path to consent.js bundle (defaults to '/consent.js') */
|
|
39
|
+
bundlePath?: string;
|
|
40
|
+
/** Custom page title */
|
|
41
|
+
pageTitle?: string;
|
|
42
|
+
/** CSP nonce for inline scripts/styles */
|
|
43
|
+
nonce?: string;
|
|
44
|
+
/** Authentication mode (consent-only, credentials, oauth, magic-link, otp) */
|
|
45
|
+
authMode?: string;
|
|
46
|
+
/** Provider name for credentials/oauth flows */
|
|
47
|
+
provider?: string;
|
|
48
|
+
/** CSRF token for form security (required for credential auth) */
|
|
49
|
+
csrfToken?: string;
|
|
50
|
+
/** Credential provider type from prior auth step (for 3-screen flow) */
|
|
51
|
+
credentialProviderType?: string;
|
|
52
|
+
/** Credential provider name from prior auth step (for 3-screen flow) */
|
|
53
|
+
credentialProvider?: string;
|
|
54
|
+
/**
|
|
55
|
+
* User DID from prior auth step
|
|
56
|
+
* CRITICAL: Bypasses KV eventual consistency issues by passing directly
|
|
57
|
+
*/
|
|
58
|
+
userDid?: string;
|
|
59
|
+
/**
|
|
60
|
+
* User email from credential provider response
|
|
61
|
+
* Used for human-readable display in AgentShield dashboard (user_identifier)
|
|
62
|
+
*/
|
|
63
|
+
credentialUserEmail?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Provider's internal user ID from credential provider response
|
|
66
|
+
* Used for business reference (e.g., Hardware World customer ID 696395)
|
|
67
|
+
*/
|
|
68
|
+
credentialProviderUserId?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Pre-built OAuth authorization URL
|
|
71
|
+
* When provided, the OAuth button will link directly to this URL instead of
|
|
72
|
+
* constructing a URL like /oauth/:provider which may not exist.
|
|
73
|
+
* Example: https://github.com/login/oauth/authorize?client_id=...&redirect_uri=...
|
|
74
|
+
*/
|
|
75
|
+
oauthUrl?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Authorization type from tool protection config
|
|
78
|
+
* Determines the provider_type sent in credential form submissions
|
|
79
|
+
* Values: 'password', 'oauth2', 'none', etc.
|
|
80
|
+
* Default: 'password' for credential flows
|
|
81
|
+
*/
|
|
82
|
+
authorizationType?: string;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Generate the consent page HTML shell
|
|
86
|
+
*
|
|
87
|
+
* This produces a minimal HTML document that:
|
|
88
|
+
* - Loads the bundled consent.js
|
|
89
|
+
* - Renders the <mcp-consent> web component
|
|
90
|
+
* - Includes a loading skeleton for perceived performance
|
|
91
|
+
* - Has a no-JS fallback form
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* const html = generateConsentShell({
|
|
96
|
+
* config: remoteConfig,
|
|
97
|
+
* tool: 'purchase',
|
|
98
|
+
* scopes: ['billing:read', 'orders:write'],
|
|
99
|
+
* agentDid: 'did:key:z6Mk...',
|
|
100
|
+
* sessionId: 'sess_abc123',
|
|
101
|
+
* projectId: 'proj_xyz',
|
|
102
|
+
* serverUrl: 'https://api.example.com',
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* return new Response(html, {
|
|
106
|
+
* headers: { 'Content-Type': 'text/html' }
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
export declare function generateConsentShell(options: ConsentShellOptions): string;
|
|
111
|
+
/**
|
|
112
|
+
* Generate inline consent component (no external bundle)
|
|
113
|
+
*
|
|
114
|
+
* For scenarios where you want to inline everything into a single HTML response.
|
|
115
|
+
* This is useful for:
|
|
116
|
+
* - Offline/embedded scenarios
|
|
117
|
+
* - Single-request consent pages
|
|
118
|
+
* - Testing/debugging
|
|
119
|
+
*
|
|
120
|
+
* Note: This requires the consent bundle to be inlined as a string.
|
|
121
|
+
*
|
|
122
|
+
* @param options - Shell options
|
|
123
|
+
* @param bundleSource - The bundled consent.js source code
|
|
124
|
+
*/
|
|
125
|
+
export declare function generateInlineConsentShell(options: Omit<ConsentShellOptions, 'bundlePath'>, bundleSource: string): string;
|
|
126
|
+
//# sourceMappingURL=shell.d.ts.map
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consent HTML Shell Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates the minimal HTML shell that Workers serve for consent pages.
|
|
5
|
+
* The shell loads the bundled consent.js and renders <mcp-consent>.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* 1. Worker receives consent page request
|
|
9
|
+
* 2. Worker calls generateConsentShell() with config
|
|
10
|
+
* 3. Browser loads HTML, fetches consent.js
|
|
11
|
+
* 4. Lit components render the consent UI
|
|
12
|
+
* 5. Form submission posts back to Worker
|
|
13
|
+
*
|
|
14
|
+
* @module @kya-os/consent/bundle/shell
|
|
15
|
+
*/
|
|
16
|
+
import { escapeHtml, escapeAttr } from '../security/escape.js';
|
|
17
|
+
/**
|
|
18
|
+
* Generate the consent page HTML shell
|
|
19
|
+
*
|
|
20
|
+
* This produces a minimal HTML document that:
|
|
21
|
+
* - Loads the bundled consent.js
|
|
22
|
+
* - Renders the <mcp-consent> web component
|
|
23
|
+
* - Includes a loading skeleton for perceived performance
|
|
24
|
+
* - Has a no-JS fallback form
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const html = generateConsentShell({
|
|
29
|
+
* config: remoteConfig,
|
|
30
|
+
* tool: 'purchase',
|
|
31
|
+
* scopes: ['billing:read', 'orders:write'],
|
|
32
|
+
* agentDid: 'did:key:z6Mk...',
|
|
33
|
+
* sessionId: 'sess_abc123',
|
|
34
|
+
* projectId: 'proj_xyz',
|
|
35
|
+
* serverUrl: 'https://api.example.com',
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* return new Response(html, {
|
|
39
|
+
* headers: { 'Content-Type': 'text/html' }
|
|
40
|
+
* });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function generateConsentShell(options) {
|
|
44
|
+
const { config, tool, scopes, agentDid, sessionId, projectId, serverUrl, oauthIdentity, bundlePath = '/consent.js', pageTitle = 'Permission Request', nonce, authMode, provider, csrfToken, credentialProviderType, credentialProvider, userDid, // CRITICAL: Bypasses KV consistency issues
|
|
45
|
+
credentialUserEmail, // User email from credential provider
|
|
46
|
+
credentialProviderUserId, // Provider's user ID (e.g., customer ID)
|
|
47
|
+
oauthUrl, // Pre-built OAuth authorization URL
|
|
48
|
+
authorizationType, // Dynamic authorization type from tool protection
|
|
49
|
+
} = options;
|
|
50
|
+
// Safely serialize config as JSON for attribute
|
|
51
|
+
const configJson = JSON.stringify(config);
|
|
52
|
+
const scopesJson = JSON.stringify(scopes);
|
|
53
|
+
const oauthJson = oauthIdentity ? JSON.stringify(oauthIdentity) : null;
|
|
54
|
+
// Build nonce attribute if provided
|
|
55
|
+
const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : '';
|
|
56
|
+
return `<!DOCTYPE html>
|
|
57
|
+
<html lang="en">
|
|
58
|
+
<head>
|
|
59
|
+
<meta charset="UTF-8">
|
|
60
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
61
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
62
|
+
<title>${escapeHtml(pageTitle)}</title>
|
|
63
|
+
|
|
64
|
+
<!-- Preload the bundle for faster loading -->
|
|
65
|
+
<link rel="preload" href="${escapeAttr(bundlePath)}" as="script" crossorigin>
|
|
66
|
+
|
|
67
|
+
<!-- Load consent components bundle -->
|
|
68
|
+
<script type="module" src="${escapeAttr(bundlePath)}"${nonceAttr}></script>
|
|
69
|
+
|
|
70
|
+
<style${nonceAttr}>
|
|
71
|
+
/* Base styles */
|
|
72
|
+
*, *::before, *::after {
|
|
73
|
+
box-sizing: border-box;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
body {
|
|
77
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
78
|
+
background: #f3f4f6;
|
|
79
|
+
min-height: 100vh;
|
|
80
|
+
margin: 0;
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
justify-content: center;
|
|
84
|
+
padding: 1rem;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/* Loading skeleton - shown while component loads */
|
|
88
|
+
.loading-skeleton {
|
|
89
|
+
max-width: 512px;
|
|
90
|
+
width: 100%;
|
|
91
|
+
background: white;
|
|
92
|
+
border-radius: 20px;
|
|
93
|
+
padding: 2rem;
|
|
94
|
+
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.skeleton-header {
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: 1rem;
|
|
101
|
+
margin-bottom: 1.5rem;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.skeleton-avatar {
|
|
105
|
+
width: 48px;
|
|
106
|
+
height: 48px;
|
|
107
|
+
background: #e5e7eb;
|
|
108
|
+
border-radius: 12px;
|
|
109
|
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.skeleton-line {
|
|
113
|
+
height: 1rem;
|
|
114
|
+
background: #e5e7eb;
|
|
115
|
+
border-radius: 0.25rem;
|
|
116
|
+
margin-bottom: 0.75rem;
|
|
117
|
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.skeleton-line.short { width: 60%; }
|
|
121
|
+
.skeleton-line.medium { width: 80%; }
|
|
122
|
+
.skeleton-line.full { width: 100%; }
|
|
123
|
+
|
|
124
|
+
.skeleton-button {
|
|
125
|
+
height: 44px;
|
|
126
|
+
background: #e5e7eb;
|
|
127
|
+
border-radius: 8px;
|
|
128
|
+
margin-top: 1.5rem;
|
|
129
|
+
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@keyframes pulse {
|
|
133
|
+
0%, 100% { opacity: 1; }
|
|
134
|
+
50% { opacity: 0.5; }
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* Hide skeleton when component is defined */
|
|
138
|
+
mcp-consent:defined + .loading-skeleton {
|
|
139
|
+
display: none;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* No-JS fallback styling */
|
|
143
|
+
noscript .fallback-form {
|
|
144
|
+
max-width: 512px;
|
|
145
|
+
width: 100%;
|
|
146
|
+
background: white;
|
|
147
|
+
border-radius: 20px;
|
|
148
|
+
padding: 2rem;
|
|
149
|
+
box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
noscript h1 {
|
|
153
|
+
font-size: 1.25rem;
|
|
154
|
+
font-weight: 600;
|
|
155
|
+
color: #111827;
|
|
156
|
+
margin: 0 0 1rem;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
noscript p {
|
|
160
|
+
color: #6b7280;
|
|
161
|
+
margin: 0 0 1.5rem;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
noscript button {
|
|
165
|
+
width: 100%;
|
|
166
|
+
padding: 0.75rem 1rem;
|
|
167
|
+
background: #2563eb;
|
|
168
|
+
color: white;
|
|
169
|
+
border: none;
|
|
170
|
+
border-radius: 8px;
|
|
171
|
+
font-size: 0.875rem;
|
|
172
|
+
font-weight: 500;
|
|
173
|
+
cursor: pointer;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
noscript button:hover {
|
|
177
|
+
background: #1d4ed8;
|
|
178
|
+
}
|
|
179
|
+
</style>
|
|
180
|
+
</head>
|
|
181
|
+
<body>
|
|
182
|
+
<!-- Main consent component -->
|
|
183
|
+
<mcp-consent
|
|
184
|
+
config='${escapeAttr(configJson)}'
|
|
185
|
+
tool="${escapeAttr(tool)}"
|
|
186
|
+
scopes='${escapeAttr(scopesJson)}'
|
|
187
|
+
agent-did="${escapeAttr(agentDid)}"
|
|
188
|
+
session-id="${escapeAttr(sessionId)}"
|
|
189
|
+
project-id="${escapeAttr(projectId)}"
|
|
190
|
+
server-url="${escapeAttr(serverUrl)}"
|
|
191
|
+
${oauthJson ? `oauth-identity='${escapeAttr(oauthJson)}'` : ''}
|
|
192
|
+
${authMode ? `auth-mode="${escapeAttr(authMode)}"` : ''}
|
|
193
|
+
${provider ? `provider="${escapeAttr(provider)}"` : ''}
|
|
194
|
+
${csrfToken ? `csrf-token="${escapeAttr(csrfToken)}"` : ''}
|
|
195
|
+
${credentialProviderType ? `credential-provider-type="${escapeAttr(credentialProviderType)}"` : ''}
|
|
196
|
+
${credentialProvider ? `credential-provider="${escapeAttr(credentialProvider)}"` : ''}
|
|
197
|
+
${userDid ? `user-did="${escapeAttr(userDid)}"` : ''}
|
|
198
|
+
${credentialUserEmail ? `credential-user-email="${escapeAttr(credentialUserEmail)}"` : ''}
|
|
199
|
+
${credentialProviderUserId ? `credential-provider-user-id="${escapeAttr(credentialProviderUserId)}"` : ''}
|
|
200
|
+
${oauthUrl ? `oauth-url="${escapeAttr(oauthUrl)}"` : ''}
|
|
201
|
+
${authorizationType ? `authorization-type="${escapeAttr(authorizationType)}"` : ''}
|
|
202
|
+
></mcp-consent>
|
|
203
|
+
|
|
204
|
+
<!-- Loading skeleton (hidden once component is defined) -->
|
|
205
|
+
<div class="loading-skeleton" aria-hidden="true">
|
|
206
|
+
<div class="skeleton-header">
|
|
207
|
+
<div class="skeleton-avatar"></div>
|
|
208
|
+
<div style="flex: 1">
|
|
209
|
+
<div class="skeleton-line short"></div>
|
|
210
|
+
<div class="skeleton-line medium" style="margin-bottom: 0; height: 0.75rem;"></div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="skeleton-line full"></div>
|
|
214
|
+
<div class="skeleton-line medium"></div>
|
|
215
|
+
<div class="skeleton-line short"></div>
|
|
216
|
+
<div class="skeleton-button"></div>
|
|
217
|
+
</div>
|
|
218
|
+
|
|
219
|
+
<!-- No-JS fallback - basic form submission -->
|
|
220
|
+
<noscript>
|
|
221
|
+
<form class="fallback-form" method="POST" action="${escapeAttr(serverUrl)}/consent/approve">
|
|
222
|
+
<h1>Permission Request</h1>
|
|
223
|
+
<p>JavaScript is required for the full consent experience. You can still approve basic access below.</p>
|
|
224
|
+
|
|
225
|
+
<input type="hidden" name="tool" value="${escapeAttr(tool)}">
|
|
226
|
+
<input type="hidden" name="scopes" value="${escapeAttr(scopesJson)}">
|
|
227
|
+
<input type="hidden" name="agent_did" value="${escapeAttr(agentDid)}">
|
|
228
|
+
<input type="hidden" name="session_id" value="${escapeAttr(sessionId)}">
|
|
229
|
+
<input type="hidden" name="project_id" value="${escapeAttr(projectId)}">
|
|
230
|
+
<input type="hidden" name="auth_mode" value="consent-only">
|
|
231
|
+
<input type="hidden" name="provider_type" value="none">
|
|
232
|
+
|
|
233
|
+
<button type="submit">Allow Basic Access</button>
|
|
234
|
+
</form>
|
|
235
|
+
</noscript>
|
|
236
|
+
</body>
|
|
237
|
+
</html>`;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Generate inline consent component (no external bundle)
|
|
241
|
+
*
|
|
242
|
+
* For scenarios where you want to inline everything into a single HTML response.
|
|
243
|
+
* This is useful for:
|
|
244
|
+
* - Offline/embedded scenarios
|
|
245
|
+
* - Single-request consent pages
|
|
246
|
+
* - Testing/debugging
|
|
247
|
+
*
|
|
248
|
+
* Note: This requires the consent bundle to be inlined as a string.
|
|
249
|
+
*
|
|
250
|
+
* @param options - Shell options
|
|
251
|
+
* @param bundleSource - The bundled consent.js source code
|
|
252
|
+
*/
|
|
253
|
+
export function generateInlineConsentShell(options, bundleSource) {
|
|
254
|
+
const { config, tool, scopes, agentDid, sessionId, projectId, serverUrl, oauthIdentity, pageTitle = 'Permission Request', nonce, } = options;
|
|
255
|
+
const configJson = JSON.stringify(config);
|
|
256
|
+
const scopesJson = JSON.stringify(scopes);
|
|
257
|
+
const oauthJson = oauthIdentity ? JSON.stringify(oauthIdentity) : null;
|
|
258
|
+
const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : '';
|
|
259
|
+
return `<!DOCTYPE html>
|
|
260
|
+
<html lang="en">
|
|
261
|
+
<head>
|
|
262
|
+
<meta charset="UTF-8">
|
|
263
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
264
|
+
<title>${escapeHtml(pageTitle)}</title>
|
|
265
|
+
<script type="module"${nonceAttr}>
|
|
266
|
+
${bundleSource}
|
|
267
|
+
</script>
|
|
268
|
+
<style${nonceAttr}>
|
|
269
|
+
body {
|
|
270
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
271
|
+
background: #f3f4f6;
|
|
272
|
+
min-height: 100vh;
|
|
273
|
+
margin: 0;
|
|
274
|
+
display: flex;
|
|
275
|
+
align-items: center;
|
|
276
|
+
justify-content: center;
|
|
277
|
+
padding: 1rem;
|
|
278
|
+
}
|
|
279
|
+
</style>
|
|
280
|
+
</head>
|
|
281
|
+
<body>
|
|
282
|
+
<mcp-consent
|
|
283
|
+
config='${escapeAttr(configJson)}'
|
|
284
|
+
tool="${escapeAttr(tool)}"
|
|
285
|
+
scopes='${escapeAttr(scopesJson)}'
|
|
286
|
+
agent-did="${escapeAttr(agentDid)}"
|
|
287
|
+
session-id="${escapeAttr(sessionId)}"
|
|
288
|
+
project-id="${escapeAttr(projectId)}"
|
|
289
|
+
server-url="${escapeAttr(serverUrl)}"
|
|
290
|
+
${oauthJson ? `oauth-identity='${escapeAttr(oauthJson)}'` : ''}
|
|
291
|
+
></mcp-consent>
|
|
292
|
+
</body>
|
|
293
|
+
</html>`;
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=shell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/bundle/shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAwE/D;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA4B;IAC/D,MAAM,EACJ,MAAM,EACN,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,aAAa,EACb,UAAU,GAAG,aAAa,EAC1B,SAAS,GAAG,oBAAoB,EAChC,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,sBAAsB,EACtB,kBAAkB,EAClB,OAAO,EAAE,2CAA2C;IACpD,mBAAmB,EAAE,sCAAsC;IAC3D,wBAAwB,EAAE,yCAAyC;IACnE,QAAQ,EAAE,oCAAoC;IAC9C,iBAAiB,EAAE,kDAAkD;MACtE,GAAG,OAAO,CAAC;IAEZ,gDAAgD;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,oCAAoC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,OAAO;;;;;;WAME,UAAU,CAAC,SAAS,CAAC;;;8BAGF,UAAU,CAAC,UAAU,CAAC;;;+BAGrB,UAAU,CAAC,UAAU,CAAC,IAAI,SAAS;;UAExD,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAkHL,UAAU,CAAC,UAAU,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC;cACd,UAAU,CAAC,UAAU,CAAC;iBACnB,UAAU,CAAC,QAAQ,CAAC;kBACnB,UAAU,CAAC,SAAS,CAAC;kBACrB,UAAU,CAAC,SAAS,CAAC;kBACrB,UAAU,CAAC,SAAS,CAAC;MACjC,SAAS,CAAC,CAAC,CAAC,mBAAmB,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MAC5D,QAAQ,CAAC,CAAC,CAAC,cAAc,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MACrD,QAAQ,CAAC,CAAC,CAAC,aAAa,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MACpD,SAAS,CAAC,CAAC,CAAC,eAAe,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MACxD,sBAAsB,CAAC,CAAC,CAAC,6BAA6B,UAAU,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MAChG,kBAAkB,CAAC,CAAC,CAAC,wBAAwB,UAAU,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MACnF,OAAO,CAAC,CAAC,CAAC,aAAa,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MAClD,mBAAmB,CAAC,CAAC,CAAC,0BAA0B,UAAU,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MACvF,wBAAwB,CAAC,CAAC,CAAC,gCAAgC,UAAU,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MACvG,QAAQ,CAAC,CAAC,CAAC,cAAc,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;MACrD,iBAAiB,CAAC,CAAC,CAAC,uBAAuB,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;wDAoB9B,UAAU,CAAC,SAAS,CAAC;;;;gDAI7B,UAAU,CAAC,IAAI,CAAC;kDACd,UAAU,CAAC,UAAU,CAAC;qDACnB,UAAU,CAAC,QAAQ,CAAC;sDACnB,UAAU,CAAC,SAAS,CAAC;sDACrB,UAAU,CAAC,SAAS,CAAC;;;;;;;;QAQnE,CAAC;AACT,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAAgD,EAChD,YAAoB;IAEpB,MAAM,EACJ,MAAM,EACN,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,SAAS,EACT,SAAS,EACT,SAAS,EACT,aAAa,EACb,SAAS,GAAG,oBAAoB,EAChC,KAAK,GACN,GAAG,OAAO,CAAC;IAEZ,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,OAAO;;;;;WAKE,UAAU,CAAC,SAAS,CAAC;yBACP,SAAS;EAChC,YAAY;;UAEJ,SAAS;;;;;;;;;;;;;;;cAeL,UAAU,CAAC,UAAU,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC;cACd,UAAU,CAAC,UAAU,CAAC;iBACnB,UAAU,CAAC,QAAQ,CAAC;kBACnB,UAAU,CAAC,SAAS,CAAC;kBACrB,UAAU,CAAC,SAAS,CAAC;kBACrB,UAAU,CAAC,SAAS,CAAC;MACjC,SAAS,CAAC,CAAC,CAAC,mBAAmB,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;;;QAG1D,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consent Button Web Component
|
|
3
|
+
*
|
|
4
|
+
* A styled button for consent pages that works in:
|
|
5
|
+
* - Browser (vanilla HTML)
|
|
6
|
+
* - React (via @lit/react wrapper)
|
|
7
|
+
* - SSR (Declarative Shadow DOM)
|
|
8
|
+
*
|
|
9
|
+
* @module components/consent-button
|
|
10
|
+
*/
|
|
11
|
+
import { LitElement } from 'lit';
|
|
12
|
+
/**
|
|
13
|
+
* Button variants matching AgentShield design system
|
|
14
|
+
*/
|
|
15
|
+
export type ButtonVariant = 'primary' | 'secondary';
|
|
16
|
+
/**
|
|
17
|
+
* ConsentButton - A themed button component
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```html
|
|
21
|
+
* <consent-button variant="primary">Allow Access</consent-button>
|
|
22
|
+
* <consent-button variant="secondary">Cancel</consent-button>
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @csspart button - The native button element
|
|
26
|
+
* @cssprop --consent-primary - Primary brand color (default: #2563EB)
|
|
27
|
+
*/
|
|
28
|
+
export declare class ConsentButton extends LitElement {
|
|
29
|
+
static formAssociated: boolean;
|
|
30
|
+
private internals;
|
|
31
|
+
constructor();
|
|
32
|
+
/**
|
|
33
|
+
* Button variant - 'primary' (filled) or 'secondary' (outlined)
|
|
34
|
+
*/
|
|
35
|
+
variant: ButtonVariant;
|
|
36
|
+
/**
|
|
37
|
+
* Button type attribute (button, submit, reset)
|
|
38
|
+
*/
|
|
39
|
+
type: 'button' | 'submit' | 'reset';
|
|
40
|
+
/**
|
|
41
|
+
* Disabled state
|
|
42
|
+
*/
|
|
43
|
+
disabled: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Full width mode
|
|
46
|
+
*/
|
|
47
|
+
fullWidth: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Loading state - shows spinner and disables button
|
|
50
|
+
*/
|
|
51
|
+
loading: boolean;
|
|
52
|
+
static styles: import("lit").CSSResult;
|
|
53
|
+
private handleClick;
|
|
54
|
+
render(): import("lit").TemplateResult<1>;
|
|
55
|
+
}
|
|
56
|
+
declare global {
|
|
57
|
+
interface HTMLElementTagNameMap {
|
|
58
|
+
'consent-button': ConsentButton;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=consent-button.d.ts.map
|