-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathoauth-setup.js
More file actions
165 lines (140 loc) · 5.06 KB
/
Copy pathoauth-setup.js
File metadata and controls
165 lines (140 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
const { google } = require('googleapis');
const http = require('http');
const url = require('url');
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const OAUTH_CREDENTIALS_PATH = path.join(__dirname, 'oauth-credentials.json');
const TOKEN_PATH = path.join(__dirname, 'oauth-token.json');
const SCOPES = [
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive',
];
/**
* Get OAuth2 client - either from saved token or by prompting user
*/
async function getOAuthClient() {
// Check for OAuth credentials
if (!fs.existsSync(OAUTH_CREDENTIALS_PATH)) {
console.log('\n❌ OAuth credentials not found!\n');
console.log('Please create OAuth 2.0 credentials:');
console.log('1. Go to: https://console.cloud.google.com/apis/credentials?project=pizzadao-scripts');
console.log('2. Click "Create Credentials" → "OAuth client ID"');
console.log('3. Select "Desktop app" as application type');
console.log('4. Name it "PizzaDAO CLI"');
console.log('5. Download the JSON and save it as:');
console.log(` ${OAUTH_CREDENTIALS_PATH}\n`);
process.exit(1);
}
const credentials = JSON.parse(fs.readFileSync(OAUTH_CREDENTIALS_PATH, 'utf8'));
const { client_id, client_secret } = credentials.installed || credentials.web;
const oauth2Client = new google.auth.OAuth2(
client_id,
client_secret,
'http://localhost:3939/oauth2callback'
);
// Check for saved token
if (fs.existsSync(TOKEN_PATH)) {
const token = JSON.parse(fs.readFileSync(TOKEN_PATH, 'utf8'));
oauth2Client.setCredentials(token);
// Check if token is expired
if (token.expiry_date && token.expiry_date < Date.now()) {
console.log('Token expired, refreshing...');
const { credentials: newCreds } = await oauth2Client.refreshAccessToken();
oauth2Client.setCredentials(newCreds);
fs.writeFileSync(TOKEN_PATH, JSON.stringify(newCreds, null, 2));
console.log('Token refreshed and saved.\n');
} else {
console.log('Using saved OAuth token.\n');
}
return oauth2Client;
}
// Need to authenticate
console.log('No saved token found. Starting OAuth flow...\n');
return await authenticateUser(oauth2Client);
}
/**
* Start OAuth flow and get user consent
*/
async function authenticateUser(oauth2Client) {
return new Promise((resolve, reject) => {
const authUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
prompt: 'consent',
});
console.log('Opening browser for authentication...');
console.log('If browser doesn\'t open, visit this URL:\n');
console.log(authUrl + '\n');
// Create local server to receive callback
const server = http.createServer(async (req, res) => {
try {
const queryParams = url.parse(req.url, true).query;
if (queryParams.code) {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<html><body><h1>✅ Authentication successful!</h1><p>You can close this window.</p></body></html>');
server.close();
// Exchange code for tokens
const { tokens } = await oauth2Client.getToken(queryParams.code);
oauth2Client.setCredentials(tokens);
// Save token
fs.writeFileSync(TOKEN_PATH, JSON.stringify(tokens, null, 2));
console.log('\n✅ Authentication successful! Token saved.\n');
resolve(oauth2Client);
}
} catch (error) {
res.writeHead(500);
res.end('Authentication failed');
reject(error);
}
});
server.listen(3939, () => {
// Open browser (Windows)
exec(`start "" "${authUrl}"`, (err) => {
if (err) console.log('Could not open browser automatically.');
});
});
});
}
/**
* Get authenticated Drive API
*/
async function getOAuthDriveApi() {
const auth = await getOAuthClient();
return google.drive({ version: 'v3', auth });
}
/**
* Get authenticated Sheets API
*/
async function getOAuthSheetsApi() {
const auth = await getOAuthClient();
return google.sheets({ version: 'v4', auth });
}
// Export for use in other scripts
module.exports = {
getOAuthClient,
getOAuthDriveApi,
getOAuthSheetsApi,
TOKEN_PATH,
OAUTH_CREDENTIALS_PATH,
};
// If run directly, test the authentication
if (require.main === module) {
(async () => {
try {
const auth = await getOAuthClient();
const drive = google.drive({ version: 'v3', auth });
const about = await drive.about.get({ fields: 'user,storageQuota' });
console.log('Authenticated as:', about.data.user.emailAddress);
const quota = about.data.storageQuota;
if (quota && quota.limit) {
const usedGB = (parseInt(quota.usage) / 1024 / 1024 / 1024).toFixed(2);
const limitGB = (parseInt(quota.limit) / 1024 / 1024 / 1024).toFixed(2);
console.log(`Storage: ${usedGB} GB / ${limitGB} GB`);
}
console.log('\n✅ OAuth setup complete! You can now run copy-sheet-oauth.js');
} catch (error) {
console.error('Error:', error.message);
}
})();
}