- Reset master to upstream/main (16,697 commits) - Overlay 2,271 local-only files (skills, tools, workspace, configs, apps) - Restore IDENTITY.md and USER.md templates - Build verified, gateway running, Discord working Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
182 lines
5.7 KiB
JavaScript
182 lines
5.7 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
const fs = require("fs");
|
|
const https = require("https");
|
|
const { homedir } = require("os");
|
|
const { join } = require("path");
|
|
const { exec } = require("child_process");
|
|
|
|
function httpsRequest(url, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const req = https.request(url, options, (res) => {
|
|
let data = "";
|
|
res.on("data", (chunk) => (data += chunk));
|
|
res.on("end", () => {
|
|
if (res.statusCode >= 400) {
|
|
reject(new Error(`HTTP ${res.statusCode}: ${data}`));
|
|
} else {
|
|
resolve(JSON.parse(data));
|
|
}
|
|
});
|
|
});
|
|
req.on("error", reject);
|
|
if (options.body) req.write(options.body);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
async function main() {
|
|
const credsPath = join(homedir(), ".openclaw/secrets/google-oauth.json");
|
|
const creds = JSON.parse(fs.readFileSync(credsPath, "utf8"));
|
|
|
|
console.log("🔐 Google OAuth - Udvid Scopes til Sheets/Drive\n");
|
|
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
|
|
|
|
// New scopes that include Gmail, Sheets and Drive
|
|
const scopes = [
|
|
"https://www.googleapis.com/auth/gmail.readonly",
|
|
"https://www.googleapis.com/auth/gmail.send",
|
|
"https://www.googleapis.com/auth/spreadsheets.readonly",
|
|
"https://www.googleapis.com/auth/drive.readonly",
|
|
].join(" ");
|
|
|
|
const authUrl =
|
|
`https://accounts.google.com/o/oauth2/v2/auth?` +
|
|
`client_id=${creds.client_id}&` +
|
|
`redirect_uri=http://localhost:8080&` +
|
|
`response_type=code&` +
|
|
`scope=${encodeURIComponent(scopes)}&` +
|
|
`access_type=offline&` +
|
|
`prompt=consent`;
|
|
|
|
console.log("📋 NYE SCOPES:\n");
|
|
console.log(" ✅ Gmail (readonly + send)");
|
|
console.log(" ✅ Google Sheets (readonly)");
|
|
console.log(" ✅ Google Drive (readonly)\n");
|
|
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
|
|
|
|
console.log("🌐 AUTHENTICATION URL:\n");
|
|
console.log(authUrl);
|
|
console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
|
|
|
|
console.log("📝 STEPS:\n");
|
|
console.log("1. Åbn URL'en ovenfor i din browser");
|
|
console.log("2. Log ind og godkend de nye scopes");
|
|
console.log('3. Du får en "redirect error" - det er OK!');
|
|
console.log("4. Kopier HELE URL'en fra adresselinjen");
|
|
console.log('5. Find "code=" parameteren');
|
|
console.log("6. Kør: node exchange-code.cjs <din-kode>\n");
|
|
|
|
// Try to open browser automatically
|
|
try {
|
|
const openCmd =
|
|
process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
exec(`${openCmd} "${authUrl}"`, (err) => {
|
|
if (err) {
|
|
console.log("⚠️ Could not open browser automatically");
|
|
} else {
|
|
console.log("✅ Browser opened automatically!\n");
|
|
}
|
|
});
|
|
} catch (e) {
|
|
console.log("⚠️ Could not open browser automatically\n");
|
|
}
|
|
|
|
// Create exchange script
|
|
const exchangeScript = `#!/usr/bin/env node
|
|
|
|
const fs = require('fs');
|
|
const https = require('https');
|
|
const { homedir } = require('os');
|
|
const { join } = require('path');
|
|
|
|
function httpsRequest(url, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const req = https.request(url, options, (res) => {
|
|
let data = '';
|
|
res.on('data', (chunk) => (data += chunk));
|
|
res.on('end', () => {
|
|
if (res.statusCode >= 400) {
|
|
reject(new Error(\`HTTP \${res.statusCode}: \${data}\`));
|
|
} else {
|
|
resolve(JSON.parse(data));
|
|
}
|
|
});
|
|
});
|
|
req.on('error', reject);
|
|
if (options.body) req.write(options.body);
|
|
req.end();
|
|
});
|
|
}
|
|
|
|
async function main() {
|
|
const code = process.argv[2];
|
|
|
|
if (!code) {
|
|
console.error('❌ Usage: node exchange-code.cjs <authorization-code>');
|
|
process.exit(1);
|
|
}
|
|
|
|
const credsPath = join(homedir(), '.openclaw/secrets/google-oauth.json');
|
|
const creds = JSON.parse(fs.readFileSync(credsPath, 'utf8'));
|
|
|
|
console.log('🔄 Exchanging authorization code for tokens...\\n');
|
|
|
|
const body = new URLSearchParams({
|
|
client_id: creds.client_id,
|
|
client_secret: creds.client_secret,
|
|
code: code,
|
|
redirect_uri: 'http://localhost:8080',
|
|
grant_type: 'authorization_code',
|
|
}).toString();
|
|
|
|
const data = await httpsRequest('https://oauth2.googleapis.com/token', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
'Content-Length': Buffer.byteLength(body),
|
|
},
|
|
body,
|
|
});
|
|
|
|
console.log('✅ Tokens received!\\n');
|
|
|
|
// Update credentials file
|
|
const newCreds = {
|
|
client_id: creds.client_id,
|
|
client_secret: creds.client_secret,
|
|
refresh_token: data.refresh_token || creds.refresh_token,
|
|
access_token: data.access_token,
|
|
expiry_date: Date.now() + (data.expires_in * 1000),
|
|
};
|
|
|
|
fs.writeFileSync(credsPath, JSON.stringify(newCreds, null, 2));
|
|
|
|
console.log('💾 Updated credentials saved to:');
|
|
console.log(\` \${credsPath}\\n\`);
|
|
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n');
|
|
console.log('🎉 Google OAuth updated successfully!\\n');
|
|
console.log('Du har nu adgang til:');
|
|
console.log(' ✅ Gmail (read + send)');
|
|
console.log(' ✅ Google Sheets (readonly)');
|
|
console.log(' ✅ Google Drive (readonly)\\n');
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error('❌ Error:', err.message);
|
|
process.exit(1);
|
|
});
|
|
`;
|
|
|
|
const exchangePath = join(__dirname, "exchange-code.cjs");
|
|
fs.writeFileSync(exchangePath, exchangeScript);
|
|
fs.chmodSync(exchangePath, 0o755);
|
|
|
|
console.log("✅ Created helper script: exchange-code.cjs\n");
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error("❌ Error:", err.message);
|
|
process.exit(1);
|
|
});
|