slek-ai-cli 1.1.6 → 1.1.8

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.
Files changed (4) hide show
  1. package/.env +5 -0
  2. package/auth.js +59 -83
  3. package/cli.js +1 -1
  4. package/package.json +4 -3
package/.env ADDED
@@ -0,0 +1,5 @@
1
+ FIREBASE_PROJECT_ID="charm-f004f"
2
+ FIREBASE_CLIENT_EMAIL="firebase-adminsdk-fbsvc@charm-f004f.iam.gserviceaccount.com"
3
+ FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDPq0be+jDD2xzZ\nHfWTD3QhZK9/vSZAah4hBN6mozeJMkeY4HF7PH8q6e/14AcLK8NtOiYOGDW0fQNX\nR4khT/DBtkEt+BR6CqGS38u+0ahhua9hw5ea8c6+8Zu9elUWHJ1mdYnt96IGf4Tj\nrJcBe5CKxJb8YvHLd1pUvjDcwxzG46qar0shr2yJJo7z8XyQImwtXjqNd7P9FnfE\nIlBZsMGbSnW+tv/ryCoPAaQJW4A/80qDLctUuKp1nSw3Hm8r/jqPmzBEt72beCxX\nPoR4RSKWZ4Pm8yFZgw2xwU41s7loIhHQeFYN1pE5OaIhZLpGedhgEST51MaIM62I\nrhCDS85VAgMBAAECgf829V0MJapCKvq3evZCtRRGwh6v757v7SWMF33VG9zWsjfA\nfaWKt7fv43ld2KwEiNBvV7Q6hq2v1mXL82KXLlDI8zLMt5qzsZyRAikpltK5Cisf\n9GNq3hOY9NgCjR13fJsrQm/+SkrW7Wh92G8eNVVLZDuRD55t+mgthSfpRLmY6K1G\nGNhwtzwJkNHMh5ZgRFhKHwCjR7s14Lt72TIak2jDn9Fdwn5f5oF/7RoQx5Y5D9sD\ngMlWshdmmi40jjsa8Kvepun0dwmnh3CWjEB3E1DoKWjVKbSaYSryrWKA9uXYiOh3\nPZe7T5pv2OfvoORpsWwI/hOb+2yJ4gv/22b5mvECgYEA81BAAbCgqA121JExnuHP\ndoTO5gdzpc6YoHYAp2cyuyEm1yA+CwamoFglSkiwpq/odnNMo/SfOxgkoIurDtn0\n3J7ARFKOK4pHZkTAvL2jqkuvh1dJc5+NC/i3SgQq8t1df/dkZ//LNycAwPZQDNuv\nV44eG68xdrC9pHY+W5NIVhECgYEA2n8+qLXJJcUt6D2Ij6GmMtjdk8gEjMzHvWC4\nICdPsCyNHEsM2e/sJQOiV+UDEjtoDWZgfe/A5vibMMQQbeHr+3ibgMvjsbvrdVWb\nq1cmjDI94D4mOms71QgH0H+QtF2t4iQWiviudIeLqF0EUpMWsvgO9B/oJUEL6WXt\nt3YgIAUCgYEAxEKEDpjpTgTmSBoB23WrgZ8owJVcLG9T34KvjliIrDbWfIouYXhw\n6T+QfLXbf+i+auUf+dQ0qFcWHEXsqeMXRunqjnHE6cv1QcHNcbDKFnBMWrAGuHQH\nMpPhTJvGBPaYF8N2wwiqY4dbbUqBUY3WhppFIPGUxXdU0Rbrv7QykfECgYEAvVTn\nod+sBkufZQ/1BqkHUCY1kroOn0dPiV2HD22hEsL4H900rKDG2qgUg99RUvohRwNA\nd8BKQpqIN7Cdn+nVx5mR/gAvNLLm7EybUNR69Z8PmQGhtJt5RDbqNpRjerd2Vm/5\nDMFCwn012lWHylnkoH5szsPbMHT18nA9le0JF1UCgYEAlJNW/WqqTETu1JciGn3o\nIeG2jbdcUjHpnd8fKVUNm4yRCtwLsHRQar0/DI1FNUAqpi/wEU9CB5YVjyyTKWQX\nOyidG32VtkB6yTmlLKxnxY2+VxL4Vfk6ka9K/6tcLfFpy+LYgAzEbeRR32kz6upu\nLudPjkoiArV7RQZE/G7ySH4=\n-----END PRIVATE KEY-----\n"
4
+ FIREBASE_API_KEY="AIzaSyBoQHn_adTTj1ZaYZBMHCMSAblCGCIbQG4"
5
+ FIREBASE_AUTH_DOMAIN="charm-f004f.firebaseapp.com"
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 / Google config (hardcoded — safe for CLI tools) ────────────────
14
- // FIREBASE_API_KEY and GOOGLE_CLIENT_ID are public-safe values.
15
- // We use Firebase's signInWithIdp flow, so GOOGLE_CLIENT_SECRET is NOT needed.
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
- // ─── Exchange Google auth code → Firebase ID token ────────────────────────────
87
- // Uses Firebase's signInWithIdp endpoint — no CLIENT_SECRET required.
88
- async function exchangeCodeForToken(code) {
89
- // Step 1: Exchange code for Google ID token using Google's token endpoint.
90
- // We use PKCE / implicit flow via Firebase — client secret not needed here.
91
- // Instead, we use Firebase's direct Google OAuth token exchange.
92
- const tokenRes = await axios.post(
93
- 'https://oauth2.googleapis.com/token',
94
- new URLSearchParams({
95
- code,
96
- client_id: GOOGLE_CLIENT_ID,
97
- redirect_uri: REDIRECT_URI,
98
- grant_type: 'authorization_code',
99
- }),
100
- { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
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
- const { id_token } = tokenRes.data;
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=${id_token}&providerId=google.com`,
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
- // Validate config is filled in
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: #0a0a0a;
174
- color: #fff;
175
- font-family: monospace;
176
- display: flex;
177
- align-items: center;
178
- justify-content: center;
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 exchangeCodeForToken(code);
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 login after 2 minutes
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/cli.js CHANGED
@@ -308,7 +308,7 @@ async function processInput(input, rl) {
308
308
  }
309
309
 
310
310
  const spinner = ora({
311
- text: chalk.cyan(' Connecting to NVIDIA API...'),
311
+ text: chalk.cyan(' Connecting to SLEK Server...'),
312
312
  spinner: 'dots',
313
313
  color: 'cyan',
314
314
  prefixText: ' ',
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "slek-ai-cli",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "SLEK AI CLI — Powered by NVIDIA API",
5
5
  "main": "cli.js",
6
6
  "bin": {
7
- "slek": "cli.js"
7
+ "slek": "./cli.js"
8
8
  },
9
9
  "scripts": {
10
10
  "start": "node cli.js"
@@ -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
  }