@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,196 @@
1
+ "use strict";
2
+ /**
3
+ * Magic Link Template
4
+ *
5
+ * Passwordless authentication via email link.
6
+ *
7
+ * @module @kya-os/consent/templates/modes/magic-link
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MagicLinkTemplate = 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
+ * Magic Link Template
17
+ *
18
+ * Renders an email-based passwordless login:
19
+ * - Email input field
20
+ * - Submit button
21
+ * - Success/waiting state
22
+ * - Resend link functionality
23
+ */
24
+ class MagicLinkTemplate extends base_template_1.BaseConsentTemplate {
25
+ get authMode() {
26
+ return modes_types_1.AUTH_MODES.MAGIC_LINK;
27
+ }
28
+ get magicLinkConfig() {
29
+ return this.config.modeConfig?.magicLink;
30
+ }
31
+ renderAuthContent() {
32
+ const config = this.magicLinkConfig;
33
+ return `
34
+ <div id="magic-link-form-container">
35
+ <form id="magic-link-form" class="space-y-4">
36
+ ${this.renderEmailField(config)}
37
+ ${(0, components_1.renderErrorContainer)()}
38
+ ${(0, components_1.renderFullWidthButton)(config?.buttonText || "Send Magic Link", "submit")}
39
+ </form>
40
+ </div>
41
+ <div id="magic-link-sent" class="hidden text-center py-4 space-y-4">
42
+ <div class="w-16 h-16 mx-auto rounded-full bg-green-100 flex items-center justify-center">
43
+ <svg class="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
44
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
45
+ </svg>
46
+ </div>
47
+ <h3 class="text-lg font-semibold text-gray-900">Check your email</h3>
48
+ <p class="text-sm text-gray-600">
49
+ We've sent a magic link to <span id="sent-email" class="font-medium"></span>.<br/>
50
+ Click the link to continue.
51
+ </p>
52
+ <button type="button" id="resend-btn" class="text-sm link-primary mt-4 disabled:opacity-50">
53
+ Resend link
54
+ </button>
55
+ </div>
56
+ `;
57
+ }
58
+ /**
59
+ * Render email input field.
60
+ */
61
+ renderEmailField(config) {
62
+ return (0, components_1.renderInput)("email", "email", config?.emailLabel || "Email address", config?.emailPlaceholder || "Enter your email", true, "email");
63
+ }
64
+ /**
65
+ * Override action buttons - form has its own submit.
66
+ */
67
+ renderActionButtons() {
68
+ return "";
69
+ }
70
+ renderModeScript() {
71
+ const serverUrl = (0, escape_1.escapeJs)(this.config.serverUrl);
72
+ const projectId = (0, escape_1.escapeJs)(this.config.projectId);
73
+ const sessionId = (0, escape_1.escapeJs)(this.config.sessionId);
74
+ const agentDid = (0, escape_1.escapeJs)(this.config.agentDid);
75
+ const tool = (0, escape_1.escapeJs)(this.config.tool);
76
+ const scopes = JSON.stringify(this.config.scopes);
77
+ const resendCooldown = this.magicLinkConfig?.resendCooldown || 60;
78
+ return `
79
+ <script>
80
+ (function() {
81
+ const form = document.getElementById('magic-link-form');
82
+ const formContainer = document.getElementById('magic-link-form-container');
83
+ const sentContainer = document.getElementById('magic-link-sent');
84
+ const sentEmail = document.getElementById('sent-email');
85
+ const resendBtn = document.getElementById('resend-btn');
86
+ const errorContainer = document.getElementById('error-container');
87
+ const errorDiv = errorContainer?.querySelector('div');
88
+
89
+ if (!form) return;
90
+
91
+ const serverUrl = ${serverUrl};
92
+ const cooldown = ${resendCooldown};
93
+ let lastEmail = '';
94
+ let resendTimer = null;
95
+
96
+ async function sendMagicLink(email) {
97
+ const data = {
98
+ provider_type: 'magic_link',
99
+ email: email,
100
+ tool: ${tool},
101
+ scopes: ${scopes},
102
+ agent_did: ${agentDid},
103
+ session_id: ${sessionId},
104
+ project_id: ${projectId},
105
+ };
106
+
107
+ const response = await fetch(serverUrl + '/consent/magic-link', {
108
+ method: 'POST',
109
+ headers: { 'Content-Type': 'application/json' },
110
+ body: JSON.stringify(data)
111
+ });
112
+
113
+ return response.json();
114
+ }
115
+
116
+ function showSent(email) {
117
+ formContainer.classList.add('hidden');
118
+ sentContainer.classList.remove('hidden');
119
+ sentEmail.textContent = email;
120
+
121
+ // Start cooldown
122
+ resendBtn.disabled = true;
123
+ let remaining = cooldown;
124
+ resendBtn.textContent = 'Resend link (' + remaining + 's)';
125
+
126
+ resendTimer = setInterval(() => {
127
+ remaining--;
128
+ if (remaining <= 0) {
129
+ clearInterval(resendTimer);
130
+ resendBtn.disabled = false;
131
+ resendBtn.textContent = 'Resend link';
132
+ } else {
133
+ resendBtn.textContent = 'Resend link (' + remaining + 's)';
134
+ }
135
+ }, 1000);
136
+ }
137
+
138
+ function showError(message) {
139
+ if (errorDiv) {
140
+ errorDiv.textContent = message;
141
+ errorContainer.classList.remove('hidden');
142
+ }
143
+ }
144
+
145
+ form.addEventListener('submit', async function(e) {
146
+ e.preventDefault();
147
+
148
+ const button = form.querySelector('button[type="submit"]');
149
+ const originalText = button.textContent;
150
+ const emailInput = form.querySelector('input[name="email"]');
151
+ lastEmail = emailInput.value;
152
+
153
+ if (errorContainer) errorContainer.classList.add('hidden');
154
+ button.disabled = true;
155
+ button.textContent = 'Sending...';
156
+
157
+ try {
158
+ const result = await sendMagicLink(lastEmail);
159
+
160
+ if (result.success) {
161
+ showSent(lastEmail);
162
+ } else {
163
+ showError(result.error || 'Failed to send magic link');
164
+ button.disabled = false;
165
+ button.textContent = originalText;
166
+ }
167
+ } catch (err) {
168
+ showError('Network error. Please try again.');
169
+ button.disabled = false;
170
+ button.textContent = originalText;
171
+ }
172
+ });
173
+
174
+ resendBtn?.addEventListener('click', async function() {
175
+ if (!lastEmail || resendBtn.disabled) return;
176
+
177
+ resendBtn.disabled = true;
178
+ try {
179
+ const result = await sendMagicLink(lastEmail);
180
+ if (result.success) {
181
+ showSent(lastEmail);
182
+ } else {
183
+ alert(result.error || 'Failed to resend');
184
+ resendBtn.disabled = false;
185
+ }
186
+ } catch (err) {
187
+ alert('Network error');
188
+ resendBtn.disabled = false;
189
+ }
190
+ });
191
+ })();
192
+ </script>`;
193
+ }
194
+ }
195
+ exports.MagicLinkTemplate = MagicLinkTemplate;
196
+ //# sourceMappingURL=magic-link.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"magic-link.template.js","sourceRoot":"","sources":["../../../src/templates/modes/magic-link.template.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,yDAA4D;AAC5D,mDAI4B;AAC5B,kDAAiD;AAEjD,yDAAqD;AAErD;;;;;;;;GAQG;AACH,MAAa,iBAAkB,SAAQ,mCAAmB;IACxD,IAAI,QAAQ;QACV,OAAO,wBAAU,CAAC,UAAU,CAAC;IAC/B,CAAC;IAED,IAAY,eAAe;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC;IAC3C,CAAC;IAEQ,iBAAiB;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC;QAEpC,OAAO;;;YAGC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;YAC7B,IAAA,iCAAoB,GAAE;YACtB,IAAA,kCAAqB,EAAC,MAAM,EAAE,UAAU,IAAI,iBAAiB,EAAE,QAAQ,CAAC;;;;;;;;;;;;;;;;;;KAkB/E,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,MAAwB;QAC/C,OAAO,IAAA,wBAAW,EAChB,OAAO,EACP,OAAO,EACP,MAAM,EAAE,UAAU,IAAI,eAAe,EACrC,MAAM,EAAE,gBAAgB,IAAI,kBAAkB,EAC9C,IAAI,EACJ,OAAO,CACR,CAAC;IACJ,CAAC;IAED;;OAEG;IACgB,mBAAmB;QACpC,OAAO,EAAE,CAAC;IACZ,CAAC;IAEkB,gBAAgB;QACjC,MAAM,SAAS,GAAG,IAAA,iBAAQ,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAA,iBAAQ,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,IAAA,iBAAQ,EAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,QAAQ,GAAG,IAAA,iBAAQ,EAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAA,iBAAQ,EAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,EAAE,cAAc,IAAI,EAAE,CAAC;QAElE,OAAO;;;;;;;;;;;;;sBAaW,SAAS;qBACV,cAAc;;;;;;;;cAQrB,IAAI;gBACF,MAAM;mBACH,QAAQ;oBACP,SAAS;oBACT,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAwFnB,CAAC;IACT,CAAC;CACF;AAxLD,8CAwLC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * OAuth Template
3
+ *
4
+ * OAuth redirect flow with provider branding.
5
+ *
6
+ * @module @kya-os/consent/templates/modes/oauth
7
+ */
8
+ import { BaseConsentTemplate } from "../base/base-template";
9
+ import type { AuthMode } from "../../types/modes.types";
10
+ /**
11
+ * OAuth Template
12
+ *
13
+ * Renders an OAuth consent page with:
14
+ * - Permission list
15
+ * - Expiration notice
16
+ * - Provider-branded continue button
17
+ */
18
+ export declare class OAuthTemplate extends BaseConsentTemplate {
19
+ private oauthUrl?;
20
+ get authMode(): AuthMode;
21
+ /**
22
+ * Set the OAuth authorization URL.
23
+ */
24
+ setOAuthUrl(url: string): void;
25
+ private get oauthConfig();
26
+ renderAuthContent(): string;
27
+ /**
28
+ * Render permissions as a simple list.
29
+ */
30
+ private renderPermissionsList;
31
+ /**
32
+ * Render expiration notice.
33
+ */
34
+ private renderExpirationNotice;
35
+ /**
36
+ * Override action buttons to show OAuth provider button.
37
+ */
38
+ protected renderActionButtons(): string;
39
+ }
40
+ //# sourceMappingURL=oauth.template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.template.d.ts","sourceRoot":"","sources":["../../../src/templates/modes/oauth.template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAI5D,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,yBAAyB,CAAC;AAqCrE;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,mBAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,CAAS;IAE1B,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI9B,OAAO,KAAK,WAAW,GAEtB;IAEQ,iBAAiB,IAAI,MAAM;IAkBpC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAM9B;;OAEG;cACgB,mBAAmB,IAAI,MAAM;CA8CjD"}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth Template
4
+ *
5
+ * OAuth redirect flow with provider branding.
6
+ *
7
+ * @module @kya-os/consent/templates/modes/oauth
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.OAuthTemplate = void 0;
11
+ const base_template_1 = require("../base/base-template");
12
+ const components_1 = require("../base/components");
13
+ const tokens_1 = require("../../styles/tokens");
14
+ const escape_1 = require("../../security/escape");
15
+ const modes_types_1 = require("../../types/modes.types");
16
+ /**
17
+ * OAuth provider branding information.
18
+ */
19
+ const PROVIDER_BRANDING = {
20
+ github: {
21
+ color: "#24292e",
22
+ name: "GitHub",
23
+ icon: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>`,
24
+ },
25
+ google: {
26
+ color: "#4285f4",
27
+ name: "Google",
28
+ icon: `<svg class="w-5 h-5" viewBox="0 0 24 24"><path fill="currentColor" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"/><path fill="currentColor" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="currentColor" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="currentColor" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>`,
29
+ },
30
+ microsoft: {
31
+ color: "#0078d4",
32
+ name: "Microsoft",
33
+ icon: `<svg class="w-5 h-5" viewBox="0 0 24 24"><path fill="#f35325" d="M1 1h10v10H1z"/><path fill="#81bc06" d="M13 1h10v10H13z"/><path fill="#05a6f0" d="M1 13h10v10H1z"/><path fill="#ffba08" d="M13 13h10v10H13z"/></svg>`,
34
+ },
35
+ slack: {
36
+ color: "#4a154b",
37
+ name: "Slack",
38
+ icon: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z"/></svg>`,
39
+ },
40
+ auth0: {
41
+ color: "#eb5424",
42
+ name: "Auth0",
43
+ icon: `<svg class="w-5 h-5" viewBox="0 0 24 24" fill="currentColor"><path d="M21.98 7.448L19.62 0H4.347L2.02 7.448c-1.352 4.312.03 9.206 3.815 12.015L12.007 24l6.157-4.552c3.755-2.81 5.182-7.688 3.815-12.015l-6.16 4.58 2.343 7.45-6.157-4.597-6.158 4.58 2.358-7.433-6.188-4.55 7.63-.045L12.008 0l2.356 7.404 7.615.044z"/></svg>`,
44
+ },
45
+ };
46
+ /**
47
+ * OAuth Template
48
+ *
49
+ * Renders an OAuth consent page with:
50
+ * - Permission list
51
+ * - Expiration notice
52
+ * - Provider-branded continue button
53
+ */
54
+ class OAuthTemplate extends base_template_1.BaseConsentTemplate {
55
+ get authMode() {
56
+ return modes_types_1.AUTH_MODES.OAUTH;
57
+ }
58
+ /**
59
+ * Set the OAuth authorization URL.
60
+ */
61
+ setOAuthUrl(url) {
62
+ this.oauthUrl = url;
63
+ }
64
+ get oauthConfig() {
65
+ return this.config.modeConfig?.oauth;
66
+ }
67
+ renderAuthContent() {
68
+ const config = this.oauthConfig;
69
+ const providerId = config?.providerId || this.config.provider || "oauth";
70
+ const branding = PROVIDER_BRANDING[providerId.toLowerCase()];
71
+ return `
72
+ <div class="space-y-4">
73
+ ${this.renderPermissionsList()}
74
+ <div class="pt-2">
75
+ <p class="text-sm text-gray-600">
76
+ You will be redirected to ${(0, escape_1.escapeHtml)(branding?.name || config?.providerName || "the identity provider")} to authenticate.
77
+ </p>
78
+ </div>
79
+ ${this.renderExpirationNotice()}
80
+ </div>
81
+ `;
82
+ }
83
+ /**
84
+ * Render permissions as a simple list.
85
+ */
86
+ renderPermissionsList() {
87
+ const { scopes } = this.config;
88
+ if (scopes.length === 0)
89
+ return "";
90
+ const items = scopes.map((s) => `<li>${(0, escape_1.escapeHtml)(s)}</li>`).join("");
91
+ return `
92
+ <div class="space-y-2">
93
+ <p class="text-sm font-medium text-gray-700">Requested permissions:</p>
94
+ <ul class="list-disc list-inside text-sm text-gray-600 space-y-1">
95
+ ${items}
96
+ </ul>
97
+ </div>
98
+ `;
99
+ }
100
+ /**
101
+ * Render expiration notice.
102
+ */
103
+ renderExpirationNotice() {
104
+ const { copy } = this.resolved;
105
+ const expirationDays = this.resolved.expirationDays || 30;
106
+ return (0, components_1.renderExpirationNotice)(copy.expirationText, expirationDays);
107
+ }
108
+ /**
109
+ * Override action buttons to show OAuth provider button.
110
+ */
111
+ renderActionButtons() {
112
+ const config = this.oauthConfig;
113
+ const providerId = config?.providerId || this.config.provider || "oauth";
114
+ const branding = PROVIDER_BRANDING[providerId.toLowerCase()];
115
+ const buttonText = config?.buttonText ||
116
+ `Continue with ${branding?.name || config?.providerName || "Provider"}`;
117
+ const { copy } = this.resolved;
118
+ // If OAuth URL is set, use a direct link
119
+ const oauthUrl = this.oauthUrl || this.config.oauthUrl;
120
+ if (oauthUrl) {
121
+ const buttonStyle = branding
122
+ ? `style="background-color: ${branding.color}"`
123
+ : "";
124
+ return `
125
+ <div class="${tokens_1.CONSENT_CLASSES.buttonGroup}">
126
+ <button type="button" onclick="window.close()" class="${tokens_1.CONSENT_CLASSES.buttonSecondary}">
127
+ ${(0, escape_1.escapeHtml)(copy.cancelButtonText)}
128
+ </button>
129
+ <a href="${(0, escape_1.escapeAttr)(oauthUrl)}"
130
+ class="${tokens_1.CONSENT_CLASSES.buttonPrimary} flex items-center justify-center gap-2"
131
+ ${buttonStyle}>
132
+ ${branding?.icon || ""}
133
+ ${(0, escape_1.escapeHtml)(buttonText)}
134
+ </a>
135
+ </div>
136
+ `;
137
+ }
138
+ // Fallback to standard buttons
139
+ return `
140
+ <div class="${tokens_1.CONSENT_CLASSES.buttonGroup}">
141
+ <button type="button" onclick="window.close()" class="${tokens_1.CONSENT_CLASSES.buttonSecondary}">
142
+ ${(0, escape_1.escapeHtml)(copy.cancelButtonText)}
143
+ </button>
144
+ <button type="submit" class="${tokens_1.CONSENT_CLASSES.buttonPrimary} btn-primary flex items-center justify-center gap-2">
145
+ ${branding?.icon || ""}
146
+ ${(0, escape_1.escapeHtml)(buttonText)}
147
+ </button>
148
+ </div>
149
+ `;
150
+ }
151
+ }
152
+ exports.OAuthTemplate = OAuthTemplate;
153
+ //# sourceMappingURL=oauth.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.template.js","sourceRoot":"","sources":["../../../src/templates/modes/oauth.template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * OTP Template
3
+ *
4
+ * One-Time Password authentication via SMS/email.
5
+ *
6
+ * @module @kya-os/consent/templates/modes/otp
7
+ */
8
+ import { BaseConsentTemplate } from "../base/base-template";
9
+ import type { AuthMode } from "../../types/modes.types";
10
+ /**
11
+ * OTP Template
12
+ *
13
+ * Renders a two-step OTP flow:
14
+ * 1. Phone/email input to request code
15
+ * 2. Code input to verify
16
+ */
17
+ export declare class OTPTemplate extends BaseConsentTemplate {
18
+ get authMode(): AuthMode;
19
+ private get otpConfig();
20
+ renderAuthContent(): string;
21
+ /**
22
+ * Render phone/email input field.
23
+ */
24
+ private renderPhoneField;
25
+ /**
26
+ * Render OTP digit input boxes.
27
+ */
28
+ private renderOTPInputs;
29
+ /**
30
+ * Override action buttons - form has its own submit.
31
+ */
32
+ protected renderActionButtons(): string;
33
+ protected renderModeScript(): string;
34
+ }
35
+ //# sourceMappingURL=otp.template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otp.template.d.ts","sourceRoot":"","sources":["../../../src/templates/modes/otp.template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAO5D,OAAO,KAAK,EAAE,QAAQ,EAAa,MAAM,yBAAyB,CAAC;AAGnE;;;;;;GAMG;AACH,qBAAa,WAAY,SAAQ,mBAAmB;IAClD,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,OAAO,KAAK,SAAS,GAEpB;IAEQ,iBAAiB,IAAI,MAAM;IAkCpC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;cACgB,mBAAmB,IAAI,MAAM;cAI7B,gBAAgB,IAAI,MAAM;CAmO9C"}