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,227 @@
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
+ }
35
+ return { headers: headersObj, ip };
36
+ }
37
+ /**
38
+ * Wraps Better Auth callbacks to automatically emit events
39
+ * This should be called during Better Auth initialization
40
+ */
41
+ const passwordResetMethod = new Map();
42
+ export function wrapAuthCallbacks(auth, eventsConfig) {
43
+ if (!auth || !eventsConfig?.enabled) {
44
+ return;
45
+ }
46
+ try {
47
+ const capturedConfig = eventsConfig;
48
+ const wrapCallback = (originalCallback, eventType, eventData) => {
49
+ return (async (...args) => {
50
+ if (originalCallback) {
51
+ await originalCallback(...args);
52
+ }
53
+ const data = eventData(args);
54
+ const requestInfo = getRequestInfo(args[args.length - 1]);
55
+ emitEvent(eventType, {
56
+ status: 'success',
57
+ ...data,
58
+ request: requestInfo,
59
+ }, capturedConfig).catch(() => { });
60
+ });
61
+ };
62
+ const deleteUserConfig = auth.options?.user?.deleteUser || auth.user?.deleteUser;
63
+ if (deleteUserConfig && !deleteUserConfig.__studio_wrapped) {
64
+ const originalSendDeleteVerification = deleteUserConfig.sendDeleteAccountVerification;
65
+ deleteUserConfig.sendDeleteAccountVerification = wrapCallback(originalSendDeleteVerification, 'user.delete_verification_requested', (args) => {
66
+ const data = args[0];
67
+ const user = data?.user;
68
+ return {
69
+ userId: user?.id,
70
+ metadata: {
71
+ email: user?.email,
72
+ name: user?.name,
73
+ token: data?.token,
74
+ },
75
+ };
76
+ });
77
+ // Wrap afterDelete callback
78
+ const originalAfterDelete = deleteUserConfig.afterDelete;
79
+ deleteUserConfig.afterDelete = wrapCallback(originalAfterDelete, 'user.deleted', (args) => {
80
+ const user = args[0];
81
+ return {
82
+ userId: user?.id,
83
+ metadata: {
84
+ email: user?.email,
85
+ name: user?.name,
86
+ },
87
+ };
88
+ });
89
+ deleteUserConfig.__studio_wrapped = true;
90
+ }
91
+ const emailVerificationConfig = auth.options?.emailVerification || auth.emailVerification;
92
+ if (emailVerificationConfig && !emailVerificationConfig.__studio_wrapped) {
93
+ const originalOnEmailVerification = emailVerificationConfig.onEmailVerification;
94
+ emailVerificationConfig.onEmailVerification = wrapCallback(originalOnEmailVerification, 'user.email_verified', (args) => {
95
+ const user = args[0];
96
+ return {
97
+ userId: user?.id,
98
+ metadata: {
99
+ email: user?.email,
100
+ name: user?.name,
101
+ verifiedAt: new Date().toISOString(),
102
+ },
103
+ };
104
+ });
105
+ emailVerificationConfig.__studio_wrapped = true;
106
+ }
107
+ const emailAndPasswordConfig = auth.options?.emailAndPassword || auth.emailAndPassword;
108
+ if (emailAndPasswordConfig && !emailAndPasswordConfig.__studio_wrapped) {
109
+ const originalOnPasswordChange = emailAndPasswordConfig.onPasswordChange;
110
+ emailAndPasswordConfig.onPasswordChange = wrapCallback(originalOnPasswordChange, 'user.password_changed', (args) => {
111
+ const data = args[0];
112
+ return {
113
+ userId: data?.user?.id,
114
+ metadata: {
115
+ email: data?.user?.email,
116
+ name: data?.user?.name,
117
+ revokeOtherSessions: data?.revokeOtherSessions || false,
118
+ changedAt: new Date().toISOString(),
119
+ },
120
+ };
121
+ });
122
+ // Wrap sendResetPassword to track password.reset_requested
123
+ const originalSendResetPassword = emailAndPasswordConfig.sendResetPassword;
124
+ if (originalSendResetPassword) {
125
+ emailAndPasswordConfig.sendResetPassword = async (...args) => {
126
+ const data = args[0];
127
+ const request = args[1];
128
+ const requestInfo = getRequestInfo(request);
129
+ // Mark this email as using token-based reset
130
+ const email = data?.user?.email?.toLowerCase();
131
+ if (email) {
132
+ passwordResetMethod.set(email, 'token');
133
+ }
134
+ const originalPromise = originalSendResetPassword(...args);
135
+ const eventPromise = emitEvent('password.reset_requested', {
136
+ status: 'success',
137
+ userId: data?.user?.id,
138
+ metadata: {
139
+ email: data?.user?.email,
140
+ name: data?.user?.name || data?.user?.email || 'Someone',
141
+ requestedAt: new Date().toISOString(),
142
+ },
143
+ request: requestInfo,
144
+ }, capturedConfig).catch(() => { });
145
+ await originalPromise;
146
+ eventPromise.catch(() => { });
147
+ };
148
+ }
149
+ const originalOnPasswordReset = emailAndPasswordConfig.onPasswordReset;
150
+ emailAndPasswordConfig.onPasswordReset = async (...args) => {
151
+ if (originalOnPasswordReset) {
152
+ await originalOnPasswordReset(...args);
153
+ }
154
+ const data = args[0];
155
+ const request = args[1];
156
+ const requestInfo = getRequestInfo(request);
157
+ const userEmail = data?.user?.email?.toLowerCase();
158
+ const method = userEmail ? passwordResetMethod.get(userEmail) : undefined;
159
+ const isOtpReset = method === 'otp';
160
+ if (userEmail) {
161
+ passwordResetMethod.delete(userEmail);
162
+ }
163
+ const eventType = isOtpReset ? 'password.reset_completed_otp' : 'password.reset_completed';
164
+ emitEvent(eventType, {
165
+ status: 'success',
166
+ userId: data?.user?.id,
167
+ metadata: {
168
+ email: data?.user?.email,
169
+ name: data?.user?.name || data?.user?.email || 'Someone',
170
+ resetAt: new Date().toISOString(),
171
+ method: isOtpReset ? 'email_otp' : 'token',
172
+ },
173
+ request: requestInfo,
174
+ }, capturedConfig).catch(() => { });
175
+ };
176
+ emailAndPasswordConfig.__studio_wrapped = true;
177
+ }
178
+ const emailOtpPlugin = auth.options?.plugins?.find((p) => p?.id === 'email-otp');
179
+ // TODO: Fix email-otp sendVerificationOTP callback wrapping because of plugin closure
180
+ if (emailOtpPlugin && !emailOtpPlugin.__studio_wrapped) {
181
+ const originalSendVerificationOTP = emailOtpPlugin.options?.sendVerificationOTP;
182
+ if (originalSendVerificationOTP) {
183
+ const wrappedSendVerificationOTP = async (data, ctx) => {
184
+ const requestInfo = getRequestInfo(ctx?.request || ctx);
185
+ if (data.type === 'forget-password') {
186
+ const email = data.email.toLowerCase();
187
+ passwordResetMethod.set(email, 'otp');
188
+ }
189
+ const originalPromise = originalSendVerificationOTP(data, ctx);
190
+ if (data.type === 'forget-password') {
191
+ const eventPromise = emitEvent('password.reset_requested_otp', {
192
+ status: 'success',
193
+ metadata: {
194
+ email: data.email,
195
+ type: 'forget-password',
196
+ requestedAt: new Date().toISOString(),
197
+ },
198
+ request: requestInfo,
199
+ }, capturedConfig).catch(() => { });
200
+ await originalPromise;
201
+ eventPromise.catch(() => { });
202
+ }
203
+ else {
204
+ await originalPromise;
205
+ }
206
+ };
207
+ emailOtpPlugin.options.sendVerificationOTP = wrappedSendVerificationOTP;
208
+ const originalInit = emailOtpPlugin.init;
209
+ if (originalInit && typeof originalInit === 'function') {
210
+ emailOtpPlugin.init = async (authInstance) => {
211
+ emailOtpPlugin.options.sendVerificationOTP = wrappedSendVerificationOTP;
212
+ await originalInit(authInstance);
213
+ // Re-apply after init
214
+ if (emailOtpPlugin.options) {
215
+ emailOtpPlugin.options.sendVerificationOTP = wrappedSendVerificationOTP;
216
+ }
217
+ };
218
+ }
219
+ }
220
+ emailOtpPlugin.__studio_wrapped = true;
221
+ }
222
+ }
223
+ catch (error) {
224
+ // Silently fail - callback wrapping is optional
225
+ }
226
+ }
227
+ //# sourceMappingURL=auth-callbacks-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-callbacks-injector.js","sourceRoot":"","sources":["../../src/utils/auth-callbacks-injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { StudioConfig } from '../types/handler.js';
2
+ /**
3
+ * Wraps Better Auth callbacks to automatically emit events
4
+ * This should be called during Better Auth initialization
5
+ */
6
+ export declare function wrapAuthCallbacks(auth: any, eventsConfig: StudioConfig['events']): void;
7
+ //# sourceMappingURL=auth-callbacks-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-callbacks-wrapper.d.ts","sourceRoot":"","sources":["../../src/utils/auth-callbacks-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAwCxD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,GAAG,EACT,YAAY,EAAE,YAAY,CAAC,QAAQ,CAAC,GACnC,IAAI,CA+GN"}
@@ -0,0 +1,123 @@
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
+ // Standard Request object
12
+ request.headers.forEach((value, key) => {
13
+ headersObj[key] = value;
14
+ });
15
+ ip = request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined;
16
+ }
17
+ else if (request.headers) {
18
+ // Object with headers property
19
+ if (typeof request.headers.get === 'function') {
20
+ ip = 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
+ /**
40
+ * Wraps Better Auth callbacks to automatically emit events
41
+ * This should be called during Better Auth initialization
42
+ */
43
+ export function wrapAuthCallbacks(auth, eventsConfig) {
44
+ if (!auth || !eventsConfig?.enabled) {
45
+ return;
46
+ }
47
+ try {
48
+ const capturedConfig = eventsConfig;
49
+ // Helper to wrap a callback function
50
+ const wrapCallback = (originalCallback, eventType, eventData) => {
51
+ return (async (...args) => {
52
+ // Call original callback if it exists
53
+ if (originalCallback) {
54
+ await originalCallback(...args);
55
+ }
56
+ // Emit event
57
+ const data = eventData(args);
58
+ const requestInfo = getRequestInfo(args[args.length - 1]); // Last arg is usually request
59
+ emitEvent(eventType, {
60
+ status: 'success',
61
+ ...data,
62
+ request: requestInfo,
63
+ }, capturedConfig).catch(() => { });
64
+ });
65
+ };
66
+ // Wrap user.deleteUser.afterDelete callback
67
+ // Check multiple possible locations
68
+ const deleteUserConfig = auth.options?.user?.deleteUser || auth.user?.deleteUser;
69
+ if (deleteUserConfig && !deleteUserConfig.__studio_wrapped) {
70
+ const originalAfterDelete = deleteUserConfig.afterDelete;
71
+ deleteUserConfig.afterDelete = wrapCallback(originalAfterDelete, 'user.deleted', (args) => {
72
+ const user = args[0];
73
+ return {
74
+ userId: user?.id,
75
+ metadata: {
76
+ email: user?.email,
77
+ name: user?.name,
78
+ },
79
+ };
80
+ });
81
+ deleteUserConfig.__studio_wrapped = true;
82
+ }
83
+ // Wrap emailVerification.onEmailVerification callback
84
+ const emailVerificationConfig = auth.options?.emailVerification || auth.emailVerification;
85
+ if (emailVerificationConfig && !emailVerificationConfig.__studio_wrapped) {
86
+ const originalOnEmailVerification = emailVerificationConfig.onEmailVerification;
87
+ emailVerificationConfig.onEmailVerification = wrapCallback(originalOnEmailVerification, 'user.email_verified', (args) => {
88
+ const user = args[0];
89
+ return {
90
+ userId: user?.id,
91
+ metadata: {
92
+ email: user?.email,
93
+ name: user?.name,
94
+ verifiedAt: new Date().toISOString(),
95
+ },
96
+ };
97
+ });
98
+ emailVerificationConfig.__studio_wrapped = true;
99
+ }
100
+ // Wrap emailAndPassword.onPasswordChange callback
101
+ const emailAndPasswordConfig = auth.options?.emailAndPassword || auth.emailAndPassword;
102
+ if (emailAndPasswordConfig && !emailAndPasswordConfig.__studio_wrapped) {
103
+ const originalOnPasswordChange = emailAndPasswordConfig.onPasswordChange;
104
+ emailAndPasswordConfig.onPasswordChange = wrapCallback(originalOnPasswordChange, 'user.password_changed', (args) => {
105
+ const data = args[0];
106
+ return {
107
+ userId: data?.user?.id,
108
+ metadata: {
109
+ email: data?.user?.email,
110
+ name: data?.user?.name,
111
+ revokeOtherSessions: data?.revokeOtherSessions || false,
112
+ changedAt: new Date().toISOString(),
113
+ },
114
+ };
115
+ });
116
+ emailAndPasswordConfig.__studio_wrapped = true;
117
+ }
118
+ }
119
+ catch (error) {
120
+ console.error('[Auth Callbacks] Failed to wrap callbacks:', error);
121
+ }
122
+ }
123
+ //# sourceMappingURL=auth-callbacks-wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-callbacks-wrapper.js","sourceRoot":"","sources":["../../src/utils/auth-callbacks-wrapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { StudioConfig } from '../types/handler.js';
2
+ export declare function wrapDatabaseHooks(auth: any, eventsConfig: StudioConfig['events']): void;
3
+ //# sourceMappingURL=database-hook-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-hook-injector.d.ts","sourceRoot":"","sources":["../../src/utils/database-hook-injector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAI,CA+JvF"}
@@ -0,0 +1,141 @@
1
+ import { emitEvent } from './event-ingestion.js';
2
+ export function wrapDatabaseHooks(auth, eventsConfig) {
3
+ if (!auth || !eventsConfig?.enabled) {
4
+ return;
5
+ }
6
+ try {
7
+ // Ensure auth.options exists
8
+ if (!auth.options) {
9
+ auth.options = {};
10
+ }
11
+ // Only proceed if auth.options is a valid object
12
+ if (typeof auth.options !== 'object' || auth.options === null) {
13
+ console.warn('[Database Hooks] auth.options is not a valid object');
14
+ return;
15
+ }
16
+ const capturedConfig = eventsConfig;
17
+ // Initialize databaseHooks if it doesn't exist
18
+ if (!auth.options.databaseHooks) {
19
+ auth.options.databaseHooks = {};
20
+ }
21
+ // Check if already wrapped
22
+ if (auth.options.databaseHooks.__studio_wrapped) {
23
+ return;
24
+ }
25
+ // Ensure databaseHooks is an object
26
+ if (typeof auth.options.databaseHooks !== 'object' || auth.options.databaseHooks === null) {
27
+ console.warn('[Database Hooks] databaseHooks is not a valid object');
28
+ return;
29
+ }
30
+ try {
31
+ const existingAccountHooks = auth.options.databaseHooks.account || {};
32
+ const existingCreateHooks = existingAccountHooks.create || {};
33
+ const existingAfter = existingCreateHooks.after;
34
+ const oauthAccountAfter = async (account, context) => {
35
+ // Validate context and internalAdapter exist
36
+ if (!context || !context.internalAdapter) {
37
+ console.warn('[OAuth DB Hook] Context or internalAdapter is missing');
38
+ return;
39
+ }
40
+ // Validate account exists
41
+ if (!account || !account.userId || !account.providerId) {
42
+ return;
43
+ }
44
+ console.log('OAuth account created', account);
45
+ if (account.providerId !== 'credential') {
46
+ try {
47
+ // Ensure internalAdapter methods exist
48
+ if (typeof context.internalAdapter.findUserById !== 'function' ||
49
+ typeof context.internalAdapter.findAccounts !== 'function') {
50
+ console.warn('[OAuth DB Hook] internalAdapter methods are missing');
51
+ return;
52
+ }
53
+ const user = await context.internalAdapter.findUserById(account.userId);
54
+ if (user) {
55
+ const existingAccounts = await context.internalAdapter.findAccounts(account.userId);
56
+ const isLinking = existingAccounts && existingAccounts.length > 1; // More than just this new account
57
+ if (isLinking) {
58
+ await emitEvent('oauth.linked', {
59
+ status: 'success',
60
+ userId: account.userId,
61
+ metadata: {
62
+ provider: account.providerId,
63
+ providerId: account.providerId,
64
+ userEmail: user.email,
65
+ email: user.email,
66
+ name: user.name,
67
+ accountId: account.accountId,
68
+ linkedAt: new Date().toISOString(),
69
+ },
70
+ }, capturedConfig).catch(() => { });
71
+ }
72
+ else {
73
+ await emitEvent('oauth.sign_in', {
74
+ status: 'success',
75
+ userId: account.userId,
76
+ metadata: {
77
+ provider: account.providerId,
78
+ providerId: account.providerId,
79
+ userEmail: user.email,
80
+ email: user.email,
81
+ name: user.name,
82
+ emailVerified: user.emailVerified,
83
+ accountId: account.accountId,
84
+ createdAt: user.createdAt
85
+ ? new Date(user.createdAt).toISOString()
86
+ : new Date().toISOString(),
87
+ },
88
+ }, capturedConfig).catch(() => { });
89
+ }
90
+ }
91
+ }
92
+ catch (error) {
93
+ console.error('[OAuth DB Hook] Error:', error);
94
+ }
95
+ }
96
+ };
97
+ // Safely assign the hook - wrap in try-catch to prevent any Better Auth initialization errors
98
+ try {
99
+ auth.options.databaseHooks.account = {
100
+ ...existingAccountHooks,
101
+ create: {
102
+ ...existingCreateHooks,
103
+ before: existingCreateHooks.before,
104
+ after: async (account, context) => {
105
+ try {
106
+ // Call existing hook first if it exists
107
+ if (existingAfter && typeof existingAfter === 'function') {
108
+ await existingAfter(account, context);
109
+ }
110
+ // Then call our OAuth tracking hook
111
+ await oauthAccountAfter(account, context);
112
+ }
113
+ catch (error) {
114
+ // Don't let hook errors break the flow
115
+ console.error('[Database Hook] Error in after hook:', error);
116
+ // Re-throw only if it's not a reloadNavigation error (Better Auth internal issue)
117
+ if (error instanceof Error && !error.message.includes('reloadNavigation')) {
118
+ throw error;
119
+ }
120
+ }
121
+ },
122
+ },
123
+ };
124
+ auth.options.databaseHooks.__studio_wrapped = true;
125
+ }
126
+ catch (assignError) {
127
+ // If assignment fails, log but don't crash
128
+ console.error('[Database Hooks] Error assigning hooks:', assignError);
129
+ // Don't mark as wrapped if assignment failed
130
+ }
131
+ }
132
+ catch (hookError) {
133
+ console.error('[Database Hooks] Error setting up hooks:', hookError);
134
+ // Don't mark as wrapped if there was an error
135
+ }
136
+ }
137
+ catch (error) {
138
+ console.error('[Database Hooks] Failed to wrap:', error);
139
+ }
140
+ }
141
+ //# sourceMappingURL=database-hook-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-hook-injector.js","sourceRoot":"","sources":["../../src/utils/database-hook-injector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { StudioConfig } from '../types/handler.js';
2
+ /**
3
+ * Wraps email-otp plugin callbacks to automatically emit events
4
+ * This wraps the sendVerificationOTP callback similar to how organization hooks work
5
+ *
6
+ * @param eventsConfig - The events configuration
7
+ * @param existingCallback - The original sendVerificationOTP callback
8
+ * @param passwordResetMethodMap - Optional shared Map to track password reset method (OTP vs token)
9
+ */
10
+ export declare function wrapEmailOTPPluginCallbacks(eventsConfig: StudioConfig['events'], existingCallback?: (data: {
11
+ email: string;
12
+ otp: string;
13
+ type: 'sign-in' | 'email-verification' | 'forget-password';
14
+ }, ctx?: any) => Promise<void>, passwordResetMethodMap?: Map<string, 'otp' | 'token'>): ((data: {
15
+ email: string;
16
+ otp: string;
17
+ type: 'sign-in' | 'email-verification' | 'forget-password';
18
+ }, ctx?: any) => Promise<void>) | undefined;
19
+ /**
20
+ * Automatically wraps email-otp plugin callbacks to emit events
21
+ * This should be called during Better Auth initialization
22
+ * Similar to wrapOrganizationPluginHooks but for callbacks
23
+ *
24
+ * @param auth - The Better Auth instance
25
+ * @param eventsConfig - The events configuration
26
+ * @param passwordResetMethodMap - Optional shared Map to track password reset method (OTP vs token)
27
+ */
28
+ export declare function wrapEmailOTPPluginHooks(auth: any, eventsConfig: StudioConfig['events'], passwordResetMethodMap?: Map<string, 'otp' | 'token'>): void;
29
+ //# sourceMappingURL=email-otp-hooks-injector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-otp-hooks-injector.d.ts","sourceRoot":"","sources":["../../src/utils/email-otp-hooks-injector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA+CxD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,YAAY,CAAC,QAAQ,CAAC,EACpC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,oBAAoB,GAAG,iBAAiB,CAAA;CAAE,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EACjJ,sBAAsB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC,GACpD,CAAC,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,GAAG,oBAAoB,GAAG,iBAAiB,CAAA;CAAE,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAqD9I;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,GAAG,EACT,YAAY,EAAE,YAAY,CAAC,QAAQ,CAAC,EACpC,sBAAsB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC,GACpD,IAAI,CAwCN"}