@rool-dev/client 0.3.0-dev.54184fd → 0.3.0-dev.f9b91b8

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/auth-node.js DELETED
@@ -1,270 +0,0 @@
1
- import * as http from 'node:http';
2
- import * as fs from 'node:fs';
3
- import * as path from 'node:path';
4
- import * as os from 'node:os';
5
- import open from 'open';
6
- const GCIP_REFRESH_ENDPOINT = 'https://securetoken.googleapis.com/v1/token';
7
- export class NodeAuthProvider {
8
- config;
9
- apiKey = null;
10
- _serverUrl = null;
11
- constructor(config = {}) {
12
- this.config = config;
13
- }
14
- setServerUrl(url) {
15
- this._serverUrl = url;
16
- }
17
- get credentialsPath() {
18
- if (this.config.credentialsPath) {
19
- return this.config.credentialsPath;
20
- }
21
- const homeDir = os.homedir();
22
- const configDir = path.join(homeDir, '.config', 'rool');
23
- return path.join(configDir, 'credentials.json');
24
- }
25
- /**
26
- * Get the base URL for auth endpoints (e.g. https://api.rool.dev/auth).
27
- * Does NOT include trailing slash.
28
- */
29
- get authEndpoint() {
30
- // 1. Use explicit authUrl if provided
31
- if (this.config.authUrl) {
32
- return this.config.authUrl.replace(/\/+$/, '');
33
- }
34
- // 2. Derive from serverUrl
35
- if (!this._serverUrl) {
36
- throw new Error('Auth URL not configured and Server URL not set.');
37
- }
38
- try {
39
- const url = new URL(this._serverUrl);
40
- return `${url.origin}/auth`;
41
- }
42
- catch {
43
- // Fallback for weird inputs
44
- return `${this._serverUrl.replace(/\/rool-server\/?$/, '')}/auth`;
45
- }
46
- }
47
- initialize() {
48
- return this.isAuthenticated();
49
- }
50
- async getToken() {
51
- const creds = this.readCredentials();
52
- if (!creds)
53
- return undefined;
54
- // Refresh if expiring in less than 5 minutes
55
- if (Date.now() >= creds.expires_at - 5 * 60 * 1000) {
56
- return this.refreshToken(creds);
57
- }
58
- return creds.access_token;
59
- }
60
- getUser() {
61
- const creds = this.readCredentials();
62
- if (!creds?.access_token)
63
- return { email: null, name: null };
64
- try {
65
- const payload = JSON.parse(Buffer.from(creds.access_token.split('.')[1], 'base64').toString());
66
- return {
67
- email: payload.email || null,
68
- name: payload.name || null,
69
- };
70
- }
71
- catch {
72
- return { email: null, name: null };
73
- }
74
- }
75
- isAuthenticated() {
76
- const creds = this.readCredentials();
77
- if (!creds)
78
- return false;
79
- // We consider it authenticated if we have a refresh token,
80
- // effectively "remember me" behavior for CLI
81
- return !!creds.refresh_token || Date.now() < creds.expires_at;
82
- }
83
- async login() {
84
- const { server, closeAll } = await this.startLoopbackServer();
85
- const port = server.address().port;
86
- const redirectUri = `http://localhost:${port}`;
87
- // Generate code verifier/state if needed, currently just state
88
- const state = Math.random().toString(36).substring(2);
89
- // Auth endpoint is the root of the auth service
90
- const loginUrl = new URL(`${this.authEndpoint}/`);
91
- loginUrl.searchParams.set('redirect_uri', redirectUri);
92
- loginUrl.searchParams.set('state', state);
93
- console.log('Opening browser to login:', loginUrl.toString());
94
- await open(loginUrl.toString());
95
- const timeoutMs = this.config.loginTimeoutMs ?? 5 * 60 * 1000; // 5 minutes default
96
- return new Promise((resolve, reject) => {
97
- const timeout = setTimeout(() => {
98
- closeAll();
99
- reject(new Error('Login timed out. Please try again.'));
100
- }, timeoutMs);
101
- server.on('authenticated', (tokens) => {
102
- clearTimeout(timeout);
103
- const expiresAt = Date.now() + (tokens.expires_in * 1000);
104
- this.writeCredentials({
105
- access_token: tokens.id_token, // GCIP returns id_token
106
- refresh_token: tokens.refresh_token,
107
- expires_at: expiresAt
108
- });
109
- this.config.onAuthStateChanged?.(true);
110
- closeAll();
111
- resolve();
112
- });
113
- server.on('error', (err) => {
114
- clearTimeout(timeout);
115
- closeAll();
116
- reject(err);
117
- });
118
- });
119
- }
120
- logout() {
121
- const filePath = this.credentialsPath;
122
- if (fs.existsSync(filePath)) {
123
- fs.unlinkSync(filePath);
124
- }
125
- this.config.onAuthStateChanged?.(false);
126
- }
127
- // ===========================================================================
128
- // Private Helpers
129
- // ===========================================================================
130
- readCredentials() {
131
- try {
132
- const filePath = this.credentialsPath;
133
- if (!fs.existsSync(filePath))
134
- return null;
135
- const data = fs.readFileSync(filePath, 'utf-8');
136
- return JSON.parse(data);
137
- }
138
- catch {
139
- return null;
140
- }
141
- }
142
- writeCredentials(creds) {
143
- const filePath = this.credentialsPath;
144
- const dir = path.dirname(filePath);
145
- try {
146
- fs.mkdirSync(dir, { recursive: true });
147
- fs.writeFileSync(filePath, JSON.stringify(creds, null, 2), { mode: 0o600 });
148
- }
149
- catch (error) {
150
- console.error('[RoolClient] Failed to save credentials:', error);
151
- }
152
- }
153
- async getApiKey() {
154
- if (this.apiKey)
155
- return this.apiKey;
156
- try {
157
- const response = await fetch(`${this.authEndpoint}/config.json`);
158
- if (!response.ok)
159
- return null;
160
- const data = await response.json();
161
- this.apiKey = data.apiKey;
162
- return this.apiKey;
163
- }
164
- catch {
165
- return null;
166
- }
167
- }
168
- async refreshToken(creds) {
169
- if (!creds.refresh_token)
170
- return undefined;
171
- const apiKey = await this.getApiKey();
172
- if (!apiKey) {
173
- console.warn('[RoolClient] Cannot refresh: API key not found');
174
- return undefined;
175
- }
176
- try {
177
- const response = await fetch(`${GCIP_REFRESH_ENDPOINT}?key=${apiKey}`, {
178
- method: 'POST',
179
- headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
180
- body: new URLSearchParams({
181
- grant_type: 'refresh_token',
182
- refresh_token: creds.refresh_token,
183
- }),
184
- });
185
- if (!response.ok)
186
- throw new Error('Refresh failed');
187
- const data = await response.json();
188
- const newCreds = {
189
- access_token: data.id_token || data.access_token,
190
- refresh_token: data.refresh_token || creds.refresh_token,
191
- expires_at: Date.now() + (Number(data.expires_in) * 1000),
192
- };
193
- this.writeCredentials(newCreds);
194
- return newCreds.access_token;
195
- }
196
- catch (error) {
197
- console.error('[RoolClient] Refresh failed:', error);
198
- // Don't auto-logout on network error, but if it's a 400 it might be invalid grant
199
- return undefined;
200
- }
201
- }
202
- startLoopbackServer() {
203
- return new Promise((resolve) => {
204
- const server = http.createServer((req, res) => {
205
- const url = new URL(req.url || '/', `http://localhost`);
206
- // 1. Serve the capture page if we just have a root request
207
- if (url.pathname === '/') {
208
- res.writeHead(200, { 'Content-Type': 'text/html' });
209
- res.end(`
210
- <html>
211
- <body>
212
- <h1>Authenticating...</h1>
213
- <script>
214
- // Extract hash and post to /callback
215
- if (window.location.hash) {
216
- const hash = window.location.hash.substring(1);
217
- fetch('/callback', {
218
- method: 'POST',
219
- headers: {'Content-Type': 'application/x-www-form-urlencoded'},
220
- body: hash
221
- })
222
- .then(() => document.body.innerHTML = '<h1>Login Successful. You can close this window.</h1>')
223
- .catch(err => document.body.innerHTML = '<h1>Error: ' + err.message + '</h1>');
224
- }
225
- </script>
226
- </body>
227
- </html>
228
- `);
229
- return;
230
- }
231
- // 2. Handle the callback POST
232
- if (url.pathname === '/callback' && req.method === 'POST') {
233
- let body = '';
234
- req.on('data', (chunk) => body += chunk.toString());
235
- req.on('end', () => {
236
- const params = new URLSearchParams(body);
237
- const idToken = params.get('id_token');
238
- const refreshToken = params.get('refresh_token');
239
- const expiresIn = params.get('expires_in');
240
- if (idToken && expiresIn) {
241
- res.writeHead(200);
242
- res.end('OK');
243
- server.emit('authenticated', {
244
- id_token: idToken,
245
- refresh_token: refreshToken,
246
- expires_in: Number(expiresIn)
247
- });
248
- }
249
- else {
250
- res.writeHead(400);
251
- res.end('Invalid tokens');
252
- }
253
- });
254
- return;
255
- }
256
- res.writeHead(404);
257
- res.end();
258
- });
259
- // Listen on random port
260
- server.listen(0, '127.0.0.1', () => resolve({
261
- server,
262
- closeAll: () => {
263
- server.close();
264
- server.closeAllConnections();
265
- },
266
- }));
267
- });
268
- }
269
- }
270
- //# sourceMappingURL=auth-node.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-node.js","sourceRoot":"","sources":["../src/auth-node.ts"],"names":[],"mappings":"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"}