better-auth-studio 1.0.49-beta.7 → 1.0.49-beta.9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAOA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAS9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA8D9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA8I/E;AAwBD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CA63JR"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAOA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAS9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA8D9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CA8I/E;AAwBD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAyiKR"}
package/dist/routes.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createHmac, randomBytes } from 'node:crypto';
2
- import { existsSync, readFileSync } from 'node:fs';
2
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { fileURLToPath, pathToFileURL } from 'node:url';
5
5
  // @ts-expect-error
@@ -4493,7 +4493,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
4493
4493
  if (provider.toLowerCase() === 'google') {
4494
4494
  try {
4495
4495
  const tokenInfoUrl = `https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=test`;
4496
- const isValidClientIdFormat = /^[\d\w\-]+\.apps\.googleusercontent\.com$|^\d+$/.test(clientId);
4496
+ const isValidClientIdFormat = /^[\d\w-]+\.apps\.googleusercontent\.com$|^\d+$/.test(clientId);
4497
4497
  if (!isValidClientIdFormat) {
4498
4498
  return res.json({
4499
4499
  success: false,
@@ -4598,9 +4598,7 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
4598
4598
  const secretLength = typeof length === 'number' && length >= 16 && length <= 128 ? length : 32;
4599
4599
  const secretFormat = format === 'base64' ? 'base64' : 'hex';
4600
4600
  const secretBytes = randomBytes(secretLength);
4601
- const secret = secretFormat === 'hex'
4602
- ? secretBytes.toString('hex')
4603
- : secretBytes.toString('base64');
4601
+ const secret = secretFormat === 'hex' ? secretBytes.toString('hex') : secretBytes.toString('base64');
4604
4602
  const entropy = secretLength * 8; // bits of entropy
4605
4603
  res.json({
4606
4604
  success: true,
@@ -4618,6 +4616,155 @@ export function createRoutes(authConfig, configPath, geoDbPath) {
4618
4616
  });
4619
4617
  }
4620
4618
  });
4619
+ router.post('/api/tools/check-env-credentials', async (req, res) => {
4620
+ try {
4621
+ const { provider } = req.body || {};
4622
+ if (!provider) {
4623
+ return res.status(400).json({
4624
+ success: false,
4625
+ message: 'Provider is required',
4626
+ });
4627
+ }
4628
+ const envPath = join(process.cwd(), '.env');
4629
+ const envLocalPath = join(process.cwd(), '.env.local');
4630
+ // Try .env.local first, then .env
4631
+ const targetPath = existsSync(envLocalPath) ? envLocalPath : envPath;
4632
+ const envContent = existsSync(targetPath) ? readFileSync(targetPath, 'utf-8') : '';
4633
+ // Generate environment variable names
4634
+ const providerUpper = provider.toUpperCase();
4635
+ const clientIdKey = `${providerUpper}_CLIENT_ID`;
4636
+ const clientSecretKey = `${providerUpper}_CLIENT_SECRET`;
4637
+ // Parse existing .env file
4638
+ const envLines = envContent.split('\n');
4639
+ const existingCredentials = {};
4640
+ envLines.forEach((line) => {
4641
+ const trimmed = line.trim();
4642
+ if (!trimmed || trimmed.startsWith('#'))
4643
+ return;
4644
+ const match = trimmed.match(/^([^=#]+)=(.*)$/);
4645
+ if (match) {
4646
+ const key = match[1].trim();
4647
+ const value = match[2].trim();
4648
+ if (key === clientIdKey || key === clientSecretKey) {
4649
+ existingCredentials[key] = value;
4650
+ }
4651
+ }
4652
+ });
4653
+ const hasExisting = existingCredentials[clientIdKey] || existingCredentials[clientSecretKey];
4654
+ res.json({
4655
+ success: true,
4656
+ hasExisting,
4657
+ existingCredentials: hasExisting ? existingCredentials : {},
4658
+ path: targetPath,
4659
+ });
4660
+ }
4661
+ catch (error) {
4662
+ res.status(500).json({
4663
+ success: false,
4664
+ message: error instanceof Error ? error.message : 'Failed to check credentials',
4665
+ });
4666
+ }
4667
+ });
4668
+ router.post('/api/tools/write-env-credentials', async (req, res) => {
4669
+ try {
4670
+ const { provider, clientId, clientSecret, action = 'override' } = req.body || {};
4671
+ if (!provider || !clientId || !clientSecret) {
4672
+ return res.status(400).json({
4673
+ success: false,
4674
+ message: 'Provider, Client ID, and Client Secret are required',
4675
+ });
4676
+ }
4677
+ const envPath = join(process.cwd(), '.env');
4678
+ const envLocalPath = join(process.cwd(), '.env.local');
4679
+ const targetPath = existsSync(envLocalPath) ? envLocalPath : envPath;
4680
+ const envContent = existsSync(targetPath) ? readFileSync(targetPath, 'utf-8') : '';
4681
+ const envLines = envContent.split('\n');
4682
+ const envMap = new Map();
4683
+ const newLines = [];
4684
+ envLines.forEach((line, index) => {
4685
+ const trimmed = line.trim();
4686
+ if (!trimmed || trimmed.startsWith('#')) {
4687
+ newLines.push(line);
4688
+ return;
4689
+ }
4690
+ const match = trimmed.match(/^([^=#]+)=(.*)$/);
4691
+ if (match) {
4692
+ const key = match[1].trim();
4693
+ const value = match[2].trim();
4694
+ envMap.set(key, { line, index });
4695
+ newLines.push(line);
4696
+ }
4697
+ else {
4698
+ newLines.push(line);
4699
+ }
4700
+ });
4701
+ const providerUpper = provider.toUpperCase();
4702
+ let clientIdKey = `${providerUpper}_CLIENT_ID`;
4703
+ let clientSecretKey = `${providerUpper}_CLIENT_SECRET`;
4704
+ if (action === 'append') {
4705
+ let suffix = 2;
4706
+ while (envMap.has(clientIdKey) || envMap.has(clientSecretKey)) {
4707
+ clientIdKey = `${providerUpper}_CLIENT_ID_${suffix}`;
4708
+ clientSecretKey = `${providerUpper}_CLIENT_SECRET_${suffix}`;
4709
+ suffix++;
4710
+ }
4711
+ }
4712
+ let updated = false;
4713
+ if (action === 'override' && envMap.has(clientIdKey)) {
4714
+ const existing = envMap.get(clientIdKey);
4715
+ newLines[existing.index] = `${clientIdKey}=${clientId}`;
4716
+ updated = true;
4717
+ }
4718
+ else if (!envMap.has(clientIdKey)) {
4719
+ // Remove trailing empty lines
4720
+ while (newLines.length > 0 && !newLines[newLines.length - 1].trim()) {
4721
+ newLines.pop();
4722
+ }
4723
+ if (newLines.length > 0 &&
4724
+ newLines[newLines.length - 1] &&
4725
+ !newLines[newLines.length - 1].endsWith('\n')) {
4726
+ if (!newLines[newLines.length - 1].endsWith('\r\n') &&
4727
+ !newLines[newLines.length - 1].endsWith('\n')) {
4728
+ newLines.push('');
4729
+ }
4730
+ }
4731
+ newLines.push(`${clientIdKey}=${clientId}`);
4732
+ updated = true;
4733
+ }
4734
+ if (action === 'override' && envMap.has(clientSecretKey)) {
4735
+ const existing = envMap.get(clientSecretKey);
4736
+ newLines[existing.index] = `${clientSecretKey}=${clientSecret}`;
4737
+ updated = true;
4738
+ }
4739
+ else if (!envMap.has(clientSecretKey)) {
4740
+ const clientIdIndex = newLines.findIndex((line) => line.startsWith(`${clientIdKey}=`));
4741
+ if (clientIdIndex >= 0) {
4742
+ newLines.splice(clientIdIndex + 1, 0, `${clientSecretKey}=${clientSecret}`);
4743
+ }
4744
+ else {
4745
+ newLines.push(`${clientSecretKey}=${clientSecret}`);
4746
+ }
4747
+ updated = true;
4748
+ }
4749
+ const newContent = newLines.join('\n');
4750
+ writeFileSync(targetPath, newContent, 'utf-8');
4751
+ res.json({
4752
+ success: true,
4753
+ message: 'OAuth credentials written successfully',
4754
+ path: targetPath,
4755
+ variables: {
4756
+ [clientIdKey]: clientId,
4757
+ [clientSecretKey]: '***',
4758
+ },
4759
+ });
4760
+ }
4761
+ catch (error) {
4762
+ res.status(500).json({
4763
+ success: false,
4764
+ message: error instanceof Error ? error.message : 'Failed to write credentials to .env',
4765
+ });
4766
+ }
4767
+ });
4621
4768
  return router;
4622
4769
  }
4623
4770
  //# sourceMappingURL=routes.js.map