@ursalock/server 0.4.0 → 0.4.2
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/dist/index.js +37 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -503,19 +503,28 @@ function listDocuments(vaultUid, userId, opts) {
|
|
|
503
503
|
function updateDocument(uid, vaultUid, userId, input) {
|
|
504
504
|
const db = getDb();
|
|
505
505
|
if (input.version != null) {
|
|
506
|
-
const
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
506
|
+
const result = db.transaction(() => {
|
|
507
|
+
const stmt2 = db.prepare(`
|
|
508
|
+
UPDATE documents SET data = ?, hmac = ?, version = ? + 1, updated_at = unixepoch()
|
|
509
|
+
WHERE uid = ? AND vault_uid = ? AND user_id = ? AND version = ?
|
|
510
|
+
RETURNING ${DOCUMENT_COLUMNS}
|
|
511
|
+
`);
|
|
512
|
+
const doc2 = stmt2.get(input.data, input.hmac ?? null, input.version, uid, vaultUid, userId, input.version);
|
|
513
|
+
if (doc2) return { document: doc2, conflict: false };
|
|
514
|
+
const exists = db.prepare(
|
|
515
|
+
`SELECT 1 FROM documents WHERE uid = ? AND vault_uid = ? AND user_id = ?`
|
|
516
|
+
).get(uid, vaultUid, userId);
|
|
517
|
+
return { document: void 0, conflict: !!exists };
|
|
518
|
+
})();
|
|
519
|
+
return result;
|
|
512
520
|
}
|
|
513
521
|
const stmt = db.prepare(`
|
|
514
522
|
UPDATE documents SET data = ?, hmac = ?, version = version + 1, updated_at = unixepoch()
|
|
515
523
|
WHERE uid = ? AND vault_uid = ? AND user_id = ?
|
|
516
524
|
RETURNING ${DOCUMENT_COLUMNS}
|
|
517
525
|
`);
|
|
518
|
-
|
|
526
|
+
const doc = stmt.get(input.data, input.hmac ?? null, uid, vaultUid, userId);
|
|
527
|
+
return { document: doc, conflict: false };
|
|
519
528
|
}
|
|
520
529
|
function softDeleteDocument(uid, vaultUid, userId) {
|
|
521
530
|
const db = getDb();
|
|
@@ -719,10 +728,6 @@ var errors = {
|
|
|
719
728
|
insufficient_permissions: { code: "insufficient_permissions", message: "Insufficient permissions" },
|
|
720
729
|
// Vault errors
|
|
721
730
|
vault_not_found: { code: "vault_not_found", message: "Vault not found" },
|
|
722
|
-
vault_already_exists: (name) => ({
|
|
723
|
-
code: "vault_already_exists",
|
|
724
|
-
message: `Vault "${name}" already exists`
|
|
725
|
-
}),
|
|
726
731
|
vault_conflict: { code: "vault_conflict", message: "Version conflict - vault has been modified. Please refresh and retry." },
|
|
727
732
|
invalid_vault_data: { code: "invalid_vault_data", message: "Invalid vault data" },
|
|
728
733
|
// Document errors
|
|
@@ -730,20 +735,25 @@ var errors = {
|
|
|
730
735
|
document_conflict: { code: "document_conflict", message: "Version conflict - document has been modified. Please refresh and retry." },
|
|
731
736
|
document_already_exists: { code: "document_already_exists", message: "Document already exists" },
|
|
732
737
|
// Validation errors
|
|
733
|
-
validation_error: (details) => ({
|
|
734
|
-
code: "validation_error",
|
|
735
|
-
message: details
|
|
736
|
-
}),
|
|
737
738
|
invalid_request: { code: "invalid_request", message: "Invalid request" },
|
|
738
739
|
// Server errors
|
|
739
740
|
internal_error: { code: "internal_error", message: "Internal server error" }
|
|
740
741
|
};
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
742
|
+
var errorBuilders = {
|
|
743
|
+
vaultAlreadyExists: (name) => ({
|
|
744
|
+
code: "vault_already_exists",
|
|
745
|
+
message: `Vault "${name}" already exists`
|
|
746
|
+
}),
|
|
747
|
+
validationError: (details) => ({
|
|
748
|
+
code: "validation_error",
|
|
749
|
+
message: details
|
|
750
|
+
})
|
|
751
|
+
};
|
|
752
|
+
function getError(code) {
|
|
753
|
+
if (code in errors) {
|
|
754
|
+
return errors[code];
|
|
745
755
|
}
|
|
746
|
-
return
|
|
756
|
+
return { code, message: code.replace(/_/g, " ") };
|
|
747
757
|
}
|
|
748
758
|
|
|
749
759
|
// src/features/auth/middleware.ts
|
|
@@ -1657,7 +1667,7 @@ var VaultService = class {
|
|
|
1657
1667
|
createVault(userId, data) {
|
|
1658
1668
|
const existing = this.vaultRepo.findByName(data.name, userId);
|
|
1659
1669
|
if (existing) {
|
|
1660
|
-
throw new ApiException(
|
|
1670
|
+
throw new ApiException(errorBuilders.vaultAlreadyExists(data.name), 409);
|
|
1661
1671
|
}
|
|
1662
1672
|
const vault = this.vaultRepo.create({
|
|
1663
1673
|
userId,
|
|
@@ -1813,8 +1823,9 @@ var DocumentService = class {
|
|
|
1813
1823
|
this.vaultRepo = vaultRepo3;
|
|
1814
1824
|
}
|
|
1815
1825
|
/**
|
|
1816
|
-
* Verify vault
|
|
1817
|
-
*
|
|
1826
|
+
* Verify vault exists and belongs to user.
|
|
1827
|
+
* Only needed for create (to prevent orphan documents referencing non-existent vaults).
|
|
1828
|
+
* Read/update/delete queries already filter by userId — no vault exists = empty result.
|
|
1818
1829
|
*/
|
|
1819
1830
|
verifyVaultOwnership(vaultUid, userId) {
|
|
1820
1831
|
const vault = this.vaultRepo.findByUid(vaultUid, userId);
|
|
@@ -1840,7 +1851,6 @@ var DocumentService = class {
|
|
|
1840
1851
|
* Get document by UID
|
|
1841
1852
|
*/
|
|
1842
1853
|
getDocument(uid, vaultUid, userId) {
|
|
1843
|
-
this.verifyVaultOwnership(vaultUid, userId);
|
|
1844
1854
|
const document = this.documentRepo.findByUid(uid, vaultUid, userId);
|
|
1845
1855
|
if (!document) {
|
|
1846
1856
|
throw new ApiException(errors.document_not_found, 404);
|
|
@@ -1851,7 +1861,6 @@ var DocumentService = class {
|
|
|
1851
1861
|
* List documents in a vault
|
|
1852
1862
|
*/
|
|
1853
1863
|
listDocuments(vaultUid, userId, opts) {
|
|
1854
|
-
this.verifyVaultOwnership(vaultUid, userId);
|
|
1855
1864
|
const documents = this.documentRepo.list(vaultUid, userId, opts);
|
|
1856
1865
|
return {
|
|
1857
1866
|
documents: documents.map(toDocumentResponse)
|
|
@@ -1861,14 +1870,10 @@ var DocumentService = class {
|
|
|
1861
1870
|
* Update a document
|
|
1862
1871
|
*/
|
|
1863
1872
|
updateDocument(uid, vaultUid, userId, data) {
|
|
1864
|
-
this.
|
|
1865
|
-
const document = this.documentRepo.update(uid, vaultUid, userId, data);
|
|
1873
|
+
const { document, conflict } = this.documentRepo.update(uid, vaultUid, userId, data);
|
|
1866
1874
|
if (!document) {
|
|
1867
|
-
if (
|
|
1868
|
-
|
|
1869
|
-
if (existing) {
|
|
1870
|
-
throw new ApiException(errors.document_conflict, 409);
|
|
1871
|
-
}
|
|
1875
|
+
if (conflict) {
|
|
1876
|
+
throw new ApiException(errors.document_conflict, 409);
|
|
1872
1877
|
}
|
|
1873
1878
|
throw new ApiException(errors.document_not_found, 404);
|
|
1874
1879
|
}
|
|
@@ -1878,7 +1883,6 @@ var DocumentService = class {
|
|
|
1878
1883
|
* Soft delete a document
|
|
1879
1884
|
*/
|
|
1880
1885
|
deleteDocument(uid, vaultUid, userId) {
|
|
1881
|
-
this.verifyVaultOwnership(vaultUid, userId);
|
|
1882
1886
|
const document = this.documentRepo.softDelete(uid, vaultUid, userId);
|
|
1883
1887
|
if (!document) {
|
|
1884
1888
|
throw new ApiException(errors.document_not_found, 404);
|
|
@@ -1889,7 +1893,6 @@ var DocumentService = class {
|
|
|
1889
1893
|
* Delta sync - get documents modified since timestamp
|
|
1890
1894
|
*/
|
|
1891
1895
|
syncDocuments(vaultUid, userId, since) {
|
|
1892
|
-
this.verifyVaultOwnership(vaultUid, userId);
|
|
1893
1896
|
const documents = this.documentRepo.getSince(vaultUid, userId, since);
|
|
1894
1897
|
return {
|
|
1895
1898
|
documents: documents.map(toDocumentResponse),
|