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.
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +152 -5
- package/dist/routes.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/{main-Dr59Z9SU.js → main-BTK8lljT.js} +118 -118
- package/public/assets/main-D2JmQhDd.css +1 -0
- package/public/index.html +2 -2
- package/public/assets/main-DMsUh9lG.css +0 -1
package/dist/routes.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
|
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
|