@kya-os/consent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/dist/constants/auth-modes.d.ts +54 -0
  2. package/dist/constants/auth-modes.d.ts.map +1 -0
  3. package/dist/constants/auth-modes.js +128 -0
  4. package/dist/constants/auth-modes.js.map +1 -0
  5. package/dist/constants/colors.d.ts +38 -0
  6. package/dist/constants/colors.d.ts.map +1 -0
  7. package/dist/constants/colors.js +40 -0
  8. package/dist/constants/colors.js.map +1 -0
  9. package/dist/constants/defaults.d.ts +112 -0
  10. package/dist/constants/defaults.d.ts.map +1 -0
  11. package/dist/constants/defaults.js +146 -0
  12. package/dist/constants/defaults.js.map +1 -0
  13. package/dist/constants/index.d.ts +11 -0
  14. package/dist/constants/index.d.ts.map +1 -0
  15. package/dist/constants/index.js +37 -0
  16. package/dist/constants/index.js.map +1 -0
  17. package/dist/index.d.ts +16 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +39 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/resolution/index.d.ts +12 -0
  22. package/dist/resolution/index.d.ts.map +1 -0
  23. package/dist/resolution/index.js +28 -0
  24. package/dist/resolution/index.js.map +1 -0
  25. package/dist/resolution/resolve-branding.d.ts +70 -0
  26. package/dist/resolution/resolve-branding.d.ts.map +1 -0
  27. package/dist/resolution/resolve-branding.js +159 -0
  28. package/dist/resolution/resolve-branding.js.map +1 -0
  29. package/dist/resolution/resolve-config.d.ts +81 -0
  30. package/dist/resolution/resolve-config.d.ts.map +1 -0
  31. package/dist/resolution/resolve-config.js +254 -0
  32. package/dist/resolution/resolve-config.js.map +1 -0
  33. package/dist/resolution/resolve-copy.d.ts +53 -0
  34. package/dist/resolution/resolve-copy.d.ts.map +1 -0
  35. package/dist/resolution/resolve-copy.js +136 -0
  36. package/dist/resolution/resolve-copy.js.map +1 -0
  37. package/dist/schemas/api.schemas.d.ts +984 -0
  38. package/dist/schemas/api.schemas.d.ts.map +1 -0
  39. package/dist/schemas/api.schemas.js +153 -0
  40. package/dist/schemas/api.schemas.js.map +1 -0
  41. package/dist/schemas/branding.schemas.d.ts +100 -0
  42. package/dist/schemas/branding.schemas.d.ts.map +1 -0
  43. package/dist/schemas/branding.schemas.js +57 -0
  44. package/dist/schemas/branding.schemas.js.map +1 -0
  45. package/dist/schemas/config.schemas.d.ts +1182 -0
  46. package/dist/schemas/config.schemas.d.ts.map +1 -0
  47. package/dist/schemas/config.schemas.js +147 -0
  48. package/dist/schemas/config.schemas.js.map +1 -0
  49. package/dist/schemas/index.d.ts +13 -0
  50. package/dist/schemas/index.d.ts.map +1 -0
  51. package/dist/schemas/index.js +29 -0
  52. package/dist/schemas/index.js.map +1 -0
  53. package/dist/schemas/modes.schemas.d.ts +406 -0
  54. package/dist/schemas/modes.schemas.d.ts.map +1 -0
  55. package/dist/schemas/modes.schemas.js +107 -0
  56. package/dist/schemas/modes.schemas.js.map +1 -0
  57. package/dist/security/escape.d.ts +114 -0
  58. package/dist/security/escape.d.ts.map +1 -0
  59. package/dist/security/escape.js +202 -0
  60. package/dist/security/escape.js.map +1 -0
  61. package/dist/security/index.d.ts +10 -0
  62. package/dist/security/index.d.ts.map +1 -0
  63. package/dist/security/index.js +26 -0
  64. package/dist/security/index.js.map +1 -0
  65. package/dist/security/validators.d.ts +98 -0
  66. package/dist/security/validators.d.ts.map +1 -0
  67. package/dist/security/validators.js +210 -0
  68. package/dist/security/validators.js.map +1 -0
  69. package/dist/styles/css-variables.d.ts +78 -0
  70. package/dist/styles/css-variables.d.ts.map +1 -0
  71. package/dist/styles/css-variables.js +129 -0
  72. package/dist/styles/css-variables.js.map +1 -0
  73. package/dist/styles/index.d.ts +12 -0
  74. package/dist/styles/index.d.ts.map +1 -0
  75. package/dist/styles/index.js +28 -0
  76. package/dist/styles/index.js.map +1 -0
  77. package/dist/styles/stylesheet.d.ts +57 -0
  78. package/dist/styles/stylesheet.d.ts.map +1 -0
  79. package/dist/styles/stylesheet.js +204 -0
  80. package/dist/styles/stylesheet.js.map +1 -0
  81. package/dist/styles/tokens.d.ts +141 -0
  82. package/dist/styles/tokens.d.ts.map +1 -0
  83. package/dist/styles/tokens.js +183 -0
  84. package/dist/styles/tokens.js.map +1 -0
  85. package/dist/templates/base/base-template.d.ts +81 -0
  86. package/dist/templates/base/base-template.d.ts.map +1 -0
  87. package/dist/templates/base/base-template.js +282 -0
  88. package/dist/templates/base/base-template.js.map +1 -0
  89. package/dist/templates/base/components.d.ts +120 -0
  90. package/dist/templates/base/components.d.ts.map +1 -0
  91. package/dist/templates/base/components.js +295 -0
  92. package/dist/templates/base/components.js.map +1 -0
  93. package/dist/templates/base/index.d.ts +8 -0
  94. package/dist/templates/base/index.d.ts.map +1 -0
  95. package/dist/templates/base/index.js +26 -0
  96. package/dist/templates/base/index.js.map +1 -0
  97. package/dist/templates/index.d.ts +18 -0
  98. package/dist/templates/index.d.ts.map +1 -0
  99. package/dist/templates/index.js +34 -0
  100. package/dist/templates/index.js.map +1 -0
  101. package/dist/templates/modes/consent-only.template.d.ts +36 -0
  102. package/dist/templates/modes/consent-only.template.d.ts.map +1 -0
  103. package/dist/templates/modes/consent-only.template.js +74 -0
  104. package/dist/templates/modes/consent-only.template.js.map +1 -0
  105. package/dist/templates/modes/credentials.template.d.ts +65 -0
  106. package/dist/templates/modes/credentials.template.d.ts.map +1 -0
  107. package/dist/templates/modes/credentials.template.js +414 -0
  108. package/dist/templates/modes/credentials.template.js.map +1 -0
  109. package/dist/templates/modes/index.d.ts +14 -0
  110. package/dist/templates/modes/index.d.ts.map +1 -0
  111. package/dist/templates/modes/index.js +24 -0
  112. package/dist/templates/modes/index.js.map +1 -0
  113. package/dist/templates/modes/magic-link.template.d.ts +33 -0
  114. package/dist/templates/modes/magic-link.template.d.ts.map +1 -0
  115. package/dist/templates/modes/magic-link.template.js +196 -0
  116. package/dist/templates/modes/magic-link.template.js.map +1 -0
  117. package/dist/templates/modes/oauth.template.d.ts +40 -0
  118. package/dist/templates/modes/oauth.template.d.ts.map +1 -0
  119. package/dist/templates/modes/oauth.template.js +153 -0
  120. package/dist/templates/modes/oauth.template.js.map +1 -0
  121. package/dist/templates/modes/otp.template.d.ts +35 -0
  122. package/dist/templates/modes/otp.template.d.ts.map +1 -0
  123. package/dist/templates/modes/otp.template.js +316 -0
  124. package/dist/templates/modes/otp.template.js.map +1 -0
  125. package/dist/templates/modes/success.template.d.ts +41 -0
  126. package/dist/templates/modes/success.template.d.ts.map +1 -0
  127. package/dist/templates/modes/success.template.js +140 -0
  128. package/dist/templates/modes/success.template.js.map +1 -0
  129. package/dist/templates/registry.d.ts +62 -0
  130. package/dist/templates/registry.d.ts.map +1 -0
  131. package/dist/templates/registry.js +135 -0
  132. package/dist/templates/registry.js.map +1 -0
  133. package/dist/types/api.types.d.ts +134 -0
  134. package/dist/types/api.types.d.ts.map +1 -0
  135. package/dist/types/api.types.js +10 -0
  136. package/dist/types/api.types.js.map +1 -0
  137. package/dist/types/branding.types.d.ts +53 -0
  138. package/dist/types/branding.types.d.ts.map +1 -0
  139. package/dist/types/branding.types.js +10 -0
  140. package/dist/types/branding.types.js.map +1 -0
  141. package/dist/types/config.types.d.ts +201 -0
  142. package/dist/types/config.types.d.ts.map +1 -0
  143. package/dist/types/config.types.js +10 -0
  144. package/dist/types/config.types.js.map +1 -0
  145. package/dist/types/copy.types.d.ts +109 -0
  146. package/dist/types/copy.types.d.ts.map +1 -0
  147. package/dist/types/copy.types.js +10 -0
  148. package/dist/types/copy.types.js.map +1 -0
  149. package/dist/types/index.d.ts +15 -0
  150. package/dist/types/index.d.ts.map +1 -0
  151. package/dist/types/index.js +31 -0
  152. package/dist/types/index.js.map +1 -0
  153. package/dist/types/modes.types.d.ts +197 -0
  154. package/dist/types/modes.types.d.ts.map +1 -0
  155. package/dist/types/modes.types.js +35 -0
  156. package/dist/types/modes.types.js.map +1 -0
  157. package/dist/types/page.types.d.ts +120 -0
  158. package/dist/types/page.types.d.ts.map +1 -0
  159. package/dist/types/page.types.js +10 -0
  160. package/dist/types/page.types.js.map +1 -0
  161. package/package.json +83 -0
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ /**
3
+ * OTP Template
4
+ *
5
+ * One-Time Password authentication via SMS/email.
6
+ *
7
+ * @module @kya-os/consent/templates/modes/otp
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.OTPTemplate = void 0;
11
+ const base_template_1 = require("../base/base-template");
12
+ const components_1 = require("../base/components");
13
+ const escape_1 = require("../../security/escape");
14
+ const modes_types_1 = require("../../types/modes.types");
15
+ /**
16
+ * OTP Template
17
+ *
18
+ * Renders a two-step OTP flow:
19
+ * 1. Phone/email input to request code
20
+ * 2. Code input to verify
21
+ */
22
+ class OTPTemplate extends base_template_1.BaseConsentTemplate {
23
+ get authMode() {
24
+ return modes_types_1.AUTH_MODES.OTP;
25
+ }
26
+ get otpConfig() {
27
+ return this.config.modeConfig?.otp;
28
+ }
29
+ renderAuthContent() {
30
+ const config = this.otpConfig;
31
+ const digits = config?.digits || 6;
32
+ return `
33
+ <div id="otp-request-container">
34
+ <form id="otp-request-form" class="space-y-4">
35
+ ${this.renderPhoneField(config)}
36
+ ${(0, components_1.renderErrorContainer)("otp-request-error")}
37
+ ${(0, components_1.renderFullWidthButton)("Send verification code", "submit")}
38
+ </form>
39
+ </div>
40
+ <div id="otp-verify-container" class="hidden">
41
+ <form id="otp-verify-form" class="space-y-4">
42
+ <div class="text-center mb-4">
43
+ <p class="text-sm text-gray-600">
44
+ ${(0, escape_1.escapeHtml)(config?.instructions || `Enter the ${digits}-digit code sent to your phone`)}
45
+ </p>
46
+ </div>
47
+ <div class="flex justify-center gap-2" id="otp-inputs">
48
+ ${this.renderOTPInputs(digits)}
49
+ </div>
50
+ ${(0, components_1.renderErrorContainer)("otp-verify-error")}
51
+ ${(0, components_1.renderFullWidthButton)("Verify", "submit")}
52
+ <div class="text-center">
53
+ <button type="button" id="resend-otp" class="text-sm link-primary disabled:opacity-50">
54
+ Resend code
55
+ </button>
56
+ </div>
57
+ </form>
58
+ </div>
59
+ `;
60
+ }
61
+ /**
62
+ * Render phone/email input field.
63
+ */
64
+ renderPhoneField(config) {
65
+ return (0, components_1.renderInput)("tel", "phone", config?.phoneLabel || "Phone number", config?.phonePlaceholder || "+1 (555) 123-4567", true, "tel");
66
+ }
67
+ /**
68
+ * Render OTP digit input boxes.
69
+ */
70
+ renderOTPInputs(digits) {
71
+ const inputs = [];
72
+ for (let i = 0; i < digits; i++) {
73
+ inputs.push(`
74
+ <input type="text" inputmode="numeric" pattern="[0-9]" maxlength="1"
75
+ class="w-12 h-14 text-center text-2xl font-bold border border-gray-300 rounded-lg shadow-sm focus-primary"
76
+ data-otp-index="${i}"
77
+ autocomplete="one-time-code" />
78
+ `);
79
+ }
80
+ return inputs.join("");
81
+ }
82
+ /**
83
+ * Override action buttons - form has its own submit.
84
+ */
85
+ renderActionButtons() {
86
+ return "";
87
+ }
88
+ renderModeScript() {
89
+ const serverUrl = (0, escape_1.escapeJs)(this.config.serverUrl);
90
+ const projectId = (0, escape_1.escapeJs)(this.config.projectId);
91
+ const sessionId = (0, escape_1.escapeJs)(this.config.sessionId);
92
+ const agentDid = (0, escape_1.escapeJs)(this.config.agentDid);
93
+ const tool = (0, escape_1.escapeJs)(this.config.tool);
94
+ const scopes = JSON.stringify(this.config.scopes);
95
+ const digits = this.otpConfig?.digits || 6;
96
+ const resendCooldown = this.otpConfig?.resendCooldown || 60;
97
+ return `
98
+ <script>
99
+ (function() {
100
+ const requestContainer = document.getElementById('otp-request-container');
101
+ const verifyContainer = document.getElementById('otp-verify-container');
102
+ const requestForm = document.getElementById('otp-request-form');
103
+ const verifyForm = document.getElementById('otp-verify-form');
104
+ const resendBtn = document.getElementById('resend-otp');
105
+ const otpInputs = document.querySelectorAll('[data-otp-index]');
106
+
107
+ const serverUrl = ${serverUrl};
108
+ const digits = ${digits};
109
+ const cooldown = ${resendCooldown};
110
+ let lastPhone = '';
111
+ let verificationId = '';
112
+
113
+ function getError(id) {
114
+ const container = document.getElementById(id);
115
+ return { container, div: container?.querySelector('div') };
116
+ }
117
+
118
+ function showError(id, message) {
119
+ const { container, div } = getError(id);
120
+ if (div) {
121
+ div.textContent = message;
122
+ container.classList.remove('hidden');
123
+ }
124
+ }
125
+
126
+ function hideError(id) {
127
+ const { container } = getError(id);
128
+ if (container) container.classList.add('hidden');
129
+ }
130
+
131
+ // OTP input auto-focus behavior
132
+ otpInputs.forEach((input, idx) => {
133
+ input.addEventListener('input', (e) => {
134
+ const value = e.target.value;
135
+ if (value && idx < otpInputs.length - 1) {
136
+ otpInputs[idx + 1].focus();
137
+ }
138
+ });
139
+
140
+ input.addEventListener('keydown', (e) => {
141
+ if (e.key === 'Backspace' && !e.target.value && idx > 0) {
142
+ otpInputs[idx - 1].focus();
143
+ }
144
+ });
145
+
146
+ input.addEventListener('paste', (e) => {
147
+ e.preventDefault();
148
+ const paste = (e.clipboardData || window.clipboardData).getData('text');
149
+ const chars = paste.replace(/\\D/g, '').slice(0, digits).split('');
150
+ chars.forEach((char, i) => {
151
+ if (otpInputs[i]) otpInputs[i].value = char;
152
+ });
153
+ if (chars.length > 0 && otpInputs[chars.length - 1]) {
154
+ otpInputs[chars.length - 1].focus();
155
+ }
156
+ });
157
+ });
158
+
159
+ // Request OTP
160
+ requestForm?.addEventListener('submit', async (e) => {
161
+ e.preventDefault();
162
+ hideError('otp-request-error');
163
+
164
+ const button = requestForm.querySelector('button[type="submit"]');
165
+ const phoneInput = requestForm.querySelector('input[name="phone"]');
166
+ lastPhone = phoneInput.value;
167
+
168
+ button.disabled = true;
169
+ button.textContent = 'Sending...';
170
+
171
+ try {
172
+ const response = await fetch(serverUrl + '/consent/otp/request', {
173
+ method: 'POST',
174
+ headers: { 'Content-Type': 'application/json' },
175
+ body: JSON.stringify({
176
+ phone: lastPhone,
177
+ tool: ${tool},
178
+ scopes: ${scopes},
179
+ agent_did: ${agentDid},
180
+ session_id: ${sessionId},
181
+ project_id: ${projectId},
182
+ })
183
+ });
184
+
185
+ const result = await response.json();
186
+
187
+ if (result.success) {
188
+ verificationId = result.verificationId || '';
189
+ requestContainer.classList.add('hidden');
190
+ verifyContainer.classList.remove('hidden');
191
+ otpInputs[0]?.focus();
192
+ startResendCooldown();
193
+ } else {
194
+ showError('otp-request-error', result.error || 'Failed to send code');
195
+ button.disabled = false;
196
+ button.textContent = 'Send verification code';
197
+ }
198
+ } catch (err) {
199
+ showError('otp-request-error', 'Network error. Please try again.');
200
+ button.disabled = false;
201
+ button.textContent = 'Send verification code';
202
+ }
203
+ });
204
+
205
+ // Verify OTP
206
+ verifyForm?.addEventListener('submit', async (e) => {
207
+ e.preventDefault();
208
+ hideError('otp-verify-error');
209
+
210
+ const button = verifyForm.querySelector('button[type="submit"]');
211
+ const code = Array.from(otpInputs).map(i => i.value).join('');
212
+
213
+ if (code.length !== digits) {
214
+ showError('otp-verify-error', 'Please enter the full code');
215
+ return;
216
+ }
217
+
218
+ button.disabled = true;
219
+ button.textContent = 'Verifying...';
220
+
221
+ try {
222
+ const response = await fetch(serverUrl + '/consent/otp/verify', {
223
+ method: 'POST',
224
+ headers: { 'Content-Type': 'application/json' },
225
+ body: JSON.stringify({
226
+ phone: lastPhone,
227
+ code: code,
228
+ verification_id: verificationId,
229
+ tool: ${tool},
230
+ scopes: ${scopes},
231
+ agent_did: ${agentDid},
232
+ session_id: ${sessionId},
233
+ project_id: ${projectId},
234
+ })
235
+ });
236
+
237
+ const result = await response.json();
238
+
239
+ if (result.success) {
240
+ button.textContent = 'Success!';
241
+ button.style.backgroundColor = '#10B981';
242
+
243
+ if (result.redirectUrl) {
244
+ window.location.href = result.redirectUrl;
245
+ } else if (result.delegation_id) {
246
+ window.location.href = serverUrl + '/consent/success?delegation_id=' +
247
+ encodeURIComponent(result.delegation_id) +
248
+ '&project_id=' + encodeURIComponent(${projectId});
249
+ }
250
+ } else {
251
+ showError('otp-verify-error', result.error || 'Invalid code');
252
+ button.disabled = false;
253
+ button.textContent = 'Verify';
254
+ }
255
+ } catch (err) {
256
+ showError('otp-verify-error', 'Network error. Please try again.');
257
+ button.disabled = false;
258
+ button.textContent = 'Verify';
259
+ }
260
+ });
261
+
262
+ // Resend cooldown
263
+ function startResendCooldown() {
264
+ resendBtn.disabled = true;
265
+ let remaining = cooldown;
266
+ resendBtn.textContent = 'Resend code (' + remaining + 's)';
267
+
268
+ const timer = setInterval(() => {
269
+ remaining--;
270
+ if (remaining <= 0) {
271
+ clearInterval(timer);
272
+ resendBtn.disabled = false;
273
+ resendBtn.textContent = 'Resend code';
274
+ } else {
275
+ resendBtn.textContent = 'Resend code (' + remaining + 's)';
276
+ }
277
+ }, 1000);
278
+ }
279
+
280
+ resendBtn?.addEventListener('click', async () => {
281
+ if (resendBtn.disabled) return;
282
+
283
+ resendBtn.disabled = true;
284
+ try {
285
+ const response = await fetch(serverUrl + '/consent/otp/request', {
286
+ method: 'POST',
287
+ headers: { 'Content-Type': 'application/json' },
288
+ body: JSON.stringify({
289
+ phone: lastPhone,
290
+ tool: ${tool},
291
+ scopes: ${scopes},
292
+ agent_did: ${agentDid},
293
+ session_id: ${sessionId},
294
+ project_id: ${projectId},
295
+ })
296
+ });
297
+
298
+ const result = await response.json();
299
+ if (result.success) {
300
+ verificationId = result.verificationId || verificationId;
301
+ startResendCooldown();
302
+ } else {
303
+ resendBtn.disabled = false;
304
+ alert(result.error || 'Failed to resend');
305
+ }
306
+ } catch (err) {
307
+ resendBtn.disabled = false;
308
+ alert('Network error');
309
+ }
310
+ });
311
+ })();
312
+ </script>`;
313
+ }
314
+ }
315
+ exports.OTPTemplate = OTPTemplate;
316
+ //# sourceMappingURL=otp.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otp.template.js","sourceRoot":"","sources":["../../../src/templates/modes/otp.template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Success Page Template
3
+ *
4
+ * Rendered after successful consent approval.
5
+ *
6
+ * @module @kya-os/consent/templates/modes/success
7
+ */
8
+ import type { SuccessPageConfig } from "../../types/page.types";
9
+ import type { ResolvedConsentBranding } from "../../types/branding.types";
10
+ /**
11
+ * Success Page Template
12
+ *
13
+ * Standalone template for the success page (not extending BaseConsentTemplate).
14
+ * Renders a simple confirmation after consent is granted.
15
+ */
16
+ export declare class SuccessTemplate {
17
+ private config;
18
+ private branding;
19
+ constructor(config: SuccessPageConfig, branding?: Partial<ResolvedConsentBranding>);
20
+ /**
21
+ * Render the success page.
22
+ */
23
+ render(): string;
24
+ /**
25
+ * Render the <head> section.
26
+ */
27
+ private renderHead;
28
+ /**
29
+ * Render credential/delegation info.
30
+ */
31
+ private renderCredentialInfo;
32
+ /**
33
+ * Render client-side script.
34
+ */
35
+ private renderScript;
36
+ }
37
+ /**
38
+ * Render a success page with the given configuration.
39
+ */
40
+ export declare function renderSuccessPage(config: SuccessPageConfig, branding?: Partial<ResolvedConsentBranding>): string;
41
+ //# sourceMappingURL=success.template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"success.template.d.ts","sourceRoot":"","sources":["../../../src/templates/modes/success.template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAK1E;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,QAAQ,CAA0B;gBAE9B,MAAM,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC;IAkBlF;;OAEG;IACH,MAAM,IAAI,MAAM;IA6BhB;;OAEG;IACH,OAAO,CAAC,UAAU;IAalB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,OAAO,CAAC,YAAY;CA2BrB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,QAAQ,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAC1C,MAAM,CAGR"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ /**
3
+ * Success Page Template
4
+ *
5
+ * Rendered after successful consent approval.
6
+ *
7
+ * @module @kya-os/consent/templates/modes/success
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.SuccessTemplate = void 0;
11
+ exports.renderSuccessPage = renderSuccessPage;
12
+ const tokens_1 = require("../../styles/tokens");
13
+ const stylesheet_1 = require("../../styles/stylesheet");
14
+ const components_1 = require("../base/components");
15
+ const escape_1 = require("../../security/escape");
16
+ const colors_1 = require("../../constants/colors");
17
+ const defaults_1 = require("../../constants/defaults");
18
+ const css_variables_1 = require("../../styles/css-variables");
19
+ /**
20
+ * Success Page Template
21
+ *
22
+ * Standalone template for the success page (not extending BaseConsentTemplate).
23
+ * Renders a simple confirmation after consent is granted.
24
+ */
25
+ class SuccessTemplate {
26
+ constructor(config, branding) {
27
+ this.config = config;
28
+ const primaryColor = branding?.primaryColor || colors_1.DEFAULT_COLORS.PRIMARY;
29
+ const secondaryColor = branding?.secondaryColor || colors_1.DEFAULT_COLORS.SECONDARY;
30
+ this.branding = {
31
+ primaryColor,
32
+ secondaryColor,
33
+ logoUrl: branding?.logoUrl,
34
+ companyName: branding?.companyName,
35
+ cssVars: {
36
+ "--consent-primary": primaryColor,
37
+ "--consent-secondary": secondaryColor,
38
+ "--consent-primary-rgb": (0, css_variables_1.hexToRgb)(primaryColor),
39
+ "--consent-secondary-rgb": (0, css_variables_1.hexToRgb)(secondaryColor),
40
+ },
41
+ };
42
+ }
43
+ /**
44
+ * Render the success page.
45
+ */
46
+ render() {
47
+ const title = this.config.title || defaults_1.DEFAULT_SUCCESS.title;
48
+ const description = this.config.description || defaults_1.DEFAULT_SUCCESS.description;
49
+ const buttonText = this.config.continueButtonText || defaults_1.DEFAULT_SUCCESS.continueButtonText;
50
+ return `<!DOCTYPE html>
51
+ <html lang="en">
52
+ <head>
53
+ ${this.renderHead()}
54
+ </head>
55
+ <body class="bg-gray-50 min-h-screen flex items-center justify-center p-4">
56
+ <div class="${tokens_1.CONSENT_CLASSES.container}">
57
+ <div class="${tokens_1.CONSENT_CLASSES.content}">
58
+ <div class="text-center py-8">
59
+ ${(0, components_1.renderSuccessIcon)()}
60
+ <h1 class="${tokens_1.CONSENT_CLASSES.title} mb-4">${(0, escape_1.escapeHtml)(title)}</h1>
61
+ <p class="text-gray-600 mb-8">${(0, escape_1.escapeHtml)(description)}</p>
62
+ ${this.renderCredentialInfo()}
63
+ <div class="mt-6">
64
+ ${(0, components_1.renderFullWidthButton)(buttonText, "button")}
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </div>
69
+ ${this.renderScript()}
70
+ </body>
71
+ </html>`;
72
+ }
73
+ /**
74
+ * Render the <head> section.
75
+ */
76
+ renderHead() {
77
+ return `
78
+ <meta charset="UTF-8">
79
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
80
+ <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; style-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; img-src 'self' data: https:; font-src 'self' data:;">
81
+ <title>Access Granted</title>
82
+ <script src="https://cdn.tailwindcss.com"></script>
83
+ <style>
84
+ ${(0, stylesheet_1.generateHeadStyles)(this.branding)}
85
+ </style>
86
+ `;
87
+ }
88
+ /**
89
+ * Render credential/delegation info.
90
+ */
91
+ renderCredentialInfo() {
92
+ if (!this.config.delegationId) {
93
+ return "";
94
+ }
95
+ return `
96
+ <div class="bg-gray-50 rounded-lg p-4 mb-4">
97
+ <p class="text-xs text-gray-500 uppercase tracking-wide mb-1">Delegation ID</p>
98
+ <p class="text-sm font-mono text-gray-700 break-all">${(0, escape_1.escapeHtml)(this.config.delegationId)}</p>
99
+ </div>
100
+ `;
101
+ }
102
+ /**
103
+ * Render client-side script.
104
+ */
105
+ renderScript() {
106
+ const autoClose = this.config.autoClose ?? false;
107
+ return `
108
+ <script>
109
+ (function() {
110
+ const closeBtn = document.querySelector('button');
111
+ const autoClose = ${autoClose};
112
+
113
+ if (closeBtn) {
114
+ closeBtn.addEventListener('click', function() {
115
+ window.close();
116
+ // If window.close() doesn't work (not opened by script), redirect home
117
+ setTimeout(function() {
118
+ window.location.href = '/';
119
+ }, 100);
120
+ });
121
+ }
122
+
123
+ if (autoClose) {
124
+ setTimeout(function() {
125
+ window.close();
126
+ }, 3000);
127
+ }
128
+ })();
129
+ </script>`;
130
+ }
131
+ }
132
+ exports.SuccessTemplate = SuccessTemplate;
133
+ /**
134
+ * Render a success page with the given configuration.
135
+ */
136
+ function renderSuccessPage(config, branding) {
137
+ const template = new SuccessTemplate(config, branding);
138
+ return template.render();
139
+ }
140
+ //# sourceMappingURL=success.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"success.template.js","sourceRoot":"","sources":["../../../src/templates/modes/success.template.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AA2IH,8CAMC;AA/ID,gDAAsD;AACtD,wDAA6D;AAC7D,mDAA8E;AAC9E,kDAAmD;AAGnD,mDAAwD;AACxD,uDAA2D;AAC3D,8DAAsD;AAEtD;;;;;GAKG;AACH,MAAa,eAAe;IAI1B,YAAY,MAAyB,EAAE,QAA2C;QAChF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,MAAM,YAAY,GAAG,QAAQ,EAAE,YAAY,IAAI,uBAAc,CAAC,OAAO,CAAC;QACtE,MAAM,cAAc,GAAG,QAAQ,EAAE,cAAc,IAAI,uBAAc,CAAC,SAAS,CAAC;QAC5E,IAAI,CAAC,QAAQ,GAAG;YACd,YAAY;YACZ,cAAc;YACd,OAAO,EAAE,QAAQ,EAAE,OAAO;YAC1B,WAAW,EAAE,QAAQ,EAAE,WAAW;YAClC,OAAO,EAAE;gBACP,mBAAmB,EAAE,YAAY;gBACjC,qBAAqB,EAAE,cAAc;gBACrC,uBAAuB,EAAE,IAAA,wBAAQ,EAAC,YAAY,CAAC;gBAC/C,yBAAyB,EAAE,IAAA,wBAAQ,EAAC,cAAc,CAAC;aACpD;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,0BAAe,CAAC,KAAK,CAAC;QACzD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,0BAAe,CAAC,WAAW,CAAC;QAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,0BAAe,CAAC,kBAAkB,CAAC;QAExF,OAAO;;;IAGP,IAAI,CAAC,UAAU,EAAE;;;gBAGL,wBAAe,CAAC,SAAS;kBACvB,wBAAe,CAAC,OAAO;;UAE/B,IAAA,8BAAiB,GAAE;qBACR,wBAAe,CAAC,KAAK,UAAU,IAAA,mBAAU,EAAC,KAAK,CAAC;wCAC7B,IAAA,mBAAU,EAAC,WAAW,CAAC;UACrD,IAAI,CAAC,oBAAoB,EAAE;;YAEzB,IAAA,kCAAqB,EAAC,UAAU,EAAE,QAAQ,CAAC;;;;;IAKnD,IAAI,CAAC,YAAY,EAAE;;QAEf,CAAC;IACP,CAAC;IAED;;OAEG;IACK,UAAU;QAChB,OAAO;;;;;;;UAOD,IAAA,+BAAkB,EAAC,IAAI,CAAC,QAAQ,CAAC;;KAEtC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,oBAAoB;QAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YAC9B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO;;;+DAGoD,IAAA,mBAAU,EAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;;KAE9F,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,YAAY;QAClB,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC;QAEjD,OAAO;;;;sBAIW,SAAS;;;;;;;;;;;;;;;;;;UAkBrB,CAAC;IACT,CAAC;CACF;AApHD,0CAoHC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAC/B,MAAyB,EACzB,QAA2C;IAE3C,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvD,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Template Registry
3
+ *
4
+ * Central registry for consent page templates.
5
+ * Provides factory methods for creating templates by auth mode.
6
+ *
7
+ * @module @kya-os/consent/templates/registry
8
+ */
9
+ import { BaseConsentTemplate } from "./base/base-template";
10
+ import type { AuthMode } from "../types/modes.types";
11
+ import type { ExtendedConsentPageConfig } from "../types/page.types";
12
+ import type { ConsentConfigWithMeta } from "../types/config.types";
13
+ /**
14
+ * Get a template instance for the specified auth mode.
15
+ *
16
+ * @param authMode - The authentication mode
17
+ * @param config - Extended page config with mode-specific settings
18
+ * @param remoteConfig - Remote consent configuration from AgentShield
19
+ * @returns Template instance ready to render
20
+ */
21
+ export declare function getTemplateForMode(authMode: AuthMode, config: ExtendedConsentPageConfig, remoteConfig?: ConsentConfigWithMeta): BaseConsentTemplate;
22
+ /**
23
+ * Determine the auth mode from config.
24
+ *
25
+ * @param config - Page config with optional OAuth settings
26
+ * @returns Detected auth mode
27
+ */
28
+ export declare function detectAuthMode(config: ExtendedConsentPageConfig): AuthMode;
29
+ /**
30
+ * Check if an auth mode is valid.
31
+ *
32
+ * @param mode - Mode string to check
33
+ * @returns True if valid auth mode
34
+ */
35
+ export declare function isValidAuthMode(mode: string): mode is AuthMode;
36
+ /**
37
+ * Get all registered auth modes.
38
+ *
39
+ * @returns Array of auth mode identifiers
40
+ */
41
+ export declare function getRegisteredModes(): AuthMode[];
42
+ /**
43
+ * Render a consent page for the given config.
44
+ *
45
+ * This is the main entry point for rendering consent pages.
46
+ *
47
+ * @param config - Extended page config
48
+ * @param remoteConfig - Remote consent configuration from AgentShield
49
+ * @param authMode - Optional explicit auth mode (auto-detected if not provided)
50
+ * @returns Rendered HTML string
51
+ */
52
+ export declare function renderConsentPage(config: ExtendedConsentPageConfig, remoteConfig?: ConsentConfigWithMeta, authMode?: AuthMode): string;
53
+ /**
54
+ * Render an OAuth consent page with pre-configured OAuth URL.
55
+ *
56
+ * @param config - Extended page config
57
+ * @param oauthUrl - OAuth authorization URL
58
+ * @param remoteConfig - Remote consent configuration from AgentShield
59
+ * @returns Rendered HTML string
60
+ */
61
+ export declare function renderOAuthConsentPage(config: ExtendedConsentPageConfig, oauthUrl: string, remoteConfig?: ConsentConfigWithMeta): string;
62
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/templates/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAS3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EACV,yBAAyB,EAE1B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAqBnE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,yBAAyB,EACjC,YAAY,CAAC,EAAE,qBAAqB,GACnC,mBAAmB,CAyBrB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,yBAAyB,GAChC,QAAQ,CA4BV;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,QAAQ,CAE9D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,QAAQ,EAAE,CAE/C;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,yBAAyB,EACjC,YAAY,CAAC,EAAE,qBAAqB,EACpC,QAAQ,CAAC,EAAE,QAAQ,GAClB,MAAM,CAIR;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,yBAAyB,EACjC,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,qBAAqB,GACnC,MAAM,CAOR"}