better-auth-studio 1.1.1-beta.3 → 1.1.1-beta.5

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 (78) hide show
  1. package/dist/adapters/hono.d.ts.map +1 -1
  2. package/dist/adapters/hono.js +5 -0
  3. package/dist/adapters/hono.js.map +1 -1
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js.map +1 -1
  6. package/dist/core/handler.d.ts.map +1 -1
  7. package/dist/core/handler.js +85 -4
  8. package/dist/core/handler.js.map +1 -1
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +3 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/providers/events/helpers.d.ts +22 -0
  14. package/dist/providers/events/helpers.d.ts.map +1 -0
  15. package/dist/providers/events/helpers.js +874 -0
  16. package/dist/providers/events/helpers.js.map +1 -0
  17. package/dist/public/assets/{main-BIlYgyPi.js → main-B_Zdj1LN.js} +139 -139
  18. package/dist/public/assets/main-RoeYO1I-.css +1 -0
  19. package/dist/public/index.html +2 -2
  20. package/dist/routes.d.ts.map +1 -1
  21. package/dist/routes.js +193 -0
  22. package/dist/routes.js.map +1 -1
  23. package/dist/studio.d.ts.map +1 -1
  24. package/dist/studio.js +6 -1
  25. package/dist/studio.js.map +1 -1
  26. package/dist/types/events.d.ts +43 -0
  27. package/dist/types/events.d.ts.map +1 -0
  28. package/dist/types/events.js +306 -0
  29. package/dist/types/events.js.map +1 -0
  30. package/dist/types/handler.d.ts +31 -0
  31. package/dist/types/handler.d.ts.map +1 -1
  32. package/dist/types/handler.js.map +1 -1
  33. package/dist/utils/auth-callbacks-injector.d.ts +3 -0
  34. package/dist/utils/auth-callbacks-injector.d.ts.map +1 -0
  35. package/dist/utils/auth-callbacks-injector.js +227 -0
  36. package/dist/utils/auth-callbacks-injector.js.map +1 -0
  37. package/dist/utils/auth-callbacks-wrapper.d.ts +7 -0
  38. package/dist/utils/auth-callbacks-wrapper.d.ts.map +1 -0
  39. package/dist/utils/auth-callbacks-wrapper.js +123 -0
  40. package/dist/utils/auth-callbacks-wrapper.js.map +1 -0
  41. package/dist/utils/database-hook-injector.d.ts +3 -0
  42. package/dist/utils/database-hook-injector.d.ts.map +1 -0
  43. package/dist/utils/database-hook-injector.js +141 -0
  44. package/dist/utils/database-hook-injector.js.map +1 -0
  45. package/dist/utils/email-otp-hooks-injector.d.ts +29 -0
  46. package/dist/utils/email-otp-hooks-injector.d.ts.map +1 -0
  47. package/dist/utils/email-otp-hooks-injector.js +134 -0
  48. package/dist/utils/email-otp-hooks-injector.js.map +1 -0
  49. package/dist/utils/event-ingestion.d.ts +38 -0
  50. package/dist/utils/event-ingestion.d.ts.map +1 -0
  51. package/dist/utils/event-ingestion.js +169 -0
  52. package/dist/utils/event-ingestion.js.map +1 -0
  53. package/dist/utils/hook-injector.d.ts +9 -0
  54. package/dist/utils/hook-injector.d.ts.map +1 -0
  55. package/dist/utils/hook-injector.js +649 -0
  56. package/dist/utils/hook-injector.js.map +1 -0
  57. package/dist/utils/html-injector.d.ts +17 -0
  58. package/dist/utils/html-injector.d.ts.map +1 -1
  59. package/dist/utils/html-injector.js +15 -0
  60. package/dist/utils/html-injector.js.map +1 -1
  61. package/dist/utils/org-hooks-injector.d.ts +74 -0
  62. package/dist/utils/org-hooks-injector.d.ts.map +1 -0
  63. package/dist/utils/org-hooks-injector.js +678 -0
  64. package/dist/utils/org-hooks-injector.js.map +1 -0
  65. package/dist/utils/org-hooks-wrapper.d.ts +74 -0
  66. package/dist/utils/org-hooks-wrapper.d.ts.map +1 -0
  67. package/dist/utils/org-hooks-wrapper.js +687 -0
  68. package/dist/utils/org-hooks-wrapper.js.map +1 -0
  69. package/dist/utils/organization-hooks-wrapper.d.ts +38 -0
  70. package/dist/utils/organization-hooks-wrapper.d.ts.map +1 -0
  71. package/dist/utils/organization-hooks-wrapper.js +297 -0
  72. package/dist/utils/organization-hooks-wrapper.js.map +1 -0
  73. package/package.json +7 -4
  74. package/public/assets/{main-BIlYgyPi.js → main-B_Zdj1LN.js} +139 -139
  75. package/public/assets/main-RoeYO1I-.css +1 -0
  76. package/public/index.html +2 -2
  77. package/dist/public/assets/main-s8HrXBxq.css +0 -1
  78. package/public/assets/main-s8HrXBxq.css +0 -1
@@ -0,0 +1,134 @@
1
+ import { emitEvent } from './event-ingestion.js';
2
+ /**
3
+ * Helper to extract request info from Better Auth request object
4
+ */
5
+ function getRequestInfo(request) {
6
+ const headersObj = {};
7
+ let ip;
8
+ if (request) {
9
+ try {
10
+ if (request instanceof Request) {
11
+ request.headers.forEach((value, key) => {
12
+ headersObj[key] = value;
13
+ });
14
+ ip =
15
+ request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined;
16
+ }
17
+ else if (request.headers) {
18
+ if (typeof request.headers.get === 'function') {
19
+ ip =
20
+ request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined;
21
+ request.headers.forEach?.((value, key) => {
22
+ headersObj[key] = value;
23
+ });
24
+ }
25
+ else {
26
+ ip = request.headers['x-forwarded-for'] || request.headers['x-real-ip'] || undefined;
27
+ Object.entries(request.headers).forEach(([key, value]) => {
28
+ headersObj[key] = String(value);
29
+ });
30
+ }
31
+ }
32
+ }
33
+ catch (e) {
34
+ // Ignore errors
35
+ }
36
+ }
37
+ return { headers: headersObj, ip };
38
+ }
39
+ // Share password reset method tracking with auth-callbacks-injector
40
+ // This is used to determine if password reset was via OTP or token
41
+ // We need to access it from auth-callbacks-injector, so we'll use a shared approach
42
+ // by setting it on the email-otp plugin options temporarily, or we can use a module-level map
43
+ // For now, we'll track it in the callback and let onPasswordReset check it
44
+ // The passwordResetMethod map in auth-callbacks-injector will be used for completion tracking
45
+ /**
46
+ * Wraps email-otp plugin callbacks to automatically emit events
47
+ * This wraps the sendVerificationOTP callback similar to how organization hooks work
48
+ *
49
+ * @param eventsConfig - The events configuration
50
+ * @param existingCallback - The original sendVerificationOTP callback
51
+ * @param passwordResetMethodMap - Optional shared Map to track password reset method (OTP vs token)
52
+ */
53
+ export function wrapEmailOTPPluginCallbacks(eventsConfig, existingCallback, passwordResetMethodMap) {
54
+ if (!eventsConfig?.enabled) {
55
+ return existingCallback;
56
+ }
57
+ if (!existingCallback) {
58
+ return undefined;
59
+ }
60
+ const capturedConfig = eventsConfig;
61
+ return async (data, ctx) => {
62
+ const requestInfo = getRequestInfo(ctx?.request || ctx);
63
+ // Call the original callback first
64
+ const originalPromise = existingCallback(data, ctx);
65
+ // Track and emit event for password reset OTP
66
+ if (data.type === 'forget-password') {
67
+ const email = data.email.toLowerCase();
68
+ // Track that this is an OTP-based password reset
69
+ // This will be checked by onPasswordReset in auth-callbacks-injector
70
+ if (passwordResetMethodMap) {
71
+ passwordResetMethodMap.set(email, 'otp');
72
+ }
73
+ // Emit event for password reset OTP requested
74
+ const eventPromise = emitEvent('password.reset_requested_otp', {
75
+ status: 'success',
76
+ metadata: {
77
+ email: data.email,
78
+ type: 'forget-password',
79
+ requestedAt: new Date().toISOString(),
80
+ },
81
+ request: requestInfo,
82
+ }, capturedConfig).catch(() => { });
83
+ // Wait for original callback to complete
84
+ await originalPromise;
85
+ // Don't wait for event emission to avoid blocking
86
+ eventPromise.catch(() => { });
87
+ }
88
+ else {
89
+ await originalPromise;
90
+ }
91
+ };
92
+ }
93
+ /**
94
+ * Automatically wraps email-otp plugin callbacks to emit events
95
+ * This should be called during Better Auth initialization
96
+ * Similar to wrapOrganizationPluginHooks but for callbacks
97
+ *
98
+ * @param auth - The Better Auth instance
99
+ * @param eventsConfig - The events configuration
100
+ * @param passwordResetMethodMap - Optional shared Map to track password reset method (OTP vs token)
101
+ */
102
+ export function wrapEmailOTPPluginHooks(auth, eventsConfig, passwordResetMethodMap) {
103
+ if (!auth || !eventsConfig?.enabled) {
104
+ return;
105
+ }
106
+ try {
107
+ const plugins = auth.options?.plugins || [];
108
+ const emailOtpPlugin = plugins.find((p) => p?.id === 'email-otp');
109
+ if (!emailOtpPlugin) {
110
+ return;
111
+ }
112
+ // Check if already wrapped to avoid double wrapping
113
+ if (emailOtpPlugin.__studio_callbacks_wrapped) {
114
+ return;
115
+ }
116
+ // Wrap the sendVerificationOTP callback
117
+ const existingSendVerificationOTP = emailOtpPlugin.options?.sendVerificationOTP;
118
+ if (existingSendVerificationOTP) {
119
+ const wrappedCallback = wrapEmailOTPPluginCallbacks(eventsConfig, existingSendVerificationOTP, passwordResetMethodMap);
120
+ if (wrappedCallback) {
121
+ if (!emailOtpPlugin.options) {
122
+ emailOtpPlugin.options = {};
123
+ }
124
+ emailOtpPlugin.options.sendVerificationOTP = wrappedCallback;
125
+ }
126
+ }
127
+ // Mark as wrapped to prevent double wrapping
128
+ emailOtpPlugin.__studio_callbacks_wrapped = true;
129
+ }
130
+ catch (error) {
131
+ console.error('[Email OTP Callbacks] Failed to wrap callbacks:', error);
132
+ }
133
+ }
134
+ //# sourceMappingURL=email-otp-hooks-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-otp-hooks-injector.js","sourceRoot":"","sources":["../../src/utils/email-otp-hooks-injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { AuthEventType, EventIngestionProvider } from '../types/events.js';
2
+ import type { StudioConfig } from '../types/handler.js';
3
+ /**
4
+ * Initialize event ingestion
5
+ */
6
+ export declare function initializeEventIngestion(eventsConfig: StudioConfig['events']): void;
7
+ /**
8
+ * Emit an event
9
+ */
10
+ export declare function emitEvent(type: AuthEventType, data: {
11
+ status: 'success' | 'failed';
12
+ userId?: string;
13
+ sessionId?: string;
14
+ organizationId?: string;
15
+ metadata?: Record<string, any>;
16
+ request?: {
17
+ headers: Record<string, string>;
18
+ ip?: string;
19
+ };
20
+ }, eventsConfig?: StudioConfig['events']): Promise<void>;
21
+ export declare function shutdownEventIngestion(): Promise<void>;
22
+ /**
23
+ * Health check
24
+ */
25
+ export declare function checkEventIngestionHealth(): Promise<boolean>;
26
+ /**
27
+ * Get initialization status
28
+ */
29
+ export declare function isEventIngestionInitialized(): boolean;
30
+ /**
31
+ * Get current queue size (for monitoring)
32
+ */
33
+ export declare function getEventQueueSize(): number;
34
+ /**
35
+ * Get the current event ingestion provider
36
+ */
37
+ export declare function getEventIngestionProvider(): EventIngestionProvider | null;
38
+ //# sourceMappingURL=event-ingestion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-ingestion.d.ts","sourceRoot":"","sources":["../../src/utils/event-ingestion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EACb,sBAAsB,EAGvB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AASxD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAqBnF;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE;IACJ,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,EACD,YAAY,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAuEf;AAwBD,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmB5D;AAED;;GAEG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,OAAO,CAAC,CAUlE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,sBAAsB,GAAG,IAAI,CAEzE"}
@@ -0,0 +1,169 @@
1
+ import { EVENT_TEMPLATES, getEventSeverity } from '../types/events.js';
2
+ let provider = null;
3
+ let config = null;
4
+ let eventQueue = [];
5
+ let flushTimer = null;
6
+ let isShuttingDown = false;
7
+ let isInitialized = false;
8
+ /**
9
+ * Initialize event ingestion
10
+ */
11
+ export function initializeEventIngestion(eventsConfig) {
12
+ if (!eventsConfig?.enabled) {
13
+ return;
14
+ }
15
+ config = eventsConfig;
16
+ provider = eventsConfig.provider || null;
17
+ if (!provider) {
18
+ console.warn('Event ingestion is enabled but no provider provided');
19
+ return;
20
+ }
21
+ isInitialized = true;
22
+ if (config.batchSize && config.batchSize > 1) {
23
+ const flushInterval = config.flushInterval || 5000;
24
+ flushTimer = setInterval(() => {
25
+ flushEvents().catch(console.error);
26
+ }, flushInterval);
27
+ }
28
+ }
29
+ /**
30
+ * Emit an event
31
+ */
32
+ export async function emitEvent(type, data, eventsConfig) {
33
+ const activeConfig = eventsConfig || config;
34
+ if (!activeConfig?.enabled) {
35
+ initializeEventIngestion(eventsConfig);
36
+ }
37
+ const useConfig = activeConfig || config;
38
+ if (!useConfig) {
39
+ return;
40
+ }
41
+ if (useConfig.include && !useConfig.include.includes(type)) {
42
+ return;
43
+ }
44
+ if (useConfig.exclude && useConfig.exclude.includes(type)) {
45
+ return;
46
+ }
47
+ const template = EVENT_TEMPLATES[type];
48
+ const tempEvent = {
49
+ id: '',
50
+ type,
51
+ timestamp: new Date(),
52
+ status: data.status,
53
+ userId: data.userId,
54
+ sessionId: data.sessionId,
55
+ organizationId: data.organizationId,
56
+ metadata: data.metadata || {},
57
+ source: 'app',
58
+ };
59
+ const displayMessage = template ? template(tempEvent) : type;
60
+ const event = {
61
+ id: crypto.randomUUID(),
62
+ type,
63
+ timestamp: new Date(),
64
+ status: data.status,
65
+ userId: data.userId,
66
+ sessionId: data.sessionId,
67
+ organizationId: data.organizationId,
68
+ metadata: data.metadata || {},
69
+ ipAddress: data.request?.ip,
70
+ userAgent: data.request?.headers['user-agent'] || data.request?.headers['User-Agent'],
71
+ source: 'app',
72
+ display: {
73
+ message: displayMessage,
74
+ severity: getEventSeverity(tempEvent, data.status),
75
+ },
76
+ };
77
+ const batchSize = useConfig.batchSize || 1;
78
+ if (batchSize > 1 && provider?.ingestBatch) {
79
+ eventQueue.push(event);
80
+ if (eventQueue.length >= batchSize) {
81
+ await flushEvents();
82
+ }
83
+ }
84
+ else {
85
+ try {
86
+ console.log(`[Event Ingestion] Emitting event: ${type}`, {
87
+ userId: event.userId,
88
+ message: event.display?.message,
89
+ });
90
+ await provider?.ingest(event);
91
+ console.log(`[Event Ingestion] ✅ Successfully ingested event: ${type}`);
92
+ }
93
+ catch (error) {
94
+ console.error(`[Event Ingestion] ❌ Failed to ingest event ${type}:`, error);
95
+ if (useConfig.retryOnError) {
96
+ eventQueue.push(event);
97
+ console.log(`[Event Ingestion] Queued event for retry: ${type}`);
98
+ }
99
+ }
100
+ }
101
+ }
102
+ async function flushEvents() {
103
+ if (eventQueue.length === 0 || !provider || isShuttingDown) {
104
+ return;
105
+ }
106
+ const eventsToSend = [...eventQueue];
107
+ eventQueue = [];
108
+ try {
109
+ if (provider.ingestBatch) {
110
+ await provider.ingestBatch(eventsToSend);
111
+ }
112
+ else {
113
+ await Promise.all(eventsToSend.map((event) => provider.ingest(event)));
114
+ }
115
+ }
116
+ catch (error) {
117
+ console.error('Batch event ingestion error:', error);
118
+ if (config?.retryOnError) {
119
+ eventQueue.unshift(...eventsToSend);
120
+ }
121
+ }
122
+ }
123
+ export async function shutdownEventIngestion() {
124
+ isShuttingDown = true;
125
+ if (flushTimer) {
126
+ clearInterval(flushTimer);
127
+ flushTimer = null;
128
+ }
129
+ await flushEvents();
130
+ if (provider?.shutdown) {
131
+ await provider.shutdown();
132
+ }
133
+ provider = null;
134
+ config = null;
135
+ eventQueue = [];
136
+ isInitialized = false;
137
+ isShuttingDown = false;
138
+ }
139
+ /**
140
+ * Health check
141
+ */
142
+ export async function checkEventIngestionHealth() {
143
+ if (!provider) {
144
+ return false;
145
+ }
146
+ if (provider.healthCheck) {
147
+ return await provider.healthCheck();
148
+ }
149
+ return true;
150
+ }
151
+ /**
152
+ * Get initialization status
153
+ */
154
+ export function isEventIngestionInitialized() {
155
+ return isInitialized;
156
+ }
157
+ /**
158
+ * Get current queue size (for monitoring)
159
+ */
160
+ export function getEventQueueSize() {
161
+ return eventQueue.length;
162
+ }
163
+ /**
164
+ * Get the current event ingestion provider
165
+ */
166
+ export function getEventIngestionProvider() {
167
+ return provider;
168
+ }
169
+ //# sourceMappingURL=event-ingestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-ingestion.js","sourceRoot":"","sources":["../../src/utils/event-ingestion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { StudioConfig } from '../types/handler.js';
2
+ /**
3
+ * Inject middleware hooks into Better Auth using plugins
4
+ *
5
+ * Better Auth processes plugins during initialization, so we add the plugin
6
+ * to auth.options.plugins array
7
+ */
8
+ export declare function injectEventHooks(auth: any, eventsConfig: StudioConfig['events']): void;
9
+ //# sourceMappingURL=hook-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-injector.d.ts","sourceRoot":"","sources":["../../src/utils/hook-injector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA4tBxD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CAmCtF"}