fa7ea191be
- File: native Save As dialog via Bridge.saveFile (replaces WebView2
browser download popup) for encrypted JSON + CSV exports.
- Auto-backup: silent periodic encrypted JSON to a chosen folder,
user-set interval + retention, separate DPAPI-stored password, runs
5s after unlock if due. New file/* bridge cmds (folder/pick,
file/write, file/listMatch, file/delete).
- Folders: per-folder color + icon (8-swatch palette, 8 icon presets),
drag-reorder via HTML5 DnD with insert-line indicators, edit pencil
on hover. New POST /folders/reorder + PUT /folders/{name}. Folder
chip on cards inherits custom icon + color.
- Recently used: vault_entries.accessed_at + POST /entries/{id}/touch
(debounced 2s), sidebar Tools entry showing top-10 by accessed_at.
- Encrypted attachments: per-entry file storage (5MB cap), AES-GCM
with vault key, native Save As download, paperclip upload in
slideover. New entry_attachments table + PM.Handler.Attachments.
- Password expiry: vault_entries.password_changed_at (conditional bump
via SQL CASE only when ciphertext differs), passwordExpiryDays
setting, "Aged" badge on cards + matching Filters chip.
- Recovery: Print button on generated code modal (A4 printable sheet
via @media print, code in 32px monospace + instructions).
- Audit log viewer (sidebar Tools, GET /audit with pagination cursor).
- Plaintext CSV export + Filters dropdown with 9 predicates.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
48 lines
1.8 KiB
ObjectPascal
48 lines
1.8 KiB
ObjectPascal
program PMServer;
|
|
|
|
uses
|
|
System.StartUpCopy,
|
|
FMX.Forms,
|
|
PM.SingleInstance in 'Source\PM.SingleInstance.pas',
|
|
UMainForm in 'UMainForm.pas' {MainForm},
|
|
PM.JSON in 'Source\PM.JSON.pas',
|
|
PM.Database in 'Source\PM.Database.pas',
|
|
PM.Router in 'Source\PM.Router.pas',
|
|
PM.StaticFiles in 'Source\PM.StaticFiles.pas',
|
|
PM.EmbeddedAssets in 'Source\PM.EmbeddedAssets.pas',
|
|
PM.Crypto in 'Source\PM.Crypto.pas',
|
|
PM.RateLimit in 'Source\PM.RateLimit.pas',
|
|
PM.Audit in 'Source\PM.Audit.pas',
|
|
PM.Session in 'Source\PM.Session.pas',
|
|
PM.HTTPServer in 'Source\PM.HTTPServer.pas',
|
|
PM.Bridge in 'Source\PM.Bridge.pas',
|
|
PM.QuickUnlock in 'Source\PM.QuickUnlock.pas',
|
|
PM.UserPrefs in 'Source\PM.UserPrefs.pas',
|
|
PM.AutoStart in 'Source\PM.AutoStart.pas',
|
|
PM.Favicon in 'Source\PM.Favicon.pas',
|
|
PM.ProcessLockdown in 'Source\PM.ProcessLockdown.pas',
|
|
PM.Handler.Ping in 'Handlers\PM.Handler.Ping.pas',
|
|
PM.Handler.Auth in 'Handlers\PM.Handler.Auth.pas',
|
|
PM.Handler.Folders in 'Handlers\PM.Handler.Folders.pas',
|
|
PM.Handler.Entries in 'Handlers\PM.Handler.Entries.pas',
|
|
PM.Handler.Passkey in 'Handlers\PM.Handler.Passkey.pas',
|
|
PM.Handler.Recovery in 'Handlers\PM.Handler.Recovery.pas',
|
|
PM.Handler.Audit in 'Handlers\PM.Handler.Audit.pas',
|
|
PM.Handler.Settings in 'Handlers\PM.Handler.Settings.pas',
|
|
PM.Handler.Attachments in 'Handlers\PM.Handler.Attachments.pas';
|
|
|
|
{$R *.res}
|
|
{$R assets\assets.res}
|
|
|
|
begin
|
|
// Single-instance: if another PMServer is running, bring it to front
|
|
// (it'll handle WM_PMSHOW on its message-only window) and exit. Avoids
|
|
// two icons in the tray and two HTTP servers fighting for the port.
|
|
if not PM.SingleInstance.AcquireOrSignal then
|
|
Exit;
|
|
|
|
Application.Initialize;
|
|
Application.CreateForm(TMainForm, MainForm);
|
|
Application.Run;
|
|
end.
|