chore: auto-commit uncommitted changes
This commit is contained in:
parent
af1ac0da44
commit
a150ee226f
|
|
@ -426,6 +426,21 @@ func (h *Handlers) AuthLoginComplete(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// ListEntries returns all entries (tree structure).
|
||||
func (h *Handlers) ListEntries(w http.ResponseWriter, r *http.Request) {
|
||||
// Metadata-only mode: returns entry_id, type, title — no field data, no decryption.
|
||||
// Used by web UI list view. Full data fetched per entry on click.
|
||||
if r.URL.Query().Get("meta") == "1" {
|
||||
entries, err := lib.EntryListMeta(h.db(r))
|
||||
if err != nil {
|
||||
ErrorResponse(w, http.StatusInternalServerError, "list_failed", "Failed to list entries")
|
||||
return
|
||||
}
|
||||
if entries == nil {
|
||||
entries = []lib.Entry{}
|
||||
}
|
||||
JSONResponse(w, http.StatusOK, entries)
|
||||
return
|
||||
}
|
||||
|
||||
actor := ActorFromContext(r.Context())
|
||||
var parent *int64
|
||||
if pidStr := r.URL.Query().Get("parent_id"); pidStr != "" {
|
||||
|
|
|
|||
|
|
@ -354,6 +354,29 @@ func EntryList(db *DB, vaultKey []byte, parentID *int64) ([]Entry, error) {
|
|||
return entries, rows.Err()
|
||||
}
|
||||
|
||||
// EntryListMeta returns entry metadata only — no decryption, no field data.
|
||||
// Used for list views. Individual entries fetched on demand via EntryGet.
|
||||
func EntryListMeta(db *DB) ([]Entry, error) {
|
||||
rows, err := db.Conn.Query(
|
||||
`SELECT entry_id, parent_id, type, title, data_level, created_at, updated_at, version
|
||||
FROM entries WHERE deleted_at IS NULL ORDER BY type, title`,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var entries []Entry
|
||||
for rows.Next() {
|
||||
var e Entry
|
||||
if err := rows.Scan(&e.EntryID, &e.ParentID, &e.Type, &e.Title, &e.DataLevel, &e.CreatedAt, &e.UpdatedAt, &e.Version); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
entries = append(entries, e)
|
||||
}
|
||||
return entries, rows.Err()
|
||||
}
|
||||
|
||||
// EntrySearch searches entries by title (blind index lookup).
|
||||
func EntrySearch(db *DB, vaultKey []byte, query string) ([]Entry, error) {
|
||||
hmacKey, err := DeriveHMACKey(vaultKey)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -216,6 +216,63 @@
|
|||
});
|
||||
});
|
||||
|
||||
/* --- Test 13: L3 TOTP seed cannot be read with L2 key --- */
|
||||
tests.push(function(done) {
|
||||
var name = 'L3 TOTP seed inaccessible to agent (L2 key)';
|
||||
var seed = 'JBSWY3DPEHPK3PXP'; // a TOTP seed
|
||||
resolve(vault1984.crypto.encrypt_field(K32, 'totp', seed), function(ct, err) {
|
||||
if (err) { fail(name, 'encrypt failed'); done(); return; }
|
||||
// Agent has K16 (L2), tries to decrypt L3 TOTP seed
|
||||
safe(function() { return vault1984.crypto.decrypt_field(K16, 'totp', ct); }, function(pt, err2) {
|
||||
if (err2) pass(name);
|
||||
else fail(name, 'L2 key decrypted L3 TOTP seed to "' + pt + '"');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/* --- Test 14: L2 TOTP seed IS accessible with L2 key --- */
|
||||
tests.push(function(done) {
|
||||
var name = 'L2 TOTP seed accessible to agent (L2 key)';
|
||||
var seed = 'JBSWY3DPEHPK3PXP';
|
||||
resolve(vault1984.crypto.encrypt_field(K16, 'totp', seed), function(ct, err) {
|
||||
if (err) { fail(name, 'encrypt failed'); done(); return; }
|
||||
resolve(vault1984.crypto.decrypt_field(K16, 'totp', ct), function(pt, err2) {
|
||||
if (err2) fail(name, err2.message);
|
||||
else if (pt === seed) pass(name);
|
||||
else fail(name, 'got "' + pt + '"');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/* --- Test 15: L3 card number cannot be read with L2 key --- */
|
||||
tests.push(function(done) {
|
||||
var name = 'L3 card number inaccessible to agent (L2 key)';
|
||||
resolve(vault1984.crypto.encrypt_field(K32, 'Number', '5452120017212208'), function(ct, err) {
|
||||
if (err) { fail(name, 'encrypt failed'); done(); return; }
|
||||
safe(function() { return vault1984.crypto.decrypt_field(K16, 'Number', ct); }, function(pt, err2) {
|
||||
if (err2) pass(name);
|
||||
else fail(name, 'L2 key decrypted L3 card number');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/* --- Test 16: Truncation model — L2 key is prefix of L3 but cannot derive L3 --- */
|
||||
tests.push(function(done) {
|
||||
var name = 'truncation: L2 prefix of L3, still cannot decrypt L3';
|
||||
// K16 = K32[0..16] by design. Encrypt with full K32, try with K16.
|
||||
resolve(vault1984.crypto.encrypt_field(K32, 'secret', 'classified'), function(ct, err) {
|
||||
if (err) { fail(name, 'encrypt failed'); done(); return; }
|
||||
safe(function() { return vault1984.crypto.decrypt_field(K16, 'secret', ct); }, function(pt, err2) {
|
||||
if (err2) pass(name);
|
||||
else fail(name, 'L2 (prefix of L3) decrypted L3 data');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/* --- Runner --- */
|
||||
function run(idx) {
|
||||
if (idx >= tests.length) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue