@livedesk/client 0.1.4 → 0.1.5

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/README.md CHANGED
@@ -16,6 +16,15 @@ On the manager computer, open the LiveDesk dashboard and sign in first. The
16
16
  dashboard keeps its local hub address and private pair token refreshed in the
17
17
  LiveDesk Supabase registry for the signed-in account.
18
18
 
19
+ Supabase Auth must allow the CLI callback URL:
20
+
21
+ ```text
22
+ http://127.0.0.1:5198/callback
23
+ ```
24
+
25
+ If you use a custom port, run `npx @livedesk/client --auth-port 5200` and add
26
+ the matching callback URL to Supabase Auth redirect URLs.
27
+
19
28
  For manual LAN fallback, start `@livedesk/hub` with an externally reachable
20
29
  RemoteHub host and pass the address/token explicitly:
21
30
 
@@ -43,5 +52,6 @@ npx @livedesk/client --no-thumbnail
43
52
  npx @livedesk/client --no-live
44
53
  npx @livedesk/client --engine node
45
54
  npx @livedesk/client --engine fast --trace-frames
55
+ npx @livedesk/client --auth-port 5200
46
56
  npx @livedesk/client --logout
47
57
  ```
@@ -13,6 +13,8 @@ const packageRoot = resolve(__dirname, '..');
13
13
  const nodeAgentPath = join(__dirname, 'livedesk-client-node.js');
14
14
  const FAST_PREFLIGHT_TIMEOUT_MS = 5000;
15
15
  const DEFAULT_MANAGER = '127.0.0.1:5197';
16
+ const DEFAULT_AUTH_CALLBACK_HOST = '127.0.0.1';
17
+ const DEFAULT_AUTH_CALLBACK_PORT = 5198;
16
18
  const SUPABASE_URL = process.env.LIVEDESK_SUPABASE_URL || 'https://otbyfkjxrkngvjziawki.supabase.co';
17
19
  const SUPABASE_PUBLISHABLE_KEY = process.env.LIVEDESK_SUPABASE_PUBLISHABLE_KEY || 'sb_publishable_NpUs0RDJH2YnllsqTKO6TQ_1jTdSsNQ';
18
20
  const CLIENT_STATE_DIR = join(os.homedir(), '.livedesk-client');
@@ -47,6 +49,7 @@ Options:
47
49
  --no-tasks Disable remote task dispatch capability.
48
50
  --login Sign in with Google and auto-discover manager.
49
51
  --logout Forget saved Google session before connecting.
52
+ --auth-port <port> Google sign-in callback port. Default: 5198.
50
53
  --version Show the agent version.
51
54
  --help Show this help.
52
55
 
@@ -80,6 +83,7 @@ function parseLauncherArgs(argv) {
80
83
  let manager = process.env.LIVEDESK_CLIENT_MANAGER || process.env.MINDEXEC_REMOTE_MANAGER || '';
81
84
  let pair = process.env.LIVEDESK_CLIENT_PAIR_TOKEN || process.env.MINDEXEC_REMOTE_PAIR_TOKEN || '';
82
85
  let slot = process.env.LIVEDESK_CLIENT_SLOT || process.env.MINDEXEC_REMOTE_SLOT || '';
86
+ let authPort = normalizePort(process.env.LIVEDESK_CLIENT_AUTH_PORT) || DEFAULT_AUTH_CALLBACK_PORT;
83
87
  let command = 'connect';
84
88
  let nodeOnlyFeature = false;
85
89
  let fakeThumbnail = false;
@@ -129,6 +133,11 @@ function parseLauncherArgs(argv) {
129
133
  logout = true;
130
134
  continue;
131
135
  }
136
+ if (arg === '--auth-port') {
137
+ authPort = normalizePort(argv[index + 1]) || authPort;
138
+ index += 1;
139
+ continue;
140
+ }
132
141
  if (arg === '--manager') {
133
142
  manager = argv[index + 1] || manager;
134
143
  forwarded.push(arg, argv[index + 1]);
@@ -178,11 +187,20 @@ function parseLauncherArgs(argv) {
178
187
  manager,
179
188
  pair,
180
189
  slot,
190
+ authPort,
181
191
  nodeOnlyFeature,
182
192
  fakeThumbnail
183
193
  };
184
194
  }
185
195
 
196
+ function normalizePort(value) {
197
+ const port = Number(String(value || '').trim());
198
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
199
+ return 0;
200
+ }
201
+ return port;
202
+ }
203
+
186
204
  function normalizeSlotNumber(value) {
187
205
  const number = Number(String(value || '').trim());
188
206
  if (!Number.isInteger(number) || number < 1 || number > 999) {
@@ -260,7 +278,9 @@ function openBrowser(url) {
260
278
  spawn(command, [url], { detached: true, stdio: 'ignore' }).unref();
261
279
  }
262
280
 
263
- async function startOAuthCallbackServer() {
281
+ async function startOAuthCallbackServer(options = {}) {
282
+ const host = String(process.env.LIVEDESK_CLIENT_AUTH_HOST || DEFAULT_AUTH_CALLBACK_HOST).trim() || DEFAULT_AUTH_CALLBACK_HOST;
283
+ const port = normalizePort(options.authPort) || DEFAULT_AUTH_CALLBACK_PORT;
264
284
  let settleCode;
265
285
  let rejectCode;
266
286
  const waitForCode = new Promise((resolve, reject) => {
@@ -288,25 +308,32 @@ async function startOAuthCallbackServer() {
288
308
  settleCode(code);
289
309
  server.close();
290
310
  });
291
- await new Promise((resolve, reject) => {
292
- server.once('error', reject);
293
- server.listen(0, '127.0.0.1', resolve);
294
- });
311
+ try {
312
+ await new Promise((resolve, reject) => {
313
+ server.once('error', reject);
314
+ server.listen(port, host, resolve);
315
+ });
316
+ } catch (err) {
317
+ if (err?.code === 'EADDRINUSE') {
318
+ throw new Error(`LiveDesk Google sign-in callback port ${port} is already in use. Close the app using it or run with --auth-port <port> and add that callback URL in Supabase Auth redirect URLs.`);
319
+ }
320
+ throw err;
321
+ }
295
322
  return {
296
323
  get redirectTo() {
297
- return `http://127.0.0.1:${server.address().port}/callback`;
324
+ return `http://${host}:${server.address().port}/callback`;
298
325
  },
299
326
  waitForCode
300
327
  };
301
328
  }
302
329
 
303
- async function signInWithGoogle(supabase) {
330
+ async function signInWithGoogle(supabase, options = {}) {
304
331
  const { data: existing } = await supabase.auth.getSession();
305
332
  if (existing?.session?.access_token) {
306
333
  return existing.session;
307
334
  }
308
335
 
309
- const callback = await startOAuthCallbackServer();
336
+ const callback = await startOAuthCallbackServer({ authPort: options.authPort });
310
337
  const { data, error } = await supabase.auth.signInWithOAuth({
311
338
  provider: 'google',
312
339
  options: {
@@ -428,7 +455,7 @@ async function prepareLoginConnection(parsed) {
428
455
 
429
456
  if (shouldLogin) {
430
457
  const supabase = await createSupabaseClient();
431
- const session = await signInWithGoogle(supabase);
458
+ const session = await signInWithGoogle(supabase, { authPort: parsed.authPort });
432
459
  const email = session.user?.email ? ` as ${session.user.email}` : '';
433
460
  console.log(`Signed in to LiveDesk${email}.`);
434
461
  const resolved = await resolveManagerFromSupabase(supabase);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/client",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "LiveDesk local remote client",
5
5
  "type": "module",
6
6
  "bin": {