/**
 * Per-user rsync sync configuration.
 *
 * Layout: one file per user at `<DATA_DIR>/sync-config/<sha1(username)>.json`.
 * The filename is a hash of the real username so usernames containing `.`,
 * spaces, or any non-[A-Za-z0-9_-] character don't round-trip lossily (the
 * earlier simple-sanitize approach collided `tom.admin` with `tom_admin` and
 * broke scheduler lookup).  The real username is stored inside the JSON as
 * `username` so `listUsersWithSyncConfig()` can return the actual strings.
 *
 * Passwords are encrypted with AES-256-GCM using a key derived from the
 * server's JWT secret.  A 4-byte fingerprint of the derived key is stored
 * alongside `passwordEnc` so a jwtSecret rotation (e.g. user re-runs setup,
 * config.json regenerated) is detected at read time and the public config
 * exposes `passwordNeedsReset: true` instead of silently returning the
 * wedged ciphertext.
 */
export type SyncDirection = 'push' | 'pull' | 'bidirectional';
export type AuthMethod = 'key' | 'password';
export interface SyncConfig {
    username: string;
    host: string;
    port: number;
    user: string;
    authMethod: AuthMethod;
    keyPath?: string;
    passwordEnc?: string;
    passwordFp?: string;
    remoteRoot: string;
    direction: SyncDirection;
    defaultExcludes: string[];
    schedule: {
        enabled: boolean;
        cron: string;
    };
    projectExcludes: Record<string, string[]>;
}
export declare const DEFAULT_CONFIG: Omit<SyncConfig, 'username'>;
export declare function encryptPassword(plain: string): {
    enc: string;
    fp: string;
};
export declare function decryptPassword(blob: string, expectedFp?: string): string;
export declare function isValidKeyPath(p: string | undefined | null): boolean;
/** A project folder name used on the remote must not contain path separators
 *  or start with `.`/`-` so `rsync ... remote:root/<name>/` stays inside
 *  `remoteRoot`.  `path.posix.join` does not protect against `..`. */
export declare function sanitizeFolderName(raw: string): string | null;
export declare function getSyncConfig(username: string): SyncConfig;
export declare function setSyncConfig(cfg: SyncConfig): void;
export declare function listUsersWithSyncConfig(): string[];
/**
 * Client-safe projection. Never leaks the password ciphertext. Sets
 * `passwordNeedsReset` when the stored ciphertext was encrypted with a key
 * the server no longer holds (jwtSecret rotated) — the UI should prompt for
 * re-entry instead of silently rendering `passwordSet: true`.
 */
export declare function publicConfig(cfg: SyncConfig): Omit<SyncConfig, 'passwordEnc' | 'passwordFp'> & {
    passwordSet: boolean;
    passwordNeedsReset: boolean;
};
//# sourceMappingURL=sync-config.d.ts.map