@localauth/cli 0.4.0 → 0.4.1

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/cli/ask.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'node:child_process'
2
2
  import * as fs from 'node:fs/promises'
3
3
  import * as path from 'node:path'
4
- import { answerFields, isAskRequest, isFieldName, isReservedName } from '../shared/ask.ts'
4
+ import { answerFields, isAskRequest, isFieldName, isReservedName, MAX_APPROVAL_DESCRIPTION } from '../shared/ask.ts'
5
5
  import { setTimeout as sleep } from 'node:timers/promises'
6
6
  import type { AnswerData, AskRequest, RunData } from '../shared/protocol.ts'
7
7
  import { isAnswer } from '../shared/validation.ts'
@@ -184,7 +184,7 @@ export async function approve(connection: Connection, options: ApproveOptions, s
184
184
  let expiresAt = Date.now() + Math.ceil(options.timeout * 60_000)
185
185
  let request: AskRequest = { title: options.title, description: options.description, fields: [{ name: 'APPROVE', label: 'Approve', secret: false, required: true }] }
186
186
  let data: RunData = { authenticatedMessages: true, kind: 'ask', approval: true, title: options.title, ask: request, expiresAt, command: '', flows: [], output: '', exitCode: null, attempt: 1, retryUntil: null }
187
- if (!isAskRequest(data.ask)) throw new Error('Invalid approval request.')
187
+ if (!isAskRequest(data.ask, MAX_APPROVAL_DESCRIPTION)) throw new Error('Invalid approval request.')
188
188
  let run = await createRun(connection, [], say, { retry: false, link: false }, data)
189
189
  let stop = new AbortController(), interrupted = 0
190
190
  let listeners = Object.entries({ SIGINT: 130, SIGTERM: 143, SIGHUP: 129 }).map(([signal, code]) => {
package/cli/cli.ts CHANGED
@@ -35,6 +35,7 @@ Usage:
35
35
  localauth approve --title <text> [--description <text>] [--timeout <minutes>]
36
36
  Wait for the owner to allow something. They answer from their
37
37
  signed-in list with a fresh passkey check; no link is made
38
+ Description: max 8000
38
39
  Needs end-to-end encryption; exits 0 if approved, 1 otherwise
39
40
  localauth finish [<callback-url>] Hand a pasted http://localhost:... address to the waiting command
40
41
  (reads it from stdin when omitted, keeping it out of ps)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@localauth/cli",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Finish CLI logins on a headless server from your phone, with optional passkey-based end-to-end encryption",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/shared/ask.ts CHANGED
@@ -10,10 +10,12 @@ export function isFieldName(name: unknown): name is string {
10
10
  function object(value: unknown): value is Record<string, unknown> {
11
11
  return value !== null && typeof value === 'object' && !Array.isArray(value)
12
12
  }
13
- export function isAskRequest(value: unknown): value is AskRequest {
13
+ /** An approval may have to show everything being approved, such as a whole diff. */
14
+ export const MAX_APPROVAL_DESCRIPTION = 8000
15
+ export function isAskRequest(value: unknown, maxDescription = 2000): value is AskRequest {
14
16
  if (!object(value)
15
17
  || (value.title !== undefined && (typeof value.title !== 'string' || !value.title.length || value.title.length > 120))
16
- || (value.description !== undefined && (typeof value.description !== 'string' || value.description.length > 2000))
18
+ || (value.description !== undefined && (typeof value.description !== 'string' || value.description.length > maxDescription))
17
19
  || !Array.isArray(value.fields) || value.fields.length < 1 || value.fields.length > 10) return false
18
20
  let names = new Set<string>()
19
21
  return value.fields.every(field => {
@@ -1,5 +1,5 @@
1
1
  import type { InputData, CallbackData, RunData } from './protocol.ts'
2
- import { isAskRequest } from './ask.ts'
2
+ import { isAskRequest, MAX_APPROVAL_DESCRIPTION } from './ask.ts'
3
3
  export { isAnswer } from './ask.ts'
4
4
  export function isCallback(value: unknown): value is CallbackData {
5
5
  let v = value as CallbackData | null
@@ -13,7 +13,7 @@ export function isRunData(value: unknown): value is RunData {
13
13
  && (v.approval === undefined || (v.approval === true && v.kind === 'ask'))
14
14
  && (v.inputEnabled === undefined || typeof v.inputEnabled === 'boolean')
15
15
  && (v.secret === undefined || typeof v.secret === 'boolean')
16
- && (v.ask === undefined || (v.kind === 'ask' && isAskRequest(v.ask)))
16
+ && (v.ask === undefined || (v.kind === 'ask' && isAskRequest(v.ask, v.approval ? MAX_APPROVAL_DESCRIPTION : undefined)))
17
17
  && (v.answerNote === undefined || (typeof v.answerNote === 'string' && v.answerNote.length <= 240))
18
18
  && (v.expiresAt === undefined || (Number.isSafeInteger(v.expiresAt) && v.expiresAt >= 0))
19
19
  && (v.machineName === undefined || (typeof v.machineName === 'string' && v.machineName.length <= 253))