PrintToVeraeTimeStamp/cmd/verae-print/stampcore.go
Grok Bot (for George) 13ebc351f5 0.3.2: Save As filename prompt per print (Windows + macOS)
- promptForFilename setting (default true; env VERAE_PROMPT_FOR_FILENAME),
  'verae-print config --prompt-for-filename', last Save As folder in
  ~/.verae/state.json
- Windows helper: common file dialog (PDF filter, overwrite prompt, topmost
  owner) before stamping; macOS printer path: choose file name (NSSavePanel)
  via 'stamp -prompt-name -title'; cancel discards the job (no stamp/credit)
- job.Options.OutPath: original saved at the chosen path, certificate and
  .verae.json next to it with the chosen base name (never overwritten)
- held jobs keep the chosen path (pendingMeta.OutPath)
- installer: 'Ask for a file name for each print' checkbox; removed the
  'Open the user guide' finish-page checkbox; mac-key-setup asks too
- auth test no longer touches the real macOS keychain (VERAE_SKIP_KEYCHAIN)
- version 0.3.2
2026-10-03 20:00:56 -04:00

61 lines
2.1 KiB
Go

package main
import (
"fmt"
"time"
"github.com/VeraeLLC/PrintToVeraeTimeStamp/internal/auth"
"github.com/VeraeLLC/PrintToVeraeTimeStamp/internal/job"
"github.com/VeraeLLC/PrintToVeraeTimeStamp/internal/veraeapi"
"github.com/VeraeLLC/PrintToVeraeTimeStamp/internal/vlog"
)
// clientForChannel builds an API client from the stored credentials.
// Missing xVerae- key (and no JWT fallback) → errNoKey.
func clientForChannel(ch auth.Channel, lj vlog.Job) (*veraeapi.Client, auth.Channel, error) {
client := &veraeapi.Client{Channel: ch}
switch ch {
case auth.ChannelZapier:
tok, err := auth.LoadXVeraeToken()
if err != nil {
if jwt, jerr := auth.LoadVeraeJWT(); jerr == nil {
lj.Printf("auth: no xVerae- token, using verae channel (auth.properties)")
client.Channel, client.VeraeToken = auth.ChannelVerae, jwt
return client, auth.ChannelVerae, nil
}
return nil, ch, fmt.Errorf("%w (%v)", errNoKey, err)
}
client.XVeraeToken = tok
default:
tok, err := auth.LoadVeraeJWT()
if err != nil {
return nil, ch, fmt.Errorf("verae channel: %v", err)
}
client.VeraeToken = tok
}
return client, ch, nil
}
// stampFile stamps one PDF with the current key (no holding / prompting).
func stampFile(pdf string, t stampTarget, lj vlog.Job) (job.Result, error) {
client, ch, err := clientForChannel(auth.PreferredChannel(), lj)
if err != nil {
return job.Result{}, err
}
client.HTTPDo = loggingDo(lj)
start := time.Now()
res, err := job.Run(job.Options{SourcePDF: pdf, OutDir: t.OutDir, OutPath: t.OutPath, DocumentName: safeStem(t.Title) + ".pdf", Channel: ch, Client: client})
if err != nil {
return res, err
}
lj.Printf("stamp: OK in %s receipt=%s sha256=%s\n original=%q\n cert=%q\n json=%q",
time.Since(start).Round(time.Millisecond), res.ReceiptID, res.SHA256, res.OriginalPDF, res.CertificatePDF, res.ReceiptJSON)
return res, nil
}
func authReason(err error) string {
if veraeapi.IsAuthError(err) {
return "Verae did not accept your signing key (it may have expired or been revoked). Please sign in again."
}
return "No Verae signing key is set up for this user yet. Please sign in or create an account."
}