@clawchatsai/connector 0.0.55 β 0.0.57
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/index.js +76 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -785,8 +785,21 @@ async function handleSetup(token) {
|
|
|
785
785
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
786
786
|
fs.mkdirSync(uploadsDir, { recursive: true });
|
|
787
787
|
ws.close();
|
|
788
|
+
// Ask if user wants to reuse TOTP from another gateway
|
|
789
|
+
let reuseSecret;
|
|
790
|
+
if (config.schemaVersion === 1) {
|
|
791
|
+
const rlSetup = (await import('node:readline')).createInterface({ input: process.stdin, output: process.stdout });
|
|
792
|
+
const askSetup = (q) => new Promise(r => rlSetup.question(q, r));
|
|
793
|
+
console.log('');
|
|
794
|
+
console.log(' π‘ Already have ClawChats on another gateway?');
|
|
795
|
+
console.log(' Run \`openclaw clawchats show-totp\` on that machine and paste the secret below.');
|
|
796
|
+
const reuseAnswer = await askSetup(' Paste existing TOTP secret to reuse it (or press Enter to set up new): ');
|
|
797
|
+
rlSetup.close();
|
|
798
|
+
if (reuseAnswer.trim())
|
|
799
|
+
reuseSecret = reuseAnswer.trim();
|
|
800
|
+
}
|
|
788
801
|
// Enroll TOTP (interactive β requires stdin)
|
|
789
|
-
const totpOk = await enrollTotp(config);
|
|
802
|
+
const totpOk = await enrollTotp(config, reuseSecret);
|
|
790
803
|
if (!totpOk) {
|
|
791
804
|
console.log('');
|
|
792
805
|
console.log(' β οΈ TOTP not configured. You can set it up later with: openclaw clawchats reauth');
|
|
@@ -813,29 +826,38 @@ async function handleSetup(token) {
|
|
|
813
826
|
});
|
|
814
827
|
});
|
|
815
828
|
}
|
|
816
|
-
async function enrollTotp(config) {
|
|
829
|
+
async function enrollTotp(config, existingSecret) {
|
|
817
830
|
const readline = await import('node:readline');
|
|
818
831
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
819
832
|
const ask = (q) => new Promise(r => rl.question(q, r));
|
|
820
833
|
try {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
834
|
+
let totpSecret;
|
|
835
|
+
if (existingSecret) {
|
|
836
|
+
// Reusing secret from another gateway β strip spaces, uppercase
|
|
837
|
+
totpSecret = existingSecret.replace(/\s+/g, '').toUpperCase();
|
|
838
|
+
console.log('');
|
|
839
|
+
console.log(' π Verifying existing TOTP secretβ¦');
|
|
840
|
+
console.log('');
|
|
841
|
+
}
|
|
842
|
+
else {
|
|
843
|
+
// Generate a brand new TOTP secret
|
|
844
|
+
totpSecret = generateTotpSecret();
|
|
845
|
+
const email = config.google?.authorizedEmail || config.userId;
|
|
846
|
+
void buildOtpauthUri(totpSecret, email); // keep import used
|
|
847
|
+
const formatted = totpSecret.match(/.{1,4}/g)?.join(' ') || totpSecret;
|
|
848
|
+
console.log('');
|
|
849
|
+
console.log(' π Setting up two-factor authentication');
|
|
850
|
+
console.log('');
|
|
851
|
+
console.log(' Open this link to scan the QR code with your authenticator app:');
|
|
852
|
+
console.log(` ${config.serverUrl.replace('wss://', 'https://').replace(/\/ws\/?$/, '')}/totp-setup#${totpSecret}`);
|
|
853
|
+
console.log('');
|
|
854
|
+
console.log(` Or enter this code manually: ${formatted}`);
|
|
855
|
+
console.log('');
|
|
856
|
+
console.log(" Don't have an authenticator app?");
|
|
857
|
+
console.log(' Google Authenticator: https://apps.apple.com/app/google-authenticator/id388497605');
|
|
858
|
+
console.log(' https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2');
|
|
859
|
+
console.log('');
|
|
860
|
+
}
|
|
839
861
|
// Verification loop
|
|
840
862
|
let verified = false;
|
|
841
863
|
for (let attempt = 0; attempt < 5; attempt++) {
|
|
@@ -886,6 +908,27 @@ async function enrollTotp(config) {
|
|
|
886
908
|
return false;
|
|
887
909
|
}
|
|
888
910
|
}
|
|
911
|
+
async function handleShowTotp() {
|
|
912
|
+
const config = loadConfig();
|
|
913
|
+
if (!config) {
|
|
914
|
+
console.error('ClawChats not configured. Run: openclaw clawchats setup <token>');
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
if (!config.totp?.secret) {
|
|
918
|
+
console.error('No TOTP secret found. Run: openclaw clawchats reauth to set one up first.');
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
console.log('');
|
|
922
|
+
console.log('Your TOTP secret (account-level, keep this safe):');
|
|
923
|
+
console.log('');
|
|
924
|
+
console.log(` ${config.totp.secret}`);
|
|
925
|
+
console.log('');
|
|
926
|
+
console.log('To reuse this on a new gateway:');
|
|
927
|
+
console.log(' 1. Generate a setup token at login.clawchats.ai/dashboard');
|
|
928
|
+
console.log(' 2. On the new machine: openclaw clawchats setup <token>');
|
|
929
|
+
console.log(' 3. When prompted for a TOTP secret, paste the value above');
|
|
930
|
+
console.log('');
|
|
931
|
+
}
|
|
889
932
|
async function handleReauth() {
|
|
890
933
|
const config = loadConfig();
|
|
891
934
|
if (!config) {
|
|
@@ -896,7 +939,16 @@ async function handleReauth() {
|
|
|
896
939
|
console.log('');
|
|
897
940
|
console.log(' β οΈ This will invalidate all existing sessions.');
|
|
898
941
|
console.log(' All connected browsers will need to re-authenticate.');
|
|
899
|
-
|
|
942
|
+
console.log('');
|
|
943
|
+
const readline = await import('node:readline');
|
|
944
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
945
|
+
const ask = (q) => new Promise(r => rl.question(q, r));
|
|
946
|
+
let existingSecret;
|
|
947
|
+
const reuseAnswer = await ask(' Reuse TOTP from another gateway? Paste secret (or press Enter to generate new): ');
|
|
948
|
+
rl.close();
|
|
949
|
+
if (reuseAnswer.trim())
|
|
950
|
+
existingSecret = reuseAnswer.trim();
|
|
951
|
+
const success = await enrollTotp(config, existingSecret);
|
|
900
952
|
if (success) {
|
|
901
953
|
console.log(' All previous sessions have been invalidated.');
|
|
902
954
|
console.log(' Restart the gateway for changes to take effect: systemctl --user restart openclaw-gateway');
|
|
@@ -1073,6 +1125,9 @@ const plugin = {
|
|
|
1073
1125
|
cmd.command('reauth')
|
|
1074
1126
|
.description('Reset two-factor authentication (new TOTP secret + invalidate sessions)')
|
|
1075
1127
|
.action(() => handleReauth());
|
|
1128
|
+
cmd.command('show-totp')
|
|
1129
|
+
.description('Show your TOTP secret (use when adding ClawChats to a second gateway)')
|
|
1130
|
+
.action(() => handleShowTotp());
|
|
1076
1131
|
cmd.command('reset')
|
|
1077
1132
|
.description('Disconnect and remove all ClawChats data')
|
|
1078
1133
|
.action(() => handleReset());
|