@keeper-security/keeperapi 16.0.1 → 16.0.4
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/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/07113f92cc3a9f5dc57b92f54542a63463f1fa9a +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/1ba6467ba06d4bfc0c8581f4ee12c2c0f687214e +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/1de1e40928c5c58c4f677d93986cdff01b3d0417 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/47382883a57ad5790d3fd6abd39f33f773726b3b +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/4939a895ecf4daac58b0d73bccd49876515d41b8 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/592d89407340c5ec6ad006df327e588b3f442eca +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/59783c8cc0cc9d984f5407c218d213bca4c98503 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/61fa6cf725249a1cae9b94b74a8c23aa3efd2ca1 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/77aced5528ce05fe900fdf7634042ec3c0f18255 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/b32ea8d6d3de0c6d8e178eff069fea4e11fa92b1 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/c05be8364ff56aba0298689783666ddb97a31285 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/e23bf49223ba8b7ec926e46c40b27b0353cfc50e +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/code/cache/eec92c105b2694c31bff21903ddc3ef81af8f056 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/07113f92cc3a9f5dc57b92f54542a63463f1fa9a +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/1ba6467ba06d4bfc0c8581f4ee12c2c0f687214e +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/1de1e40928c5c58c4f677d93986cdff01b3d0417 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/47382883a57ad5790d3fd6abd39f33f773726b3b +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/4939a895ecf4daac58b0d73bccd49876515d41b8 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/592d89407340c5ec6ad006df327e588b3f442eca +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/59783c8cc0cc9d984f5407c218d213bca4c98503 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/61fa6cf725249a1cae9b94b74a8c23aa3efd2ca1 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/77aced5528ce05fe900fdf7634042ec3c0f18255 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/b32ea8d6d3de0c6d8e178eff069fea4e11fa92b1 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/c05be8364ff56aba0298689783666ddb97a31285 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/e23bf49223ba8b7ec926e46c40b27b0353cfc50e +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/semanticDiagnostics/cache/eec92c105b2694c31bff21903ddc3ef81af8f056 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/07113f92cc3a9f5dc57b92f54542a63463f1fa9a +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/1ba6467ba06d4bfc0c8581f4ee12c2c0f687214e +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/1de1e40928c5c58c4f677d93986cdff01b3d0417 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/47382883a57ad5790d3fd6abd39f33f773726b3b +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/4939a895ecf4daac58b0d73bccd49876515d41b8 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/592d89407340c5ec6ad006df327e588b3f442eca +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/59783c8cc0cc9d984f5407c218d213bca4c98503 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/61fa6cf725249a1cae9b94b74a8c23aa3efd2ca1 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/77aced5528ce05fe900fdf7634042ec3c0f18255 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/b32ea8d6d3de0c6d8e178eff069fea4e11fa92b1 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/c05be8364ff56aba0298689783666ddb97a31285 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/e23bf49223ba8b7ec926e46c40b27b0353cfc50e +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/syntacticDiagnostics/cache/eec92c105b2694c31bff21903ddc3ef81af8f056 +1 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/20b49cde4def23063b280689e4ff4d5a3803712b +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/3809196a67de680945038f2b4846e2e3b4af35aa +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/4ad5d47b1ce7bf45cc7d9ff8c970e1fc57f446f3 +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/5a0816a3c916ff0e4961dc0ec2da48646f2ac5aa +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/6182f5491d41e8f10acfbcf46ee875587904f5a3 +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/7ca2e31bcece668dfa5de5e1349ba34a757b5140 +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/86a4b0102f5568ac0a5b946d05c55f42c30b472d +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/87fae47dd5b05377c04cfe377699d748414dc1c9 +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/a7c23ecebcaf23c9346007731c5796b96c580738 +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/ac4d101c3489192db3e0ec98430a2336cba9a741 +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/b1eb441c5b806d06ba6bb36fcfd0cc4746c23a8a +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/b7942903000069a51e317fef1595a8ea1d8b828d +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/cee91236390168fd38b01aaae7bed3099bb4555a +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/d7c87ce194d923e6f02c7e570008e88ade1cbabf +0 -0
- package/.rpt2_cache/rpt2_73ef004c41e5fb714e8076cf96455df4f040d49c/types/cache/fba70878178c036fb4e9e1f19bdb465a1270d258 +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/05d17f791979143cbce20e3e3e811aa19ed8b492 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/07113f92cc3a9f5dc57b92f54542a63463f1fa9a +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/1ba6467ba06d4bfc0c8581f4ee12c2c0f687214e +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/1de1e40928c5c58c4f677d93986cdff01b3d0417 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/47382883a57ad5790d3fd6abd39f33f773726b3b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/4d58c1113d07816b1909aaef4395fd8b4d0ee13c +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/4ee978699d6de2a60214b16c42d87f8e9309636b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/50f4a014d14ada987c125e6ea55d4e6e75605313 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/58aa8c228c99b690d3ca1f3b464585c41d1cd4bb +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/592d89407340c5ec6ad006df327e588b3f442eca +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/59783c8cc0cc9d984f5407c218d213bca4c98503 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/61fa6cf725249a1cae9b94b74a8c23aa3efd2ca1 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/89f8a81d9d078b69f9fa7fa95251b38ccc394a3b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/b32ea8d6d3de0c6d8e178eff069fea4e11fa92b1 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/c05be8364ff56aba0298689783666ddb97a31285 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/e23bf49223ba8b7ec926e46c40b27b0353cfc50e +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/code/cache/eec92c105b2694c31bff21903ddc3ef81af8f056 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/05d17f791979143cbce20e3e3e811aa19ed8b492 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/07113f92cc3a9f5dc57b92f54542a63463f1fa9a +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/1ba6467ba06d4bfc0c8581f4ee12c2c0f687214e +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/1de1e40928c5c58c4f677d93986cdff01b3d0417 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/47382883a57ad5790d3fd6abd39f33f773726b3b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/4d58c1113d07816b1909aaef4395fd8b4d0ee13c +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/4ee978699d6de2a60214b16c42d87f8e9309636b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/50f4a014d14ada987c125e6ea55d4e6e75605313 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/58aa8c228c99b690d3ca1f3b464585c41d1cd4bb +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/592d89407340c5ec6ad006df327e588b3f442eca +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/59783c8cc0cc9d984f5407c218d213bca4c98503 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/61fa6cf725249a1cae9b94b74a8c23aa3efd2ca1 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/89f8a81d9d078b69f9fa7fa95251b38ccc394a3b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/b32ea8d6d3de0c6d8e178eff069fea4e11fa92b1 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/c05be8364ff56aba0298689783666ddb97a31285 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/e23bf49223ba8b7ec926e46c40b27b0353cfc50e +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/semanticDiagnostics/cache/eec92c105b2694c31bff21903ddc3ef81af8f056 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/05d17f791979143cbce20e3e3e811aa19ed8b492 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/07113f92cc3a9f5dc57b92f54542a63463f1fa9a +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/1ba6467ba06d4bfc0c8581f4ee12c2c0f687214e +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/1de1e40928c5c58c4f677d93986cdff01b3d0417 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/47382883a57ad5790d3fd6abd39f33f773726b3b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/4d58c1113d07816b1909aaef4395fd8b4d0ee13c +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/4ee978699d6de2a60214b16c42d87f8e9309636b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/50f4a014d14ada987c125e6ea55d4e6e75605313 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/58aa8c228c99b690d3ca1f3b464585c41d1cd4bb +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/592d89407340c5ec6ad006df327e588b3f442eca +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/59783c8cc0cc9d984f5407c218d213bca4c98503 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/61fa6cf725249a1cae9b94b74a8c23aa3efd2ca1 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/89f8a81d9d078b69f9fa7fa95251b38ccc394a3b +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/b32ea8d6d3de0c6d8e178eff069fea4e11fa92b1 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/c05be8364ff56aba0298689783666ddb97a31285 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/e23bf49223ba8b7ec926e46c40b27b0353cfc50e +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/syntacticDiagnostics/cache/eec92c105b2694c31bff21903ddc3ef81af8f056 +1 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/20b49cde4def23063b280689e4ff4d5a3803712b +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/3809196a67de680945038f2b4846e2e3b4af35aa +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/4ad5d47b1ce7bf45cc7d9ff8c970e1fc57f446f3 +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/5a0816a3c916ff0e4961dc0ec2da48646f2ac5aa +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/6182f5491d41e8f10acfbcf46ee875587904f5a3 +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/7ca2e31bcece668dfa5de5e1349ba34a757b5140 +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/86a4b0102f5568ac0a5b946d05c55f42c30b472d +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/87fae47dd5b05377c04cfe377699d748414dc1c9 +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/a7c23ecebcaf23c9346007731c5796b96c580738 +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/ac4d101c3489192db3e0ec98430a2336cba9a741 +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/b1eb441c5b806d06ba6bb36fcfd0cc4746c23a8a +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/b7942903000069a51e317fef1595a8ea1d8b828d +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/cee91236390168fd38b01aaae7bed3099bb4555a +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/d7c87ce194d923e6f02c7e570008e88ade1cbabf +0 -0
- package/.rpt2_cache/rpt2_e52dc086a65136b8064433446ffcd05307935b95/types/cache/fba70878178c036fb4e9e1f19bdb465a1270d258 +0 -0
- package/babel.config.js +6 -0
- package/package.json +7 -10
- package/rollup.config.js +50 -0
- package/scripts/cleanDistFolder.js +9 -0
- package/src/__tests__/utils.test.js +13 -0
- package/src/auth.ts +1514 -0
- package/src/browser/asn1hex.ts +296 -0
- package/src/browser/index.ts +17 -0
- package/src/browser/jsbn.ts +1213 -0
- package/src/browser/platform.ts +434 -0
- package/src/browser/rng.ts +15 -0
- package/src/browser/rsa.ts +262 -0
- package/src/commands.ts +1378 -0
- package/src/company.ts +244 -0
- package/src/configuration.ts +125 -0
- package/src/endpoint.ts +350 -0
- package/src/node/index.ts +17 -0
- package/src/node/platform.ts +283 -0
- package/src/platform.ts +76 -0
- package/{dist → src}/proto.d.ts +0 -0
- package/src/proto.js +136564 -0
- package/src/restMessages.ts +311 -0
- package/src/utils.ts +169 -0
- package/src/vault.ts +844 -0
- package/src/vendorContext.ts +69 -0
- package/src/vendorModel.ts +36 -0
- package/tsconfig.json +14 -0
- package/tsconfig.rollup.json +14 -0
package/src/vault.ts
ADDED
|
@@ -0,0 +1,844 @@
|
|
|
1
|
+
import {Auth} from './auth'
|
|
2
|
+
import {
|
|
3
|
+
DeleteCommand,
|
|
4
|
+
FolderAddCommand,
|
|
5
|
+
PreDeleteCommand,
|
|
6
|
+
PublicKeysCommand,
|
|
7
|
+
PurgeDeletedRecordsCommand,
|
|
8
|
+
RecordAddCommand,
|
|
9
|
+
RecordData,
|
|
10
|
+
RecordMetaData,
|
|
11
|
+
RecordShareUpdateCommand,
|
|
12
|
+
RecordShareUpdateResponse,
|
|
13
|
+
RequestUploadCommand,
|
|
14
|
+
SharedFolder,
|
|
15
|
+
SharedFolderUpdateCommand,
|
|
16
|
+
ShareObject,
|
|
17
|
+
SyncDownCommand,
|
|
18
|
+
SyncDataInclude, DeleteResponse, RecordUpdateCommand
|
|
19
|
+
} from './commands'
|
|
20
|
+
import {platform} from './platform'
|
|
21
|
+
import {
|
|
22
|
+
decryptFromStorage,
|
|
23
|
+
decryptFromStorageGcm,
|
|
24
|
+
decryptKey,
|
|
25
|
+
encryptForStorage,
|
|
26
|
+
encryptObjectForStorage,
|
|
27
|
+
encryptObjectForStorageGCM,
|
|
28
|
+
generateEncryptionKey,
|
|
29
|
+
generateUid,
|
|
30
|
+
normal64,
|
|
31
|
+
normal64Bytes,
|
|
32
|
+
shareKey, shareKeyEC,
|
|
33
|
+
webSafe64FromBytes
|
|
34
|
+
} from './utils'
|
|
35
|
+
import {
|
|
36
|
+
applicationAddMessage,
|
|
37
|
+
fileAddMessage,
|
|
38
|
+
fileDownloadMessage,
|
|
39
|
+
getEnterprisePublicKeyMessage,
|
|
40
|
+
recordsAddMessage,
|
|
41
|
+
recordsUpdateMessage
|
|
42
|
+
} from './restMessages'
|
|
43
|
+
import {Records} from './proto'
|
|
44
|
+
import RecordFolderType = Records.RecordFolderType;
|
|
45
|
+
import FileAddResult = Records.FileAddResult;
|
|
46
|
+
|
|
47
|
+
async function decryptRecord(record: VaultRecord) {
|
|
48
|
+
try {
|
|
49
|
+
const dataBytes = record.recordData.version < 3
|
|
50
|
+
? await decryptFromStorage(record.recordData.data, record.key)
|
|
51
|
+
: await decryptFromStorageGcm(record.recordData.data, record.key)
|
|
52
|
+
record.data = JSON.parse(platform.bytesToString(dataBytes))
|
|
53
|
+
if (record.recordData.extra) {
|
|
54
|
+
record.extra = JSON.parse(platform.bytesToString(await decryptFromStorage(record.recordData.extra, record.key)))
|
|
55
|
+
}
|
|
56
|
+
} catch (e) {
|
|
57
|
+
console.log(e)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class Vault {
|
|
62
|
+
private _includes: SyncDataInclude[] = ['folders', 'non_shared_data', 'record', 'shared_folder', 'sfheaders', 'sfrecords', 'sfusers']
|
|
63
|
+
private _records: Record<string, VaultRecord> = {}
|
|
64
|
+
private _sharedFolders: Record<string, VaultSharedFolder> = {}
|
|
65
|
+
private _revision: number = 0
|
|
66
|
+
noTypedRecords: boolean = false
|
|
67
|
+
|
|
68
|
+
constructor(private auth: Auth) {
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private getRecord(recordUid: string): { record: VaultRecord, isNew: boolean } {
|
|
72
|
+
let record = this._records[recordUid]
|
|
73
|
+
let isNew = false;
|
|
74
|
+
if (!record) {
|
|
75
|
+
record = {}
|
|
76
|
+
this._records[recordUid] = record
|
|
77
|
+
isNew = true
|
|
78
|
+
}
|
|
79
|
+
return { record, isNew }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get includes(): SyncDataInclude[] {
|
|
83
|
+
return this._includes
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get revision(): number {
|
|
87
|
+
return this._revision
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
get records(): VaultRecord[] {
|
|
91
|
+
return Object.values(this._records)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
get sharedFolders(): VaultSharedFolder[] {
|
|
95
|
+
return Object.values(this._sharedFolders)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
get recordUids(): string[] {
|
|
99
|
+
return Object.keys(this._records)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
get sharedFolderUids(): string[] {
|
|
103
|
+
return Object.keys(this._sharedFolders)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
recordByUid(record_uid: string): VaultRecord {
|
|
107
|
+
return this._records[record_uid]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
recordByUidBytes(record_uid: Uint8Array): VaultRecord {
|
|
111
|
+
return this.recordByUid(webSafe64FromBytes(record_uid))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async decryptKey(encryptedKey: string, keyType: number): Promise<Uint8Array> {
|
|
115
|
+
switch (keyType) {
|
|
116
|
+
case 1:
|
|
117
|
+
return decryptFromStorage(encryptedKey, this.auth.dataKey)
|
|
118
|
+
case 2:
|
|
119
|
+
return platform.privateDecrypt(normal64Bytes(encryptedKey), this.auth.privateKey)
|
|
120
|
+
case 3:
|
|
121
|
+
return decryptKey(encryptedKey, this.auth.dataKey)
|
|
122
|
+
case 4:
|
|
123
|
+
return platform.privateDecryptEC(normal64Bytes(encryptedKey), this.auth.eccPrivateKey)
|
|
124
|
+
default:
|
|
125
|
+
throw new Error(`Unknown key type: ${keyType}`)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
setIncludes(includes: SyncDataInclude[]): void {
|
|
130
|
+
this._includes = includes
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// todo: remove logResponse in favor of a unified log levels solution
|
|
134
|
+
async syncDown(revision?: number, logResponse?: boolean) {
|
|
135
|
+
if (typeof revision === 'number') {
|
|
136
|
+
this._revision = revision
|
|
137
|
+
}
|
|
138
|
+
console.log(`syncing revision ${this._revision} for ${this.auth.username}`)
|
|
139
|
+
|
|
140
|
+
let syncDownCommand = new SyncDownCommand(this._revision)
|
|
141
|
+
syncDownCommand.include = [...this._includes]
|
|
142
|
+
if (!this.noTypedRecords) {
|
|
143
|
+
syncDownCommand.include.push('typed_record', 'app_record')
|
|
144
|
+
}
|
|
145
|
+
let syncDownResponse = await this.auth.executeCommand(syncDownCommand)
|
|
146
|
+
if (logResponse) {
|
|
147
|
+
console.log(syncDownResponse)
|
|
148
|
+
// console.log(syncDownResponse.shared_folders[0].records)
|
|
149
|
+
}
|
|
150
|
+
this._revision = syncDownResponse.revision
|
|
151
|
+
if (syncDownResponse.full_sync) {
|
|
152
|
+
this._records = {}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
let added = 0
|
|
156
|
+
let updated = 0
|
|
157
|
+
let removed = 0
|
|
158
|
+
for (let recordData of syncDownResponse.records || []) {
|
|
159
|
+
let { record, isNew } = this.getRecord(recordData.record_uid)
|
|
160
|
+
record.recordData = recordData
|
|
161
|
+
if (isNew) {
|
|
162
|
+
added++
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
updated++
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (let meta of syncDownResponse.record_meta_data || []) {
|
|
169
|
+
let { record } = this.getRecord(meta.record_uid)
|
|
170
|
+
record.metaData = meta
|
|
171
|
+
try {
|
|
172
|
+
record.key = await this.decryptKey(meta.record_key, meta.record_key_type);
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
console.log(e);
|
|
176
|
+
}
|
|
177
|
+
await decryptRecord(record)
|
|
178
|
+
}
|
|
179
|
+
for (let sharedFolder of syncDownResponse.shared_folders || []) {
|
|
180
|
+
let vaultFolder: VaultSharedFolder = {
|
|
181
|
+
sharedFolder: sharedFolder
|
|
182
|
+
}
|
|
183
|
+
this._sharedFolders[sharedFolder.shared_folder_uid] = vaultFolder
|
|
184
|
+
if (!(sharedFolder.shared_folder_key && sharedFolder.key_type)) {
|
|
185
|
+
continue
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
vaultFolder.key = await this.decryptKey(sharedFolder.shared_folder_key, sharedFolder.key_type);
|
|
189
|
+
for (let sfRecord of sharedFolder.records || []) {
|
|
190
|
+
let recordKey
|
|
191
|
+
try {
|
|
192
|
+
recordKey = sfRecord.record_key.length === 80
|
|
193
|
+
? await decryptKey(sfRecord.record_key, vaultFolder.key) // GCM
|
|
194
|
+
: decryptFromStorage(sfRecord.record_key, vaultFolder.key) // CBC
|
|
195
|
+
let { record } = this.getRecord(sfRecord.record_uid)
|
|
196
|
+
record.key = recordKey
|
|
197
|
+
record.sharedFolderUid = sharedFolder.shared_folder_uid
|
|
198
|
+
await decryptRecord(record)
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
console.log(e);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
catch (e) {
|
|
206
|
+
console.log(e);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
for (let team of syncDownResponse.teams || []) {
|
|
211
|
+
const teamKey = await this.decryptKey(team.team_key, team.team_key_type);
|
|
212
|
+
for (let folderKey of team.shared_folder_keys || []) {
|
|
213
|
+
let decryptedFolderKey
|
|
214
|
+
switch (folderKey.key_type) {
|
|
215
|
+
case 1:
|
|
216
|
+
decryptedFolderKey = decryptFromStorage(folderKey.shared_folder_key, teamKey)
|
|
217
|
+
break
|
|
218
|
+
case 2:
|
|
219
|
+
const teamPrivateKey = await decryptFromStorage(team.team_private_key, teamKey)
|
|
220
|
+
decryptedFolderKey = platform.privateDecrypt(normal64Bytes(folderKey.shared_folder_key), teamPrivateKey)
|
|
221
|
+
break
|
|
222
|
+
default:
|
|
223
|
+
throw new Error(`Unknown key type: ${folderKey.key_type}`)
|
|
224
|
+
}
|
|
225
|
+
this._sharedFolders[folderKey.shared_folder_uid].key = decryptedFolderKey
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for (let sffRecord of syncDownResponse.shared_folder_folder_records || []) {
|
|
230
|
+
let { record } = this.getRecord(sffRecord.record_uid)
|
|
231
|
+
record.sharedFolderFolderUid = sffRecord.folder_uid
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
for (let uid of syncDownResponse.removed_records || []) {
|
|
235
|
+
if (this.records[uid]) {
|
|
236
|
+
removed++
|
|
237
|
+
delete this.records[uid]
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
for (let non_shared_data of syncDownResponse.non_shared_data || []) {
|
|
242
|
+
let { record } = this.getRecord(non_shared_data.record_uid)
|
|
243
|
+
try {
|
|
244
|
+
const nonSharedData = record.recordData.version > 2
|
|
245
|
+
? await decryptFromStorageGcm(non_shared_data.data, this.auth.dataKey)
|
|
246
|
+
: await decryptFromStorage(non_shared_data.data, this.auth.dataKey)
|
|
247
|
+
record.nonSharedData = JSON.parse(platform.bytesToString(nonSharedData))
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
console.log(e)
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
for (let record of this.records.filter(x => !!x.recordData?.owner_uid)) {
|
|
255
|
+
const owner = this._records[record.recordData.owner_uid]
|
|
256
|
+
if (!owner.links) {
|
|
257
|
+
owner.links = []
|
|
258
|
+
}
|
|
259
|
+
owner.links.push(record.recordData.record_uid)
|
|
260
|
+
record.key = await decryptKey(record.recordData.link_key, owner.key)
|
|
261
|
+
await decryptRecord(record)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (added > 0)
|
|
265
|
+
console.log(`${added} records added.`)
|
|
266
|
+
if (updated > 0)
|
|
267
|
+
console.log(`${updated} records updated.`)
|
|
268
|
+
if (removed > 0)
|
|
269
|
+
console.log(`${removed} records removed.`)
|
|
270
|
+
console.log(`Synced to the revision ${syncDownResponse.revision}`)
|
|
271
|
+
console.log(`${Object.keys(this._records).length} records are in the vault.`)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
async addRecord(recordData: KeeperRecordData, sharedFolderUid?: string, files?: [ExtraFile]): Promise<string> {
|
|
275
|
+
let recordAddCommand = new RecordAddCommand()
|
|
276
|
+
recordAddCommand.record_uid = generateUid()
|
|
277
|
+
let recordKey = generateEncryptionKey()
|
|
278
|
+
recordAddCommand.record_key = await encryptForStorage(recordKey, this.auth.dataKey)
|
|
279
|
+
recordAddCommand.record_type = 'password'
|
|
280
|
+
recordAddCommand.data = await encryptForStorage(platform.stringToBytes(JSON.stringify(recordData)), recordKey)
|
|
281
|
+
recordAddCommand.how_long_ago = 0
|
|
282
|
+
if (sharedFolderUid) {
|
|
283
|
+
recordAddCommand.folder_type = 'shared_folder'
|
|
284
|
+
recordAddCommand.folder_uid = sharedFolderUid
|
|
285
|
+
recordAddCommand.folder_key = await encryptForStorage(recordKey, this._sharedFolders[sharedFolderUid].key)
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
recordAddCommand.folder_type = 'user_folder'
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (files) {
|
|
292
|
+
let extra: KeeperRecordExtra = {
|
|
293
|
+
fields: [],
|
|
294
|
+
files: files
|
|
295
|
+
}
|
|
296
|
+
recordAddCommand.extra = await encryptForStorage(platform.stringToBytes(JSON.stringify(extra)), recordKey)
|
|
297
|
+
recordAddCommand.file_ids = files.map(x => x.id)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
await this.auth.executeCommand(recordAddCommand)
|
|
301
|
+
return recordAddCommand.record_uid
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
async addRecordNew(recordData: any, sharedFolderUid?: string, linkedRecords?: string[]): Promise<Records.IRecordsModifyResponse> {
|
|
305
|
+
const recordKey = generateEncryptionKey()
|
|
306
|
+
|
|
307
|
+
const encryptedKey = await platform.aesGcmEncrypt(recordKey, this.auth.dataKey)
|
|
308
|
+
const encryptedData = await encryptObjectForStorageGCM(recordData, recordKey)
|
|
309
|
+
|
|
310
|
+
let recordAdd: Records.IRecordAdd = {
|
|
311
|
+
recordUid: platform.getRandomBytes(16),
|
|
312
|
+
recordKey: encryptedKey,
|
|
313
|
+
data: encryptedData,
|
|
314
|
+
clientModifiedTime: new Date().getTime()
|
|
315
|
+
}
|
|
316
|
+
if (sharedFolderUid) {
|
|
317
|
+
recordAdd.folderType = RecordFolderType.shared_folder
|
|
318
|
+
recordAdd.folderUid = normal64Bytes(sharedFolderUid)
|
|
319
|
+
recordAdd.folderKey = await platform.aesGcmEncrypt(recordKey, this._sharedFolders[sharedFolderUid].key)
|
|
320
|
+
}
|
|
321
|
+
if (linkedRecords) {
|
|
322
|
+
let links: Records.IRecordLink[] = []
|
|
323
|
+
for (const linkedRecord of linkedRecords) {
|
|
324
|
+
const linkedRecordKey = generateEncryptionKey()
|
|
325
|
+
// const linkedRecordKey = await platform.aesGcmEncrypt(this._records[linkedRecord].key, recordKey)
|
|
326
|
+
links.push({
|
|
327
|
+
recordUid: normal64Bytes(linkedRecord),
|
|
328
|
+
recordKey: linkedRecordKey
|
|
329
|
+
})
|
|
330
|
+
}
|
|
331
|
+
recordAdd.recordLinks = links
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const recordAddResponse = await this.auth.executeRest(recordsAddMessage({
|
|
335
|
+
clientTime: new Date().getTime(),
|
|
336
|
+
records: [recordAdd]
|
|
337
|
+
}))
|
|
338
|
+
|
|
339
|
+
const recordUid = webSafe64FromBytes(recordAdd.recordUid)
|
|
340
|
+
this._records[recordUid] = {
|
|
341
|
+
recordData: {
|
|
342
|
+
record_uid: recordUid,
|
|
343
|
+
version: 3
|
|
344
|
+
},
|
|
345
|
+
key: recordKey
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return recordAddResponse
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async addRecordsNew(recordsData: any[]): Promise<Records.IRecordsModifyResponse> {
|
|
352
|
+
const now = new Date().getTime()
|
|
353
|
+
|
|
354
|
+
let records: Records.IRecordAdd[] = []
|
|
355
|
+
let keys: Record<string, Uint8Array> = {}
|
|
356
|
+
for (const recordData of recordsData) {
|
|
357
|
+
const recordKey = generateEncryptionKey()
|
|
358
|
+
|
|
359
|
+
const encryptedKey = await platform.aesGcmEncrypt(recordKey, this.auth.dataKey)
|
|
360
|
+
const encryptedData = await encryptObjectForStorageGCM(recordData, recordKey)
|
|
361
|
+
|
|
362
|
+
let recordAdd: Records.IRecordAdd = {
|
|
363
|
+
recordUid: platform.getRandomBytes(16),
|
|
364
|
+
recordKey: encryptedKey,
|
|
365
|
+
data: encryptedData,
|
|
366
|
+
clientModifiedTime: now
|
|
367
|
+
}
|
|
368
|
+
records.push(recordAdd)
|
|
369
|
+
keys[webSafe64FromBytes(recordAdd.recordUid)] = recordKey
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const recordsAddResponse = await this.auth.executeRest(recordsAddMessage({
|
|
373
|
+
clientTime: now,
|
|
374
|
+
records: records
|
|
375
|
+
}))
|
|
376
|
+
|
|
377
|
+
for (const recordResponse of recordsAddResponse.records) {
|
|
378
|
+
const recordUid = webSafe64FromBytes(recordResponse.recordUid)
|
|
379
|
+
this._records[recordUid] = {
|
|
380
|
+
recordData: {
|
|
381
|
+
record_uid: recordUid,
|
|
382
|
+
version: 3
|
|
383
|
+
},
|
|
384
|
+
key: keys[recordUid]
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
return recordsAddResponse
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
async uploadFile(fileName: string, fileData: Uint8Array, thumbnailData?: Uint8Array): Promise<string> {
|
|
392
|
+
|
|
393
|
+
const fileMetaData = {
|
|
394
|
+
name: fileName,
|
|
395
|
+
hasThumbnail: !!thumbnailData
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const recordKey = generateEncryptionKey()
|
|
399
|
+
|
|
400
|
+
const encryptedKey = await platform.aesGcmEncrypt(recordKey, this.auth.dataKey)
|
|
401
|
+
const encryptedData = await encryptObjectForStorageGCM(fileMetaData, recordKey)
|
|
402
|
+
const encryptedFile = await platform.aesGcmEncrypt(fileData, recordKey)
|
|
403
|
+
const encryptedThumbnail = thumbnailData
|
|
404
|
+
? await platform.aesGcmEncrypt(thumbnailData, recordKey)
|
|
405
|
+
: undefined
|
|
406
|
+
|
|
407
|
+
const fileRequest = {
|
|
408
|
+
clientTime: new Date().getTime(),
|
|
409
|
+
files: [
|
|
410
|
+
{
|
|
411
|
+
recordUid: platform.getRandomBytes(16),
|
|
412
|
+
recordKey: encryptedKey,
|
|
413
|
+
data: encryptedData,
|
|
414
|
+
fileSize: encryptedFile.length,
|
|
415
|
+
thumbSize: encryptedThumbnail ? encryptedThumbnail.length : undefined
|
|
416
|
+
}
|
|
417
|
+
]
|
|
418
|
+
}
|
|
419
|
+
console.log(fileRequest)
|
|
420
|
+
const rq = fileAddMessage(fileRequest)
|
|
421
|
+
|
|
422
|
+
const fileAddResponse = await this.auth.executeRest(rq)
|
|
423
|
+
const file = fileAddResponse.files[0]
|
|
424
|
+
if (file.status !== FileAddResult.FA_SUCCESS)
|
|
425
|
+
throw new Error(`Error adding a file record for ${fileName}`)
|
|
426
|
+
|
|
427
|
+
console.log(file.url)
|
|
428
|
+
await this.uploadFileData(file.url, file.parameters, file.successStatusCode, encryptedFile)
|
|
429
|
+
if (encryptedThumbnail) {
|
|
430
|
+
await this.uploadFileData(file.url, file.thumbnailParameters, file.successStatusCode, encryptedThumbnail)
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const fileUid = webSafe64FromBytes(file.recordUid)
|
|
434
|
+
this._records[fileUid] = {
|
|
435
|
+
recordData: {
|
|
436
|
+
record_uid: fileUid,
|
|
437
|
+
version: 4
|
|
438
|
+
},
|
|
439
|
+
key: recordKey
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return fileUid
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
async uploadFileData(url: string, parameters: string, successStatusCode: number, encryptedData: Uint8Array) {
|
|
446
|
+
const res = await platform.fileUpload(url, JSON.parse(parameters), encryptedData)
|
|
447
|
+
if (res.statusCode !== successStatusCode) {
|
|
448
|
+
throw new Error(`Upload failed (${res.statusMessage}), code ${res.statusCode}`)
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async downloadFile(recordUid: string, thumbNail: boolean): Promise<Uint8Array> {
|
|
453
|
+
const rq = fileDownloadMessage({
|
|
454
|
+
recordUids: [
|
|
455
|
+
normal64Bytes(recordUid)
|
|
456
|
+
],
|
|
457
|
+
forThumbnails: thumbNail
|
|
458
|
+
})
|
|
459
|
+
let resp = await this.auth.executeRest(rq)
|
|
460
|
+
let file = resp.files[0]
|
|
461
|
+
console.log(resp)
|
|
462
|
+
console.log(file)
|
|
463
|
+
|
|
464
|
+
const fileResponse = await platform.get(file.url, {})
|
|
465
|
+
console.log(fileResponse)
|
|
466
|
+
switch (file.fileKeyType) {
|
|
467
|
+
case Records.RecordKeyType.ENCRYPTED_BY_DATA_KEY:
|
|
468
|
+
return platform.aesCbcDecrypt(fileResponse.data, this._records[recordUid].key, false);
|
|
469
|
+
case Records.RecordKeyType.ENCRYPTED_BY_DATA_KEY_GCM:
|
|
470
|
+
return platform.aesGcmDecrypt(fileResponse.data, this._records[recordUid].key);
|
|
471
|
+
default:
|
|
472
|
+
throw Error(`Unsupported kile key type: ${file.fileKeyType}`)
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
async addApplication(appData: any): Promise<string> {
|
|
477
|
+
const recordKey = generateEncryptionKey()
|
|
478
|
+
const encryptedKey = await platform.aesGcmEncrypt(recordKey, this.auth.dataKey)
|
|
479
|
+
const encryptedData = await encryptObjectForStorageGCM(appData, recordKey)
|
|
480
|
+
let applicationAdd: Records.IApplicationAddRequest = {
|
|
481
|
+
appUid: platform.getRandomBytes(16),
|
|
482
|
+
recordKey: encryptedKey,
|
|
483
|
+
data: encryptedData,
|
|
484
|
+
clientModifiedTime: new Date().getTime()
|
|
485
|
+
}
|
|
486
|
+
await this.auth.executeRest(applicationAddMessage(applicationAdd))
|
|
487
|
+
return webSafe64FromBytes(applicationAdd.appUid)
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
async updateRecordV2(update: RecordUpdateV2): Promise<void> {
|
|
491
|
+
const record = this._records[update.record_uid]
|
|
492
|
+
|
|
493
|
+
const encryptedData = update.data
|
|
494
|
+
? await encryptObjectForStorage(update.data, record.key)
|
|
495
|
+
: undefined
|
|
496
|
+
|
|
497
|
+
const encryptedExtra = await encryptObjectForStorage(record.extra, record.key)
|
|
498
|
+
|
|
499
|
+
let nonSharedData = undefined
|
|
500
|
+
if (update.nonSharedData || update.nonSharedData === null) {
|
|
501
|
+
if (update.nonSharedData == null) {
|
|
502
|
+
nonSharedData = Uint8Array.of(0)
|
|
503
|
+
} else {
|
|
504
|
+
nonSharedData = encryptObjectForStorage(update.nonSharedData, this.auth.dataKey)
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
const updateCommand = new RecordUpdateCommand()
|
|
509
|
+
updateCommand.client_time = new Date().getTime()
|
|
510
|
+
updateCommand.update_records = [
|
|
511
|
+
{
|
|
512
|
+
record_uid: update.record_uid,
|
|
513
|
+
client_modified_time: new Date().getTime(),
|
|
514
|
+
data: encryptedData,
|
|
515
|
+
extra: encryptedExtra,
|
|
516
|
+
non_shared_data: nonSharedData,
|
|
517
|
+
revision: record.recordData.revision,
|
|
518
|
+
version: 2,
|
|
519
|
+
udata: update.udata,
|
|
520
|
+
}
|
|
521
|
+
]
|
|
522
|
+
|
|
523
|
+
const resp = await this.auth.executeCommand(updateCommand)
|
|
524
|
+
console.log(resp)
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
async updateRecord(update: RecordUpdate): Promise<Records.IRecordsModifyResponse> {
|
|
528
|
+
return this.updateRecords([update])
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
async updateRecords(updates: RecordUpdate[]): Promise<Records.IRecordsModifyResponse> {
|
|
532
|
+
|
|
533
|
+
const request: Records.IRecordsUpdateRequest = {
|
|
534
|
+
clientTime: new Date().getTime(),
|
|
535
|
+
records: []
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
for (const update of updates) {
|
|
539
|
+
const record = this._records[update.record_uid]
|
|
540
|
+
|
|
541
|
+
const encryptedData = update.data
|
|
542
|
+
? await encryptObjectForStorageGCM(update.data, record.key)
|
|
543
|
+
: undefined
|
|
544
|
+
|
|
545
|
+
let nonSharedData = undefined
|
|
546
|
+
if (update.nonSharedData || update.nonSharedData === null) {
|
|
547
|
+
if (update.nonSharedData == null) {
|
|
548
|
+
nonSharedData = Uint8Array.of(0)
|
|
549
|
+
} else {
|
|
550
|
+
nonSharedData = await encryptObjectForStorageGCM(update.nonSharedData, this.auth.dataKey, false)
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
let recordAudit: KeeperRecordAudit = undefined
|
|
555
|
+
if (update.audit) {
|
|
556
|
+
const pubKeyResponse = await this.auth.executeRest(getEnterprisePublicKeyMessage())
|
|
557
|
+
const auditBytes = platform.stringToBytes(JSON.stringify(update.audit.data));
|
|
558
|
+
const auditData = await platform.publicEncryptEC(auditBytes, pubKeyResponse.enterpriseECCPublicKey)
|
|
559
|
+
recordAudit = {
|
|
560
|
+
version: update.audit.version,
|
|
561
|
+
data: auditData
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
let addedLinks: Records.IRecordLink[] = undefined
|
|
566
|
+
if (update.add_links) {
|
|
567
|
+
addedLinks = []
|
|
568
|
+
for (const linkedRecord of update.add_links) {
|
|
569
|
+
const linkedRecordKey = await platform.aesGcmEncrypt(this._records[linkedRecord].key, record.key)
|
|
570
|
+
addedLinks.push({
|
|
571
|
+
recordUid: normal64Bytes(linkedRecord),
|
|
572
|
+
recordKey: linkedRecordKey
|
|
573
|
+
})
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
let removedLinks = update.remove_links
|
|
578
|
+
? update.remove_links.map(x => normal64Bytes(x))
|
|
579
|
+
: undefined
|
|
580
|
+
|
|
581
|
+
request.records.push({
|
|
582
|
+
recordUid: normal64Bytes(update.record_uid),
|
|
583
|
+
data: encryptedData,
|
|
584
|
+
nonSharedData: nonSharedData,
|
|
585
|
+
audit: recordAudit,
|
|
586
|
+
recordLinksAdd: addedLinks,
|
|
587
|
+
recordLinksRemove: removedLinks,
|
|
588
|
+
clientModifiedTime: new Date().getTime(),
|
|
589
|
+
revision: record.recordData.revision
|
|
590
|
+
})
|
|
591
|
+
console.log(`Updating record ${update.record_uid} revision ${record.recordData.revision}`)
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
const updateMsg = recordsUpdateMessage(request)
|
|
595
|
+
const response = await this.auth.executeRest(updateMsg)
|
|
596
|
+
const revision: number = response.revision as number
|
|
597
|
+
for (const record of response.records) {
|
|
598
|
+
this._records[webSafe64FromBytes(record.recordUid)].recordData.revision = revision
|
|
599
|
+
}
|
|
600
|
+
return response
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
async deleteRecords(recordUids: string[]): Promise<DeleteResponse> {
|
|
604
|
+
const preDeleteCommand = new PreDeleteCommand()
|
|
605
|
+
preDeleteCommand.objects = recordUids.map(x => {
|
|
606
|
+
return {
|
|
607
|
+
object_uid: x,
|
|
608
|
+
object_type: 'record',
|
|
609
|
+
from_type: 'user_folder',
|
|
610
|
+
delete_resolution: 'unlink'
|
|
611
|
+
}
|
|
612
|
+
})
|
|
613
|
+
const preDeleteResult = await this.auth.executeCommand(preDeleteCommand)
|
|
614
|
+
const deleteCommand = new DeleteCommand()
|
|
615
|
+
deleteCommand.pre_delete_token = preDeleteResult.pre_delete_response.pre_delete_token
|
|
616
|
+
return this.auth.executeCommand(deleteCommand)
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
async cleanTrash() {
|
|
620
|
+
await this.auth.executeCommand(new PurgeDeletedRecordsCommand())
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
async createSharedFolder(folderName: string): Promise<string> {
|
|
624
|
+
let folderKey = generateEncryptionKey()
|
|
625
|
+
let folderUid = generateUid()
|
|
626
|
+
|
|
627
|
+
const faCommand = new FolderAddCommand()
|
|
628
|
+
faCommand.name = await encryptForStorage(platform.stringToBytes(folderName), folderKey)
|
|
629
|
+
faCommand.folder_uid = folderUid
|
|
630
|
+
faCommand.folder_type = 'shared_folder'
|
|
631
|
+
faCommand.key = await encryptForStorage(folderKey, this.auth.dataKey)
|
|
632
|
+
faCommand.data = await encryptObjectForStorage({ name: folderName + '1', color: '#FF0000'}, folderKey)
|
|
633
|
+
const addFolderResponse = await this.auth.executeCommand(faCommand)
|
|
634
|
+
this._revision = addFolderResponse.revision
|
|
635
|
+
|
|
636
|
+
this._sharedFolders[folderUid] = {
|
|
637
|
+
key: folderKey
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
return folderUid
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
async addUserToSharedFolder(sharedFolderUid: string, user: string) {
|
|
644
|
+
const sharedFolder = this._sharedFolders[sharedFolderUid]
|
|
645
|
+
const userPublicKey = await this.fetchUserPublicKey(user)
|
|
646
|
+
|
|
647
|
+
const sfuCommand = new SharedFolderUpdateCommand()
|
|
648
|
+
sfuCommand.operation = 'update'
|
|
649
|
+
sfuCommand.name = await encryptForStorage(platform.stringToBytes('sftest2'), sharedFolder.key)
|
|
650
|
+
sfuCommand.shared_folder_uid = sharedFolderUid
|
|
651
|
+
sfuCommand.revision = this._revision
|
|
652
|
+
sfuCommand.add_users = [{
|
|
653
|
+
username: user,
|
|
654
|
+
manage_records: false,
|
|
655
|
+
manage_users: false,
|
|
656
|
+
shared_folder_key: shareKey(sharedFolder.key, userPublicKey)
|
|
657
|
+
}]
|
|
658
|
+
await this.auth.executeCommand(sfuCommand)
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
async deleteSharedFolders(sharedFolderUids: string[]) {
|
|
662
|
+
for (let sharedFolderUid of sharedFolderUids) {
|
|
663
|
+
const sfuCommand = new SharedFolderUpdateCommand()
|
|
664
|
+
sfuCommand.operation = 'delete'
|
|
665
|
+
sfuCommand.shared_folder_uid = sharedFolderUid
|
|
666
|
+
await this.auth.executeCommand(sfuCommand)
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// only can leave shared folders if not the owner
|
|
670
|
+
// {"command":"shared_folder_update","pt":"-n4s_eSHBZzOMRZQtX0gDg","operation":"update","shared_folder_uid":"PFe3TzKS6wq3YtXivxR6oA","revision":944012,
|
|
671
|
+
// "remove_users":[{"username":"saldoukhov@gmail.com"}],"locale":"en_US","username":"saldoukhov@gmail.com","session_token":"6X8lJLgDecS2IKTwErliMX0UKYkhznDWS59asu4kVeN3GMidq--T1kyBJ1YSJ9hxm67qsMkXeG5egEGaAQ_YjVc6CrhyFJovS4mOIZ3APLVdiylEroLQbsttCgkF","client_version":"w14.13.0"}
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
async fetchUserPublicKey(user: string): Promise<string> {
|
|
675
|
+
const publicKeysCommand = new PublicKeysCommand()
|
|
676
|
+
publicKeysCommand.key_owners = [user]
|
|
677
|
+
const publicKeys = await this.auth.executeCommand(publicKeysCommand)
|
|
678
|
+
if (!publicKeys.public_keys[0].public_key) {
|
|
679
|
+
throw new Error(publicKeys.public_keys[0].message)
|
|
680
|
+
}
|
|
681
|
+
return normal64(publicKeys.public_keys[0].public_key)
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
async fetchUserPublicKeyEC(user: string): Promise<Uint8Array> {
|
|
685
|
+
const publicKeysCommand = new PublicKeysCommand()
|
|
686
|
+
publicKeysCommand.key_owners = [user]
|
|
687
|
+
const publicKeys = await this.auth.executeCommand(publicKeysCommand)
|
|
688
|
+
if (!publicKeys.public_keys[0].public_key) {
|
|
689
|
+
throw new Error(publicKeys.public_keys[0].message)
|
|
690
|
+
}
|
|
691
|
+
return null
|
|
692
|
+
// return normal64(publicKeys.public_keys[0].public_key)
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
async shareRecords(recordUids: string[], share: RecordShare): Promise<RecordShareUpdateResponse> {
|
|
696
|
+
const userPublicKey = await this.fetchUserPublicKey(share.to_user)
|
|
697
|
+
|
|
698
|
+
const shareCommand = new RecordShareUpdateCommand()
|
|
699
|
+
let shareObjects: ShareObject[] = []
|
|
700
|
+
for (const recordUid of recordUids) {
|
|
701
|
+
const recordKey = shareKey(this._records[recordUid].key, userPublicKey)
|
|
702
|
+
const so: ShareObject = {
|
|
703
|
+
record_uid: recordUid,
|
|
704
|
+
record_key: recordKey,
|
|
705
|
+
to_username: share.to_user,
|
|
706
|
+
shareable: share.shareable,
|
|
707
|
+
editable: share.editable
|
|
708
|
+
}
|
|
709
|
+
shareObjects.push(so)
|
|
710
|
+
}
|
|
711
|
+
shareCommand.add_shares = shareObjects
|
|
712
|
+
return this.auth.executeCommand(shareCommand)
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
async shareRecordsEC(recordUids: string[], share: RecordShare): Promise<RecordShareUpdateResponse> {
|
|
716
|
+
const userPublicKey = await this.fetchUserPublicKeyEC(share.to_user)
|
|
717
|
+
|
|
718
|
+
const shareCommand = new RecordShareUpdateCommand()
|
|
719
|
+
let shareObjects: ShareObject[] = []
|
|
720
|
+
for (const recordUid of recordUids) {
|
|
721
|
+
const recordKey = await shareKeyEC(this._records[recordUid].key, userPublicKey)
|
|
722
|
+
const so: ShareObject = {
|
|
723
|
+
record_uid: recordUid,
|
|
724
|
+
record_key: recordKey,
|
|
725
|
+
to_username: share.to_user,
|
|
726
|
+
shareable: share.shareable,
|
|
727
|
+
editable: share.editable
|
|
728
|
+
}
|
|
729
|
+
shareObjects.push(so)
|
|
730
|
+
}
|
|
731
|
+
shareCommand.add_shares = shareObjects
|
|
732
|
+
return this.auth.executeCommand(shareCommand)
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
async uploadFileOld(fileName: string, fileData: Uint8Array, thumbnailData?: Uint8Array): Promise<ExtraFile> {
|
|
736
|
+
const uploadCommand = new RequestUploadCommand()
|
|
737
|
+
uploadCommand.file_count = 1
|
|
738
|
+
uploadCommand.thumbnail_count = thumbnailData ? 1 : 0
|
|
739
|
+
const resp = await this.auth.executeCommand(uploadCommand)
|
|
740
|
+
const uploadInfo = resp.file_uploads[0]
|
|
741
|
+
console.log(uploadInfo)
|
|
742
|
+
const fileKey = generateEncryptionKey()
|
|
743
|
+
// const encryptedFile = await platform.aesGcmEncrypt(fileData, fileKey)
|
|
744
|
+
const encryptedFile = await platform.aesCbcEncrypt(fileData, fileKey, true)
|
|
745
|
+
const res = await platform.fileUpload(uploadInfo.url, uploadInfo.parameters, encryptedFile)
|
|
746
|
+
if (res.statusCode !== uploadInfo.success_status_code) {
|
|
747
|
+
throw new Error(`Upload failed (${res.statusMessage}), code ${res.statusCode}`)
|
|
748
|
+
}
|
|
749
|
+
return {
|
|
750
|
+
id: uploadInfo.file_id,
|
|
751
|
+
name: fileName,
|
|
752
|
+
title: fileName,
|
|
753
|
+
key: webSafe64FromBytes(fileKey),
|
|
754
|
+
lastModified: new Date().getTime(),
|
|
755
|
+
size: encryptedFile.length,
|
|
756
|
+
type: '',
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
export interface VaultRecord {
|
|
762
|
+
recordData?: RecordData
|
|
763
|
+
metaData?: RecordMetaData;
|
|
764
|
+
key?: Uint8Array
|
|
765
|
+
|
|
766
|
+
data?: KeeperRecordData
|
|
767
|
+
extra?: KeeperRecordExtra
|
|
768
|
+
sharedFolderUid?: string;
|
|
769
|
+
sharedFolderFolderUid?: string;
|
|
770
|
+
nonSharedData?: any;
|
|
771
|
+
audit?: KeeperRecordAudit;
|
|
772
|
+
links?: string[]
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
export interface VaultSharedFolder {
|
|
776
|
+
sharedFolder?: SharedFolder
|
|
777
|
+
key?: Uint8Array
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
export interface KeeperRecordData {
|
|
781
|
+
title?: string;
|
|
782
|
+
secret1?: string;
|
|
783
|
+
secret2?: string;
|
|
784
|
+
link?: string;
|
|
785
|
+
notes?: string;
|
|
786
|
+
custom?: {name?: string, value?: string}[];
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
export interface KeeperRecordExtra {
|
|
790
|
+
fields: ExtraField[]
|
|
791
|
+
files: ExtraFile[]
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
export interface KeeperRecordAudit {
|
|
795
|
+
version: number
|
|
796
|
+
data: any
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
export interface RecordShare {
|
|
800
|
+
to_user: string;
|
|
801
|
+
shareable: boolean;
|
|
802
|
+
editable: boolean;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
export interface RecordUpdateV2 {
|
|
806
|
+
record_uid: string
|
|
807
|
+
data?: KeeperRecordData
|
|
808
|
+
nonSharedData?: any
|
|
809
|
+
udata?: { file_ids: string[] }
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
export interface RecordUpdate {
|
|
813
|
+
record_uid: string;
|
|
814
|
+
data?: KeeperRecordData
|
|
815
|
+
nonSharedData?: any;
|
|
816
|
+
audit?: KeeperRecordAudit;
|
|
817
|
+
add_links?: string[]
|
|
818
|
+
remove_links?: string[]
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
export interface ExtraField {
|
|
822
|
+
id: string
|
|
823
|
+
field_type: 'totp'
|
|
824
|
+
field_title: string
|
|
825
|
+
type: number
|
|
826
|
+
data: string
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
export interface ExtraFile {
|
|
830
|
+
id: string
|
|
831
|
+
name?: string
|
|
832
|
+
lastModified?: number
|
|
833
|
+
size?: number
|
|
834
|
+
type?: string
|
|
835
|
+
title?: string
|
|
836
|
+
key?: string
|
|
837
|
+
thumbs?: FileThumb[]
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
export interface FileThumb {
|
|
841
|
+
id: string
|
|
842
|
+
size: number
|
|
843
|
+
type: 'image/jpg'
|
|
844
|
+
}
|