slek-ai-cli 1.1.6 → 1.1.7
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/auth.js +59 -83
- package/package.json +3 -2
package/auth.js
CHANGED
|
@@ -10,22 +10,9 @@ const axios = require('axios');
|
|
|
10
10
|
const chalk = require('chalk');
|
|
11
11
|
const boxen = require('boxen');
|
|
12
12
|
|
|
13
|
-
// ─── Firebase
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const FIREBASE_API_KEY = 'AIzaSyBoQHn_adTTj1ZaYZBMHCMSAblCGCIbQG4';
|
|
17
|
-
const GOOGLE_CLIENT_ID = 'YOUR_GOOGLE_CLIENT_ID'; // e.g. 123456.apps.googleusercontent.com
|
|
18
|
-
|
|
19
|
-
// Additional Firebase config (for future SDK use if needed)
|
|
20
|
-
const FIREBASE_CONFIG = {
|
|
21
|
-
apiKey: 'AIzaSyBoQHn_adTTj1ZaYZBMHCMSAblCGCIbQG4',
|
|
22
|
-
authDomain: 'charm-f004f.firebaseapp.com',
|
|
23
|
-
projectId: 'charm-f004f',
|
|
24
|
-
storageBucket: 'charm-f004f.firebasestorage.app',
|
|
25
|
-
messagingSenderId: '763614479011',
|
|
26
|
-
appId: '1:763614479011:web:5cd0082b14b78b9c5eb516',
|
|
27
|
-
measurementId: 'G-0G0F5DT6PC',
|
|
28
|
-
};
|
|
13
|
+
// ─── Firebase config (hardcoded — all values from Firebase Console) ───────────
|
|
14
|
+
const FIREBASE_API_KEY = 'AIzaSyBoQHn_adTTj1ZaYZBMHCMSAblCGCIbQG4';
|
|
15
|
+
const FIREBASE_AUTH_DOMAIN = 'charm-f004f.firebaseapp.com';
|
|
29
16
|
|
|
30
17
|
const REDIRECT_URI = 'http://localhost:9876/callback';
|
|
31
18
|
const AUTH_PORT = 9876;
|
|
@@ -65,7 +52,7 @@ function getUser() {
|
|
|
65
52
|
return loadToken();
|
|
66
53
|
}
|
|
67
54
|
|
|
68
|
-
// ─── Open browser cross-platform
|
|
55
|
+
// ─── Open browser cross-platform ─────────────────────────────────────────────
|
|
69
56
|
function openBrowser(targetUrl) {
|
|
70
57
|
try {
|
|
71
58
|
const platform = process.platform;
|
|
@@ -83,73 +70,72 @@ function openBrowser(targetUrl) {
|
|
|
83
70
|
}
|
|
84
71
|
}
|
|
85
72
|
|
|
86
|
-
// ───
|
|
87
|
-
// Uses Firebase's
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
);
|
|
73
|
+
// ─── Firebase Google Sign-In URL ──────────────────────────────────────────────
|
|
74
|
+
// Uses Firebase's own OAuth redirect — no separate Google Client ID needed.
|
|
75
|
+
function buildFirebaseAuthUrl() {
|
|
76
|
+
const base = `https://${FIREBASE_AUTH_DOMAIN}/__/auth/handler`;
|
|
77
|
+
const params = new URLSearchParams({
|
|
78
|
+
apiKey: FIREBASE_API_KEY,
|
|
79
|
+
appName: '[DEFAULT]',
|
|
80
|
+
authType: 'signInViaRedirect',
|
|
81
|
+
redirectUrl: REDIRECT_URI,
|
|
82
|
+
providerId: 'google.com',
|
|
83
|
+
scopes: 'profile,email',
|
|
84
|
+
v: '10',
|
|
85
|
+
});
|
|
86
|
+
return `${base}?${params.toString()}`;
|
|
87
|
+
}
|
|
102
88
|
|
|
103
|
-
|
|
89
|
+
// ─── Exchange Firebase redirect token ────────────────────────────────────────
|
|
90
|
+
// After Firebase redirect, we get an id_token in the callback URL fragment/query.
|
|
91
|
+
async function handleFirebaseCallback(queryParams) {
|
|
92
|
+
// Firebase returns id_token directly in the callback
|
|
93
|
+
const idToken = queryParams.id_token || queryParams.idToken;
|
|
94
|
+
|
|
95
|
+
if (idToken) {
|
|
96
|
+
// Verify and get user info from Firebase
|
|
97
|
+
const res = await axios.post(
|
|
98
|
+
`https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=${FIREBASE_API_KEY}`,
|
|
99
|
+
{ idToken }
|
|
100
|
+
);
|
|
101
|
+
const user = res.data.users?.[0];
|
|
102
|
+
if (!user) throw new Error('User not found');
|
|
103
|
+
return {
|
|
104
|
+
name: user.displayName || user.email,
|
|
105
|
+
email: user.email,
|
|
106
|
+
photo: user.photoUrl || '',
|
|
107
|
+
idToken,
|
|
108
|
+
expiresAt: Date.now() + 3600 * 1000, // 1 hour
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Fallback: if Firebase sends an auth code instead
|
|
113
|
+
const code = queryParams.code;
|
|
114
|
+
if (!code) throw new Error('No token or code received from Firebase');
|
|
104
115
|
|
|
105
|
-
// Step 2: Sign in to Firebase using the Google ID token.
|
|
106
116
|
const firebaseRes = await axios.post(
|
|
107
117
|
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithIdp?key=${FIREBASE_API_KEY}`,
|
|
108
118
|
{
|
|
109
|
-
postBody: `id_token=${
|
|
119
|
+
postBody: `id_token=${code}&providerId=google.com`,
|
|
110
120
|
requestUri: REDIRECT_URI,
|
|
111
121
|
returnIdpCredential: true,
|
|
112
122
|
returnSecureToken: true,
|
|
113
123
|
}
|
|
114
124
|
);
|
|
115
125
|
|
|
116
|
-
const { displayName, email, idToken, expiresIn, photoUrl } = firebaseRes.data;
|
|
117
|
-
|
|
126
|
+
const { displayName, email, idToken: token, expiresIn, photoUrl } = firebaseRes.data;
|
|
118
127
|
return {
|
|
119
128
|
name: displayName,
|
|
120
129
|
email,
|
|
121
|
-
photo: photoUrl,
|
|
122
|
-
idToken,
|
|
130
|
+
photo: photoUrl || '',
|
|
131
|
+
idToken: token,
|
|
123
132
|
expiresAt: Date.now() + parseInt(expiresIn) * 1000,
|
|
124
133
|
};
|
|
125
134
|
}
|
|
126
135
|
|
|
127
136
|
// ─── Login ────────────────────────────────────────────────────────────────────
|
|
128
137
|
async function login() {
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
!GOOGLE_CLIENT_ID || GOOGLE_CLIENT_ID === 'YOUR_GOOGLE_CLIENT_ID'
|
|
132
|
-
) {
|
|
133
|
-
console.log(
|
|
134
|
-
boxen(
|
|
135
|
-
chalk.red('✗ Google Client ID not set!\n\n') +
|
|
136
|
-
chalk.white('Open ') + chalk.yellow('auth.js') + chalk.white(' and replace:\n\n') +
|
|
137
|
-
chalk.cyan('YOUR_GOOGLE_CLIENT_ID') +
|
|
138
|
-
chalk.white('\n\nwith your OAuth Client ID from Google Cloud Console.'),
|
|
139
|
-
{ padding: 1, margin: { left: 2 }, borderStyle: 'round', borderColor: 'red' }
|
|
140
|
-
)
|
|
141
|
-
);
|
|
142
|
-
process.exit(1);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Build Google OAuth URL
|
|
146
|
-
const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth');
|
|
147
|
-
authUrl.searchParams.set('client_id', GOOGLE_CLIENT_ID);
|
|
148
|
-
authUrl.searchParams.set('redirect_uri', REDIRECT_URI);
|
|
149
|
-
authUrl.searchParams.set('response_type', 'code');
|
|
150
|
-
authUrl.searchParams.set('scope', 'openid email profile');
|
|
151
|
-
authUrl.searchParams.set('access_type', 'offline');
|
|
152
|
-
authUrl.searchParams.set('prompt', 'select_account');
|
|
138
|
+
const authUrl = buildFirebaseAuthUrl();
|
|
153
139
|
|
|
154
140
|
return new Promise((resolve, reject) => {
|
|
155
141
|
const server = http.createServer(async (req, res) => {
|
|
@@ -162,26 +148,17 @@ async function login() {
|
|
|
162
148
|
return;
|
|
163
149
|
}
|
|
164
150
|
|
|
165
|
-
const code = parsed.query.code;
|
|
166
|
-
const error = parsed.query.error;
|
|
167
|
-
|
|
168
151
|
// Send success page to browser immediately
|
|
169
152
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
170
153
|
res.end(`
|
|
171
154
|
<html>
|
|
172
155
|
<body style="
|
|
173
|
-
background
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
height: 100vh;
|
|
180
|
-
margin: 0;
|
|
181
|
-
">
|
|
182
|
-
<div style="text-align: center;">
|
|
183
|
-
<h1 style="color: #76b900;">✓ Login Successful!</h1>
|
|
184
|
-
<p style="color: #aaa;">You can close this tab and return to the terminal.</p>
|
|
156
|
+
background:#0a0a0a;color:#fff;font-family:monospace;
|
|
157
|
+
display:flex;align-items:center;justify-content:center;
|
|
158
|
+
height:100vh;margin:0;">
|
|
159
|
+
<div style="text-align:center;">
|
|
160
|
+
<h1 style="color:#76b900;">✓ Login Successful!</h1>
|
|
161
|
+
<p style="color:#aaa;">You can close this tab and return to the terminal.</p>
|
|
185
162
|
</div>
|
|
186
163
|
</body>
|
|
187
164
|
</html>
|
|
@@ -189,6 +166,7 @@ async function login() {
|
|
|
189
166
|
|
|
190
167
|
server.close();
|
|
191
168
|
|
|
169
|
+
const error = parsed.query.error;
|
|
192
170
|
if (error) {
|
|
193
171
|
console.log(chalk.red('\n ✗ Login cancelled.\n'));
|
|
194
172
|
reject(new Error(error));
|
|
@@ -197,7 +175,7 @@ async function login() {
|
|
|
197
175
|
|
|
198
176
|
try {
|
|
199
177
|
process.stdout.write(chalk.cyan('\n ⏳ Verifying with Firebase...\n'));
|
|
200
|
-
const userData = await
|
|
178
|
+
const userData = await handleFirebaseCallback(parsed.query);
|
|
201
179
|
saveToken(userData);
|
|
202
180
|
|
|
203
181
|
console.log(
|
|
@@ -235,12 +213,10 @@ async function login() {
|
|
|
235
213
|
{ padding: 1, margin: { left: 2 }, borderStyle: 'double', borderColor: 'green' }
|
|
236
214
|
)
|
|
237
215
|
);
|
|
238
|
-
|
|
239
|
-
// Small delay to ensure server is ready before opening browser
|
|
240
216
|
setTimeout(() => openBrowser(authUrl.toString()), 500);
|
|
241
217
|
});
|
|
242
218
|
|
|
243
|
-
// Auto-cancel
|
|
219
|
+
// Auto-cancel after 2 minutes
|
|
244
220
|
setTimeout(() => {
|
|
245
221
|
server.close();
|
|
246
222
|
console.log(chalk.red('\n ✗ Login timed out (2 min). Please try again.\n'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slek-ai-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "SLEK AI CLI — Powered by NVIDIA API",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"figlet": "^1.7.0",
|
|
18
18
|
"gradient-string": "^2.0.2",
|
|
19
19
|
"open": "^8.4.2",
|
|
20
|
-
"ora": "^5.4.1"
|
|
20
|
+
"ora": "^5.4.1",
|
|
21
|
+
"slek-ai-cli": "^1.1.6"
|
|
21
22
|
}
|
|
22
23
|
}
|