better-auth-studio 1.0.59-beta.9 → 1.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +188 -3
- package/dist/routes.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/main-p2dU6WGq.js +1140 -0
- package/public/index.html +1 -1
- package/public/assets/main-fX0tKK6u.js +0 -1104
package/dist/routes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAeA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAS9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+D9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAqLhG;AAeD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAeA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAS9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+D9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAqLhG;AAeD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAkzLR"}
|
package/dist/routes.js
CHANGED
|
@@ -5122,14 +5122,11 @@ export const authClient = createAuthClient({
|
|
|
5122
5122
|
}
|
|
5123
5123
|
const envPath = join(process.cwd(), '.env');
|
|
5124
5124
|
const envLocalPath = join(process.cwd(), '.env.local');
|
|
5125
|
-
// Try .env.local first, then .env
|
|
5126
5125
|
const targetPath = existsSync(envLocalPath) ? envLocalPath : envPath;
|
|
5127
5126
|
const envContent = existsSync(targetPath) ? readFileSync(targetPath, 'utf-8') : '';
|
|
5128
|
-
// Generate environment variable names
|
|
5129
5127
|
const providerUpper = provider.toUpperCase();
|
|
5130
5128
|
const clientIdKey = `${providerUpper}_CLIENT_ID`;
|
|
5131
5129
|
const clientSecretKey = `${providerUpper}_CLIENT_SECRET`;
|
|
5132
|
-
// Parse existing .env file
|
|
5133
5130
|
const envLines = envContent.split('\n');
|
|
5134
5131
|
const existingCredentials = {};
|
|
5135
5132
|
envLines.forEach((line) => {
|
|
@@ -5291,6 +5288,194 @@ export const authClient = createAuthClient({
|
|
|
5291
5288
|
});
|
|
5292
5289
|
}
|
|
5293
5290
|
});
|
|
5291
|
+
router.post('/api/tools/apply-email-template', async (req, res) => {
|
|
5292
|
+
try {
|
|
5293
|
+
const { subject, html, templateId } = req.body || {};
|
|
5294
|
+
if (!subject || !html || !templateId) {
|
|
5295
|
+
return res
|
|
5296
|
+
.status(400)
|
|
5297
|
+
.json({ success: false, message: 'templateId, subject and html are required' });
|
|
5298
|
+
}
|
|
5299
|
+
const authPath = join(process.cwd(), 'examples/nextjs/prisma/lib/auth.ts');
|
|
5300
|
+
if (!existsSync(authPath)) {
|
|
5301
|
+
return res.status(404).json({ success: false, message: 'auth.ts not found' });
|
|
5302
|
+
}
|
|
5303
|
+
let fileContent = readFileSync(authPath, 'utf-8');
|
|
5304
|
+
const escapedSubject = subject.replace(/`/g, '\\`').replace(/\${/g, '\\${');
|
|
5305
|
+
const escapedHtml = html.replace(/`/g, '\\`').replace(/\${/g, '\\${');
|
|
5306
|
+
if (!fileContent.includes("from 'resend'")) {
|
|
5307
|
+
fileContent = `import { Resend } from 'resend';\n` + fileContent;
|
|
5308
|
+
}
|
|
5309
|
+
if (!fileContent.includes('const resend = new Resend(')) {
|
|
5310
|
+
const importBlockEnd = fileContent.indexOf('\n', fileContent.lastIndexOf('import'));
|
|
5311
|
+
if (importBlockEnd > -1) {
|
|
5312
|
+
fileContent =
|
|
5313
|
+
fileContent.slice(0, importBlockEnd + 1) +
|
|
5314
|
+
`const resend = new Resend(process.env.RESEND_API_KEY || '');\n` +
|
|
5315
|
+
fileContent.slice(importBlockEnd + 1);
|
|
5316
|
+
}
|
|
5317
|
+
else {
|
|
5318
|
+
fileContent =
|
|
5319
|
+
`const resend = new Resend(process.env.RESEND_API_KEY || '');\n` + fileContent;
|
|
5320
|
+
}
|
|
5321
|
+
}
|
|
5322
|
+
const handlers = {
|
|
5323
|
+
'password-reset': {
|
|
5324
|
+
regex: /sendResetPassword\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
|
|
5325
|
+
fn: `sendResetPassword: async ({ user, url, token }, request) => {
|
|
5326
|
+
const subject = \\\`${escapedSubject}\\\`
|
|
5327
|
+
.replace(/{{user.name}}/g, user?.name || '')
|
|
5328
|
+
.replace(/{{user.email}}/g, user?.email || '');
|
|
5329
|
+
|
|
5330
|
+
const html = \\\`${escapedHtml}\\\`
|
|
5331
|
+
.replace(/{{user.name}}/g, user?.name || '')
|
|
5332
|
+
.replace(/{{user.email}}/g, user?.email || '')
|
|
5333
|
+
.replace(/{{url}}/g, url || '')
|
|
5334
|
+
.replace(/{{token}}/g, token || '');
|
|
5335
|
+
|
|
5336
|
+
void sendEmail({
|
|
5337
|
+
to: user.email,
|
|
5338
|
+
subject,
|
|
5339
|
+
html,
|
|
5340
|
+
});
|
|
5341
|
+
}`,
|
|
5342
|
+
},
|
|
5343
|
+
'email-verification': {
|
|
5344
|
+
regex: /sendVerificationEmail\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
|
|
5345
|
+
fn: `sendVerificationEmail: async ({ user, url, token }, request) => {
|
|
5346
|
+
const subject = \\\`${escapedSubject}\\\`
|
|
5347
|
+
.replace(/{{user.name}}/g, user?.name || '')
|
|
5348
|
+
.replace(/{{user.email}}/g, user?.email || '');
|
|
5349
|
+
|
|
5350
|
+
const html = \\\`${escapedHtml}\\\`
|
|
5351
|
+
.replace(/{{user.name}}/g, user?.name || '')
|
|
5352
|
+
.replace(/{{user.email}}/g, user?.email || '')
|
|
5353
|
+
.replace(/{{url}}/g, url || '')
|
|
5354
|
+
.replace(/{{token}}/g, token || '');
|
|
5355
|
+
|
|
5356
|
+
void sendEmail({
|
|
5357
|
+
to: user.email,
|
|
5358
|
+
subject,
|
|
5359
|
+
html,
|
|
5360
|
+
});
|
|
5361
|
+
}`,
|
|
5362
|
+
},
|
|
5363
|
+
'magic-link': {
|
|
5364
|
+
regex: /sendMagicLink\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
|
|
5365
|
+
fn: `sendMagicLink: async ({ email, token, url }, ctx) => {
|
|
5366
|
+
const subject = \\\`${escapedSubject}\\\`
|
|
5367
|
+
.replace(/{{user.email}}/g, email || '');
|
|
5368
|
+
|
|
5369
|
+
const html = \\\`${escapedHtml}\\\`
|
|
5370
|
+
.replace(/{{user.email}}/g, email || '')
|
|
5371
|
+
.replace(/{{url}}/g, url || '')
|
|
5372
|
+
.replace(/{{token}}/g, token || '');
|
|
5373
|
+
|
|
5374
|
+
void sendEmail({
|
|
5375
|
+
to: email,
|
|
5376
|
+
subject,
|
|
5377
|
+
html,
|
|
5378
|
+
});
|
|
5379
|
+
}`,
|
|
5380
|
+
},
|
|
5381
|
+
'org-invitation': {
|
|
5382
|
+
regex: /sendInvitationEmail\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
|
|
5383
|
+
fn: `sendInvitationEmail: async ({ data, request }: {
|
|
5384
|
+
data: {
|
|
5385
|
+
invitation: {
|
|
5386
|
+
id: string;
|
|
5387
|
+
organizationId: string;
|
|
5388
|
+
email: string;
|
|
5389
|
+
role: string;
|
|
5390
|
+
status: "pending" | "accepted" | "rejected" | "canceled";
|
|
5391
|
+
inviterId: string;
|
|
5392
|
+
expiresAt: Date;
|
|
5393
|
+
createdAt: Date;
|
|
5394
|
+
teamId?: string | null | undefined;
|
|
5395
|
+
};
|
|
5396
|
+
organization: { name?: string; slug?: string };
|
|
5397
|
+
inviter: { user: { name?: string; email?: string } };
|
|
5398
|
+
};
|
|
5399
|
+
request?: Request;
|
|
5400
|
+
}) => {
|
|
5401
|
+
const { invitation, organization, inviter } = data;
|
|
5402
|
+
const baseUrl = process.env.BETTER_AUTH_URL || 'http://localhost:3000';
|
|
5403
|
+
const url = \\\`\\\${baseUrl}/accept-invitation?id=\\\${invitation.id}\\\`;
|
|
5404
|
+
|
|
5405
|
+
const subject = \\\`${escapedSubject}\\\`
|
|
5406
|
+
.replace(/{{organization.name}}/g, organization?.name || '')
|
|
5407
|
+
.replace(/{{invitation.role}}/g, invitation.role || '')
|
|
5408
|
+
.replace(/{{inviter.user.name}}/g, inviter?.user?.name || '')
|
|
5409
|
+
.replace(/{{inviter.user.email}}/g, inviter?.user?.email || '')
|
|
5410
|
+
.replace(/{{invitation.email}}/g, invitation.email || '');
|
|
5411
|
+
|
|
5412
|
+
const html = \\\`${escapedHtml}\\\`
|
|
5413
|
+
.replace(/{{invitation.url}}/g, url)
|
|
5414
|
+
.replace(/{{invitation.role}}/g, invitation.role || '')
|
|
5415
|
+
.replace(/{{organization.name}}/g, organization?.name || '')
|
|
5416
|
+
.replace(/{{organization.slug}}/g, organization?.slug || '')
|
|
5417
|
+
.replace(/{{inviter.user.name}}/g, inviter?.user?.name || '')
|
|
5418
|
+
.replace(/{{inviter.user.email}}/g, inviter?.user?.email || '')
|
|
5419
|
+
.replace(/{{invitation.email}}/g, invitation.email || '')
|
|
5420
|
+
.replace(/{{invitation.expiresAt}}/g, invitation.expiresAt?.toLocaleString() || '')
|
|
5421
|
+
.replace(/{{expiresIn}}/g, invitation.expiresAt ? \\\`\\\${Math.ceil((invitation.expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24))} days\\\` : '');
|
|
5422
|
+
|
|
5423
|
+
void sendEmail({
|
|
5424
|
+
to: invitation.email,
|
|
5425
|
+
subject,
|
|
5426
|
+
html,
|
|
5427
|
+
});
|
|
5428
|
+
}`,
|
|
5429
|
+
},
|
|
5430
|
+
};
|
|
5431
|
+
const handler = handlers[templateId];
|
|
5432
|
+
if (!handler) {
|
|
5433
|
+
return res
|
|
5434
|
+
.status(400)
|
|
5435
|
+
.json({ success: false, message: 'Unsupported templateId for apply' });
|
|
5436
|
+
}
|
|
5437
|
+
if (!fileContent.includes('const sendEmail = async')) {
|
|
5438
|
+
const insertPoint = fileContent.indexOf('export const auth');
|
|
5439
|
+
fileContent =
|
|
5440
|
+
fileContent.slice(0, insertPoint) +
|
|
5441
|
+
`const sendEmail = async ({ to, subject, text, html }: { to: string; subject: string; text?: string; html?: string }) => {\n console.log(\`Sending email to \${to} | \${subject}\`);\n if (text) console.log('Text content:', text);\n if (html) console.log('HTML content:', html);\n};\n\n` +
|
|
5442
|
+
fileContent.slice(insertPoint);
|
|
5443
|
+
}
|
|
5444
|
+
if (handler.regex.test(fileContent)) {
|
|
5445
|
+
fileContent = fileContent.replace(handler.regex, `${handler.fn},`);
|
|
5446
|
+
}
|
|
5447
|
+
else {
|
|
5448
|
+
if (templateId === 'org-invitation') {
|
|
5449
|
+
const orgPluginRegex = /organization\(\s*\{\s*/;
|
|
5450
|
+
if (!orgPluginRegex.test(fileContent)) {
|
|
5451
|
+
return res.status(400).json({
|
|
5452
|
+
success: false,
|
|
5453
|
+
message: 'organization plugin config not found in auth.ts',
|
|
5454
|
+
});
|
|
5455
|
+
}
|
|
5456
|
+
fileContent = fileContent.replace(orgPluginRegex, (m) => `${m}${handler.fn},\n `);
|
|
5457
|
+
}
|
|
5458
|
+
else {
|
|
5459
|
+
const emailAndPasswordRegex = /emailAndPassword\s*:\s*\{\s*/;
|
|
5460
|
+
if (!emailAndPasswordRegex.test(fileContent)) {
|
|
5461
|
+
return res.status(400).json({
|
|
5462
|
+
success: false,
|
|
5463
|
+
message: 'emailAndPassword config not found in auth.ts',
|
|
5464
|
+
});
|
|
5465
|
+
}
|
|
5466
|
+
fileContent = fileContent.replace(emailAndPasswordRegex, (m) => `${m}${handler.fn},\n `);
|
|
5467
|
+
}
|
|
5468
|
+
}
|
|
5469
|
+
writeFileSync(authPath, fileContent, 'utf-8');
|
|
5470
|
+
res.json({ success: true, path: authPath });
|
|
5471
|
+
}
|
|
5472
|
+
catch (error) {
|
|
5473
|
+
res.status(500).json({
|
|
5474
|
+
success: false,
|
|
5475
|
+
message: error?.message || 'Failed to apply invitation template',
|
|
5476
|
+
});
|
|
5477
|
+
}
|
|
5478
|
+
});
|
|
5294
5479
|
return router;
|
|
5295
5480
|
}
|
|
5296
5481
|
//# sourceMappingURL=routes.js.map
|