diff --git a/src/secrets/src/keyring/Cargo.lock b/src/secrets/src/core/Cargo.lock similarity index 63% rename from src/secrets/src/keyring/Cargo.lock rename to src/secrets/src/core/Cargo.lock index ca9f2a10..fa08d203 100644 --- a/src/secrets/src/keyring/Cargo.lock +++ b/src/secrets/src/core/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aho-corasick" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" -dependencies = [ - "memchr", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -19,15 +10,15 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "cfg-expr" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9" +checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3" dependencies = [ "smallvec", "target-lexicon", @@ -39,15 +30,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -64,16 +46,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "ctor" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f34ba9a9bcb8645379e9de8cb3ecfcf4d1c85ba66d90deb3259206fa5aa193b" -dependencies = [ - "quote", - "syn 2.0.28", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -82,24 +54,24 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" dependencies = [ "futures-core", "futures-task", @@ -108,32 +80,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.38", ] [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-core", "futures-macro", @@ -209,7 +181,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.38", ] [[package]] @@ -235,9 +207,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "heck" @@ -247,48 +219,19 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "indexmap" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", "hashbrown", ] -[[package]] -name = "keyring" -version = "1.0.0" -dependencies = [ - "cfg-if", - "core-foundation", - "core-foundation-sys", - "gio", - "glib", - "glib-sys", - "libsecret", - "libsecret-sys", - "napi", - "napi-build", - "napi-derive", - "thiserror", - "windows-sys", -] - [[package]] name = "libc" -version = "0.2.147" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libsecret" @@ -318,66 +261,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "napi" -version = "2.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ede2d12cd6fce44da537a4be1f5510c73be2506c2e32dfaaafd1f36968f3a0e" -dependencies = [ - "bitflags", - "ctor", - "napi-derive", - "napi-sys", - "once_cell", -] - -[[package]] -name = "napi-build" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882a73d9ef23e8dc2ebbffb6a6ae2ef467c0f18ac10711e4cc59c5485d41df0e" - -[[package]] -name = "napi-derive" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1c6a8fa84d549aa8708fcd062372bf8ec6e849de39016ab921067d21bde367" -dependencies = [ - "cfg-if", - "convert_case", - "napi-derive-backend", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "napi-derive-backend" -version = "1.0.52" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20bbc7c69168d06a848f925ec5f0e0997f98e8c8d4f2cc30157f0da51c009e17" -dependencies = [ - "convert_case", - "once_cell", - "proc-macro2", - "quote", - "regex", - "semver", - "syn 1.0.109", -] - -[[package]] -name = "napi-sys" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "166b5ef52a3ab5575047a9fe8d4a030cdd0f63c96f071cd6907674453b07bae3" -dependencies = [ - "libloading", -] +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "once_cell" @@ -387,9 +273,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -410,7 +296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] @@ -439,86 +325,81 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] -name = "regex" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +name = "secrets_core" +version = "0.1.0" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "cfg-if", + "core-foundation", + "core-foundation-sys", + "gio", + "glib", + "glib-sys", + "libsecret", + "libsecret-sys", + "thiserror", + "windows-sys", ] [[package]] -name = "regex-automata" -version = "0.3.4" +name = "serde" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "serde_derive", ] [[package]] -name = "regex-syntax" -version = "0.7.4" +name = "serde_derive" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" - -[[package]] -name = "semver" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" - -[[package]] -name = "serde" -version = "1.0.179" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5bf42b8d227d4abf38a1ddb08602e229108a517cd4e5bb28f9c7eaafdce5c0" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" dependencies = [ "serde", ] [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "syn" @@ -527,15 +408,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", - "quote", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.28" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -544,9 +424,9 @@ dependencies = [ [[package]] name = "system-deps" -version = "6.1.1" +version = "6.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" +checksum = "94af52f9402f94aac4948a2518b43359be8d9ce6cd9efc1c4de3b2f7b7e897d6" dependencies = [ "cfg-expr", "heck", @@ -557,75 +437,80 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.10" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.38", ] [[package]] name = "toml" -version = "0.7.6" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "8ff9e3abce27ee2c9a37f9ad37238c1bdd4e789c84ba37df76aa4d528f5072cc" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.20.7", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", - "serde", - "serde_spanned", "toml_datetime", "winnow", ] [[package]] -name = "unicode-ident" -version = "1.0.11" +name = "toml_edit" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] [[package]] -name = "unicode-segmentation" -version = "1.10.1" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "version-compare" @@ -672,9 +557,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -687,51 +572,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.5.2" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7" +checksum = "a3b801d0e0a6726477cc207f60162da452f3a95adb368399bef20a946e06f65c" dependencies = [ "memchr", ] diff --git a/src/secrets/src/keyring/Cargo.toml b/src/secrets/src/core/Cargo.toml similarity index 53% rename from src/secrets/src/keyring/Cargo.toml rename to src/secrets/src/core/Cargo.toml index e3e3ab56..b178909c 100644 --- a/src/secrets/src/keyring/Cargo.toml +++ b/src/secrets/src/core/Cargo.toml @@ -1,20 +1,12 @@ [package] +name = "secrets_core" +version = "0.1.0" edition = "2021" -name = "keyring" -version = "1.0.0" -authors = ["Zowe Project"] -license = "EPL-2.0" -repository = "https://github.com/zowe/zowe-cli" -[lib] -name = "keyring" -crate-type = ["cdylib"] +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cfg-if = "1.0" -# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix -napi = { version = "2", default-features = false, features = ["napi4"] } -napi-derive = "2" thiserror = "1.0.38" [target.'cfg(target_os = "windows")'.dependencies.windows-sys] @@ -36,12 +28,4 @@ glib = "0.18.2" glib-sys = "0.18.1" gio = "0.18.2" libsecret = "0.4.0" -libsecret-sys = "0.4.0" - -[build-dependencies] -napi-build = "2" - -[profile.release] -lto = true -opt-level = "z" # Optimize for size. -strip = "symbols" +libsecret-sys = "0.4.0" \ No newline at end of file diff --git a/src/secrets/src/core/src/lib.rs b/src/secrets/src/core/src/lib.rs new file mode 100644 index 00000000..dda20c34 --- /dev/null +++ b/src/secrets/src/core/src/lib.rs @@ -0,0 +1 @@ +pub mod os; \ No newline at end of file diff --git a/src/secrets/src/keyring/src/os/error.rs b/src/secrets/src/core/src/os/error.rs similarity index 100% rename from src/secrets/src/keyring/src/os/error.rs rename to src/secrets/src/core/src/os/error.rs diff --git a/src/secrets/src/keyring/src/os/mac/error.rs b/src/secrets/src/core/src/os/mac/error.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mac/error.rs rename to src/secrets/src/core/src/os/mac/error.rs diff --git a/src/secrets/src/keyring/src/os/mac/ffi.rs b/src/secrets/src/core/src/os/mac/ffi.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mac/ffi.rs rename to src/secrets/src/core/src/os/mac/ffi.rs diff --git a/src/secrets/src/keyring/src/os/mac/keychain.rs b/src/secrets/src/core/src/os/mac/keychain.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mac/keychain.rs rename to src/secrets/src/core/src/os/mac/keychain.rs diff --git a/src/secrets/src/keyring/src/os/mac/keychain_item.rs b/src/secrets/src/core/src/os/mac/keychain_item.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mac/keychain_item.rs rename to src/secrets/src/core/src/os/mac/keychain_item.rs diff --git a/src/secrets/src/keyring/src/os/mac/keychain_search.rs b/src/secrets/src/core/src/os/mac/keychain_search.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mac/keychain_search.rs rename to src/secrets/src/core/src/os/mac/keychain_search.rs diff --git a/src/secrets/src/keyring/src/os/mac/misc.rs b/src/secrets/src/core/src/os/mac/misc.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mac/misc.rs rename to src/secrets/src/core/src/os/mac/misc.rs diff --git a/src/secrets/src/keyring/src/os/mac/mod.rs b/src/secrets/src/core/src/os/mac/mod.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mac/mod.rs rename to src/secrets/src/core/src/os/mac/mod.rs diff --git a/src/secrets/src/keyring/src/os/mod.rs b/src/secrets/src/core/src/os/mod.rs similarity index 100% rename from src/secrets/src/keyring/src/os/mod.rs rename to src/secrets/src/core/src/os/mod.rs diff --git a/src/secrets/src/keyring/src/os/unix.rs b/src/secrets/src/core/src/os/unix.rs similarity index 100% rename from src/secrets/src/keyring/src/os/unix.rs rename to src/secrets/src/core/src/os/unix.rs diff --git a/src/secrets/src/keyring/src/os/win.rs b/src/secrets/src/core/src/os/win.rs similarity index 98% rename from src/secrets/src/keyring/src/os/win.rs rename to src/secrets/src/core/src/os/win.rs index a0d2742d..a66b03ab 100644 --- a/src/secrets/src/keyring/src/os/win.rs +++ b/src/secrets/src/core/src/os/win.rs @@ -22,10 +22,10 @@ impl From for KeyringError { /// /// Helper function to convert the last Win32 error into a human-readable error message. -/// -/// Returns: +/// +/// Returns: /// A `String` object containing the error message -/// +/// fn win32_error_as_string(error: WIN32_ERROR) -> String { let buffer: PWSTR = std::ptr::null_mut(); @@ -62,22 +62,22 @@ fn win32_error_as_string(error: WIN32_ERROR) -> String { /// /// Helper function to encode a string as a null-terminated UTF-16 string for use w/ credential APIs. -/// +/// /// Returns: /// - `Some(val)` if the string was successfully converted to UTF-16, or `None` otherwise. -/// +/// fn encode_utf16(str: &str) -> Vec { let mut chars: Vec = str.encode_utf16().collect(); chars.push(0); chars } -/// +/// /// Attempts to set a password for a given service and account. -/// +/// /// - `service`: The service name for the new credential /// - `account`: The account name for the new credential -/// +/// /// Returns: /// - `true` if the credential was stored successfully /// - A `KeyringError` if there were any issues interacting with the credential vault @@ -85,7 +85,7 @@ fn encode_utf16(str: &str) -> Vec { pub fn set_password( service: &String, account: &String, - password: &mut String, + password: &String, ) -> Result { // Build WinAPI strings and object parameters from arguments let target_bytes = encode_utf16(format!("{}/{}", service, account).as_str()); @@ -120,16 +120,16 @@ pub fn set_password( Ok(true) } -/// +/// /// Returns a password contained in the given service and account, if found. -/// +/// /// - `service`: The service name that matches the credential of interest /// - `account`: The account name that matches the credential of interest -/// +/// /// Returns: /// - `Some(password)` if a matching credential was found; `None` otherwise /// - A `KeyringError` if there were any issues interacting with the credential vault -/// +/// pub fn get_password(service: &String, account: &String) -> Result, KeyringError> { let mut cred: *mut CREDENTIALW = std::ptr::null_mut::(); let target_name = encode_utf16(format!("{}/{}", service, account).as_str()); @@ -173,16 +173,16 @@ pub fn get_password(service: &String, account: &String) -> Result } } -/// +/// /// Attempts to delete the password associated with a given service and account. -/// +/// /// - `service`: The service name of the credential to delete /// - `account`: The account name of the credential to delete -/// +/// /// Returns: /// - `true` if a matching credential was deleted; `false` otherwise /// - A `KeyringError` if there were any issues interacting with the credential vault -/// +/// pub fn delete_password(service: &String, account: &String) -> Result { let target_name = encode_utf16(format!("{}/{}", service, account).as_str()); @@ -204,15 +204,15 @@ pub fn delete_password(service: &String, account: &String) -> Result Result, KeyringError> { let filter = encode_utf16(format!("{}*", service).as_str()); @@ -257,16 +257,16 @@ pub fn find_password(service: &String) -> Result, KeyringError> { } } -/// +/// /// Builds a vector of all credentials matching the given service pattern. -/// +/// /// - `service`: The service pattern that matches the credential(s) of interest -/// - `credentials`: The vector consisting of (username, password) pairs for each credential that matches -/// +/// - `credentials`: The vector consisting of (username, password) pairs for each credential that matches +/// /// Returns: /// - `true` if at least 1 credential was found, `false` otherwise /// - A `KeyringError` if there were any issues interacting with the credential vault -/// +/// pub fn find_credentials( service: &String, credentials: &mut Vec<(String, String)>, diff --git a/src/secrets/src/keyring-test/Cargo.lock b/src/secrets/src/keyring-test/Cargo.lock index 2d2672ed..482d67cc 100644 --- a/src/secrets/src/keyring-test/Cargo.lock +++ b/src/secrets/src/keyring-test/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "aho-corasick" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" -dependencies = [ - "memchr", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -45,15 +36,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "convert_case" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -70,16 +52,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "ctor" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583" -dependencies = [ - "quote", - "syn 2.0.38", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -267,31 +239,12 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" -[[package]] -name = "keyring" -version = "1.0.0" -dependencies = [ - "cfg-if", - "core-foundation", - "core-foundation-sys", - "gio", - "glib", - "glib-sys", - "libsecret", - "libsecret-sys", - "napi", - "napi-build", - "napi-derive", - "thiserror", - "windows-sys", -] - [[package]] name = "keyring-test" version = "0.1.0" dependencies = [ - "keyring", "pyo3", + "secrets_core", ] [[package]] @@ -300,16 +253,6 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libsecret" version = "0.4.0" @@ -361,63 +304,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "napi" -version = "2.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd063c93b900149304e3ba96ce5bf210cd4f81ef5eb80ded0d100df3e85a3ac0" -dependencies = [ - "bitflags 2.4.1", - "ctor", - "napi-derive", - "napi-sys", - "once_cell", -] - -[[package]] -name = "napi-build" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882a73d9ef23e8dc2ebbffb6a6ae2ef467c0f18ac10711e4cc59c5485d41df0e" - -[[package]] -name = "napi-derive" -version = "2.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1c6a8fa84d549aa8708fcd062372bf8ec6e849de39016ab921067d21bde367" -dependencies = [ - "cfg-if", - "convert_case", - "napi-derive-backend", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "napi-derive-backend" -version = "1.0.52" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20bbc7c69168d06a848f925ec5f0e0997f98e8c8d4f2cc30157f0da51c009e17" -dependencies = [ - "convert_case", - "once_cell", - "proc-macro2", - "quote", - "regex", - "semver", - "syn 1.0.109", -] - -[[package]] -name = "napi-sys" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "166b5ef52a3ab5575047a9fe8d4a030cdd0f63c96f071cd6907674453b07bae3" -dependencies = [ - "libloading", -] - [[package]] name = "once_cell" version = "1.18.0" @@ -586,35 +472,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "regex" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" - [[package]] name = "scopeguard" version = "1.2.0" @@ -622,10 +479,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "semver" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +name = "secrets_core" +version = "0.1.0" +dependencies = [ + "cfg-if", + "core-foundation", + "core-foundation-sys", + "gio", + "glib", + "glib-sys", + "libsecret", + "libsecret-sys", + "thiserror", + "windows-sys", +] [[package]] name = "serde" @@ -783,12 +650,6 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" -[[package]] -name = "unicode-segmentation" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" - [[package]] name = "unindent" version = "0.1.11" diff --git a/src/secrets/src/keyring-test/Cargo.toml b/src/secrets/src/keyring-test/Cargo.toml index 65bbe461..bfb2b113 100644 --- a/src/secrets/src/keyring-test/Cargo.toml +++ b/src/secrets/src/keyring-test/Cargo.toml @@ -10,4 +10,4 @@ crate-type = ["cdylib"] [dependencies] pyo3 = "0.19.0" -keyring = { path = "../keyring" } +secrets_core = { path = "../core" } diff --git a/src/secrets/src/keyring-test/src/lib.rs b/src/secrets/src/keyring-test/src/lib.rs index 858ab70d..b2b7c846 100644 --- a/src/secrets/src/keyring-test/src/lib.rs +++ b/src/secrets/src/keyring-test/src/lib.rs @@ -1,56 +1,60 @@ +use pyo3::exceptions::PyValueError; use pyo3::prelude::*; -extern crate keyring; -use keyring::os::*; +extern crate secrets_core; +use secrets_core::*; #[pyfunction] -fn py_set_password(service: &str, account: &str, password: &str) -> PyResult<()> { - match set_password(service, account, password) { +fn set_password(service: String, account: String, password: String) -> PyResult<()> { + match os::set_password(&service, &account, &password) { Ok(_) => Ok(()), - Err(e) => Err(e), + Err(e) => Err(PyValueError::new_err("error in set_password")), } } #[pyfunction] -fn py_get_password(service: &str, account: &str) -> PyResult { - match get_password(service, account) { - Ok(_) => Ok(()), - Err(e) => Err(e), +fn get_password(service: String, account: String) -> PyResult { + match os::get_password(&service, &account) { + Ok(pw) => Ok(pw.unwrap_or("".to_string())), + Err(e) => Err(PyValueError::new_err("error in get_password")), } } #[pyfunction] -fn py_delete_password(service: &str, account: &str) -> PyResult { - match delete_password(service, account) { +fn delete_password(service: String, account: String) -> PyResult { + match os::delete_password(&service, &account) { Ok(res) => Ok(res), - Err(e) => Err(e), + Err(e) => Err(PyValueError::new_err("error in delete_password")), } } #[pyfunction] -fn py_find_password(service: &str) -> PyResult { - match find_password(service) { - Ok(res) => Ok(res), - Err(e) => Err(e), +fn find_password(service: String) -> PyResult { + match os::find_password(&service) { + Ok(res) => match res { + Some(val) => Ok(val), + _ => Ok("".to_owned()), + }, + Err(e) => Err(PyValueError::new_err("error in find_password")), } } #[pyfunction] -fn py_find_credentials(service: &str) -> PyResult> { +fn find_credentials(service: String) -> PyResult> { let mut creds: Vec<(String, String)> = vec![]; - match find_credentials(service, &mut creds) { + match os::find_credentials(&service, &mut creds) { Ok(res) => Ok(creds), - Err(e) => Err(e), + Err(e) => Err(PyValueError::new_err("error in find_credentials")), } } /// A Python module implemented in Rust. #[pymodule] fn keyring_test(_py: Python, m: &PyModule) -> PyResult<()> { - m.add_function(wrap_pyfunction!(py_get_password, m)?)?; - m.add_function(wrap_pyfunction!(py_set_password, m)?)?; - m.add_function(wrap_pyfunction!(py_delete_password, m)?)?; - m.add_function(wrap_pyfunction!(py_find_password, m)?)?; - m.add_function(wrap_pyfunction!(py_find_credentials, m)?)?; + m.add_function(wrap_pyfunction!(get_password, m)?)?; + m.add_function(wrap_pyfunction!(set_password, m)?)?; + m.add_function(wrap_pyfunction!(delete_password, m)?)?; + m.add_function(wrap_pyfunction!(find_password, m)?)?; + m.add_function(wrap_pyfunction!(find_credentials, m)?)?; Ok(()) } diff --git a/src/secrets/src/keyring/.cargo/config.toml b/src/secrets/src/keyring/.cargo/config.toml deleted file mode 100644 index d6d7ccc3..00000000 --- a/src/secrets/src/keyring/.cargo/config.toml +++ /dev/null @@ -1,2 +0,0 @@ -[target.'cfg(all(windows, target_env = "msvc"))'] -rustflags = ["-Ctarget-feature=+crt-static"] \ No newline at end of file diff --git a/src/secrets/src/keyring/.npmignore b/src/secrets/src/keyring/.npmignore deleted file mode 100644 index d0560b0c..00000000 --- a/src/secrets/src/keyring/.npmignore +++ /dev/null @@ -1,13 +0,0 @@ -target -Cross.toml -.cargo -.github -npm -.eslintrc -.prettierignore -rustfmt.toml -yarn.lock -*.node -.yarn -__test__ -renovate.json diff --git a/src/secrets/src/keyring/Cross.toml b/src/secrets/src/keyring/Cross.toml deleted file mode 100644 index 106f07ec..00000000 --- a/src/secrets/src/keyring/Cross.toml +++ /dev/null @@ -1,37 +0,0 @@ -[build] -pre-build = [ - "dpkg --add-architecture $CROSS_DEB_ARCH", - "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y libsecret-1-dev:$CROSS_DEB_ARCH", -] - -[build.env] -passthrough = [ - "PKG_CONFIG_SYSROOT_DIR", - "PKG_CONFIG_PATH", - "RUSTFLAGS" -] - -[target.aarch64-unknown-linux-gnu] -image = "ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main" - -[target.aarch64-unknown-linux-musl] -image = "rust:alpine" -pre-build = [ - "wget -qO- https://musl.cc/aarch64-linux-musl-cross.tgz | tar -xzC / && export PATH=\"/aarch64-linux-musl-cross/bin:$PATH\"", - "apk add --no-cache musl-dev pkgconfig", - "apk add -p /aarch64-linux-musl-cross --initdb --arch aarch64 --allow-untrusted -X \"https://dl-cdn.alpinelinux.org/alpine/latest-stable/main/\" --no-cache --no-scripts libsecret-dev", - "rustup target add aarch64-unknown-linux-musl" -] - -[target.armv7-unknown-linux-gnueabihf] -image = "ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:main" - -[target.i686-unknown-linux-gnu] -image = "ghcr.io/cross-rs/i686-unknown-linux-gnu:main" - -[target.x86_64-unknown-linux-gnu] -image = "ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main" - -[target.x86_64-unknown-linux-musl] -image = "rust:alpine" -pre-build = ["apk add libsecret-dev musl-dev"] diff --git a/src/secrets/src/keyring/EXTENDERS.md b/src/secrets/src/keyring/EXTENDERS.md deleted file mode 100644 index d2f55110..00000000 --- a/src/secrets/src/keyring/EXTENDERS.md +++ /dev/null @@ -1,140 +0,0 @@ -# Usage (Extenders) - -## What is `keyring`? - -`keyring` is a cross-platform module meant to interact with OS (operating system) credential storage. `keyring` is written in Rust, and uses other Rust libraries to interface with credential storage APIs (application programming interfaces). - -## Why switch to `keyring`? - -As `node-keytar` is now unmaintained, there was a demand for a replacement that can function identically to the original module. - -As `keyring` was modeled after `node-keytar`, the same operations can be performed in credential storage: - -- Storing credentials -- Retrieving credentials -- Searching for passwords based on a matching label -- Searching for matching credentials based on a prefix/query -- Deleting credentials - -**Currently, there are no breaking changes** between the use of `node-keytar` and `keyring`. This is intended by design. - -From a developer's perspective, one can simply update existing extenders or plug-ins to import the keyring module from `@zowe/secrets-for-zowe-sdk` instead of `node-keytar`, allowing for a straightforward transition. All functions previously exported in `node-keytar` will be available in `keyring`. Simply add `@zowe/secrets-for-zowe-sdk` to your project using `npm` or `yarn`. - -Importing a function from `keyring` is identical to the `node-keytar` import process: - -```ts -// Import all functions under a namespace... -import { keyring } from "@zowe/secrets-for-zowe-sdk"; -// Or, use require to import the keyring module. -const { keyring } = require("@zowe/secrets-for-zowe-sdk"); -``` - -After the desired functions are imported, feel free to use them in the same fashion as the `node-keytar` functions. For the examples below, `async/await` keywords are used, but the functions can also be used with `.then/.catch` promise blocks: - -```ts -getPassword("TestService", "AccountA") -.then((pw) => { - console.log("The password for TestService/AccountA is:", pw); -}) -.catch((err) => { - console.error("An error occurred!", err.message); -}); -``` - -**Examples:** - -```ts -// Set a password with a given service and account name -// Password will be stored under / -await keyring.setPassword("TestService", "AccountA", "Apassword"); - -// Get a password, given a service and account name -await keyring.getPassword("TestService", "AccountA"); - -// Find credentials based on a matching label -await keyring.findCredentials("TestService"); - -// Find password that matches a service and account -await keyring.findPassword("TestService/AccountA"); - -// Delete a credential w/ the provided service and account name -await keyring.deletePassword("TestService", "AccountA"); -``` - -## Webpacking/bundling alongside your project - -Some projects leverage a JavaScript bundler, such as Webpack or Vite, to minify and compress their Node.js packages. -While the Secrets SDK does support Webpack, developers who want to bundle the Secrets SDK alongside their package should set up a `prebuilds` folder alongside their package root. - -For example, if your package places build output in the `out` folder, your directory structure should look like this: - -``` -your-pkg/ -├── package.json -├── src/ -├── out/ -│ └── bundle.js -├── prebuilds/ -│ └── (node binaries for Secrets SDK) -``` - -If you are using ESbuild or Webpack, consider using a copy plugin to copy the `prebuilds` folder from the Secrets SDK *node_modules* folder: -- ESbuild: [esbuild-copy-static-files](https://www.npmjs.com/package/esbuild-copy-static-files) -- Webpack: [copy-webpack-plugin](https://www.npmjs.com/package/copy-webpack-plugin) - -Otherwise, use the Node.js script below (**requires Node 16.7.0 and above**). It creates a copy of the `prebuilds` folder containing the required Secrets SDK binaries. Run this script in the same directory as your extension's `package.json`: - -```js -const { cpSync } = require("fs"); -cpSync("/path/to/node_modules/@zowe/secrets-for-zowe-sdk/prebuilds", "prebuilds", {force: true, recursive: true}); -``` -**Note:** The first argument for `cpSync` will vary, depending on where the *node_modules* folder is located in your environment. - -We recommend that developers add this logic to a `prepare` script in their `package.json` to guarantee the binaries are up-to-date after installing dependencies. -Save the above script as a JavaScript file (e.g., `scripts/copyKeyringBinaries.js`), and execute the script: - -```js -{ - "scripts": { - "prepare": "node scripts/copyKeyringBinaries.js" - } -} -``` - -If you are bundling a VSCode extension, and are using a `.vscodeignore` file, you must allow the prebuilds folder to be packaged in the VSIX. -Add the following line to your `.vscodeignore` file: -``` -!prebuilds/** -``` - -### Updating imports - -Some extenders might import `keytar` directly as a dependency. In these cases, extenders should import the `keyring` module from this package instead. - -**Take caution when importing** as the import process is slightly different than `node-keytar`: - -Before: -```js -const keytar = require("node-keytar"); -// ES6 import: -import * as keytar from "node-keytar"; -``` - -After: -```js -const { keyring } = require("@zowe/secrets-for-zowe-sdk"); -// ES6 import: -import { keyring } from "@zowe/secrets-for-zowe-sdk"; -``` - -Notice that the keyring module must be accessed from the dependency imports before use. -To reduce the amount of code that needs updated, users can use an import alias to the phrase "keytar": - -```js -const { keyring: keytar } = require("@zowe/secrets-for-zowe-sdk"); -// ES6 import: -import { keyring as keytar } from "@zowe/secrets-for-zowe-sdk"; - -// Existing code, such as the example below, can remain unchanged with this import alias: -keytar.setPassword("Hello", "World", "ExamplePassword"); -``` \ No newline at end of file diff --git a/src/secrets/src/keyring/README.md b/src/secrets/src/keyring/README.md deleted file mode 100644 index 3a61337c..00000000 --- a/src/secrets/src/keyring/README.md +++ /dev/null @@ -1,177 +0,0 @@ -# keyring - -keyring is a native Node.js module for accessing and managing OS credential storage. - -## Compatibility - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OS / ArchitectureNode.js Version
v12v14v16v18
Windowsx64
x86
arm64
macOSx64
aarch64
Linux (gnu)x64
x86
aarch64
armv7l (gnueabihf)
Linux (musl)x64
aarch64
- -## Features - -keyring supports the following operations within credential storage: - -- [x] **Set** a credential -- [x] **Retrieve** a credential -- [x] **Find all credentials** with matching attributes -- [x] **Find a password** with matching attributes - -Some benefits to using keyring: - -- [x] **Cross-platform support** makes for straight-forward secrets management -- [x] **Existing OS credentials are supported** out-of-the-box -- [x] **Avoids memory allocation** - memory only allocated as needed for OS-specific APIs - -## Node API documentation - -### deletePassword - -Deletes a password with matching `service` and `account` parameters. - -**Returns:** Whether the password was deleted successfully. - -```ts -function deletePassword(service: string, account: string) -> Promise -``` - -### findCredentials - -Finds all credentials with a matching `service` parameter. - -**Returns:** An array of `Credential` objects, containing the `account` and `password` for each credential that is found within `service`. - -```ts -interface Credential { - account: string; - password: string; -}; - -function findCredentials(service: string) -> Promise> -``` - -### findPassword - -Finds a password with a matching `service` and `account` parameter. - -**Returns:** The first password found in `/`, or `null` if not found. - -```ts -function findPassword(service: string, account: string) -> Promise -``` - -### getPassword - -Gets a password with a matching `service` and `account` parameter. - -**Returns:** The password stored under `/`, or `null` if not found. - -```ts -function getPassword(service: string, account: string) -> Promise -``` - -### setPassword - -Stores a password with the given `service`, `account`, and `password`. - -```ts -function setPassword(service: string, account: string, password: string) -> Promise -``` diff --git a/src/secrets/src/keyring/__test__/index.spec.mjs b/src/secrets/src/keyring/__test__/index.spec.mjs deleted file mode 100644 index 6ca2cd4c..00000000 --- a/src/secrets/src/keyring/__test__/index.spec.mjs +++ /dev/null @@ -1,312 +0,0 @@ -import test from "ava"; -import { - deletePassword, - findCredentials, - findPassword, - getPassword, - setPassword, -} from "../index.js"; - -// generate a number in range [min, max) -const randomInt = (min, max) => { - return Math.floor(Math.random() * (max - min)) + min; -}; - -// generate random ASCII string of length "len" -// (could use constants instead, but this should better emulate real-world scenarios) -const randomAsciiString = (len) => { - let str = ""; - for (let i = 0; i < len; i++) { - str = str.concat(String.fromCharCode(randomInt(97, 123))); - } - return str; -}; - -const TEST_CREDENTIALS = [ - { service: "TestKeyring", account: "TestASCII" }, - { service: "TestKeyring", account: "TestUTF8" }, - { service: "TestKeyring", account: "TestCharSet" }, - { service: "TestKeyring", account: "TestUTF16" }, - { service: "TestKeyring", account: "TestCJK" }, - { service: "TestKeyring", account: "TestBinary" }, - { service: "TestEmptyAccount", account: "" }, - { service: "", account: "TestEmptyService" }, - { service: "TestKeyring", account: "PwNullTerm" }, -]; - -test.serial("get/setPassword with binary data", async (t) => { - const binaryGroups = - "01001000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100 00100001".match( - /[01]{8}/g - ); - const parsed = binaryGroups.map((binary) => parseInt(binary, 2)); - const buffer = Buffer.from(new Uint8Array(parsed).buffer); - - await setPassword("TestKeyring", "TestBinary", buffer.toString()); - const res = await getPassword("TestKeyring", "TestBinary"); - t.is(res, buffer.toString()); -}); - -test.serial("get/setPassword with empty string parameters", async (t) => { - // Empty "account" parameter - await setPassword("TestEmptyAccount", "", "emptyAccountPW"); - const accountRes = await getPassword("TestEmptyAccount", ""); - t.is(accountRes, "emptyAccountPW"); - - // Empty "service" parameter - await setPassword("", "TestEmptyService", "emptyServicePW"); - const serviceRes = await getPassword("", "TestEmptyService"); - t.is(serviceRes, "emptyServicePW"); -}); - -test.serial("get/setPassword with ASCII string", async (t) => { - await setPassword("TestKeyring", "TestASCII", "ASCII string"); - - const str = await getPassword("TestKeyring", "TestASCII"); - t.is(str, "ASCII string"); -}); - -test.serial("get/setPassword with mixed character set", async (t) => { - await setPassword("TestKeyring", "TestCharSet", "I 💔 ASCII"); - - const str = await getPassword("TestKeyring", "TestCharSet"); - t.is(str, "I 💔 ASCII"); -}); - -test.serial("get/setPassword with UTF-16 chars", async (t) => { - await setPassword("TestKeyring", "TestUTF16", "🌞🌙🌟🌴"); - - const str = await getPassword("TestKeyring", "TestUTF16"); - t.is(str, "🌞🌙🌟🌴"); -}); - -test.serial("get/setPassword with UTF-8 chars", async (t) => { - await setPassword( - "TestKeyring", - "TestUTF8", - "ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ" - ); - - const str = await getPassword("TestKeyring", "TestUTF8"); - t.is(str, "ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ"); -}); - -test.serial("get/setPassword with CJK symbols", async (t) => { - await setPassword("TestKeyring", "TestCJK", "「こんにちは世界」"); - - const str = await getPassword("TestKeyring", "TestCJK"); - t.is(str, "「こんにちは世界」"); -}); - -test.serial("get/setPassword fails with null/undefined data", async (t) => { - try { - await setPassword("TestKeyring", "TestNull", null); - } catch (err) { - t.is(err.code, "StringExpected"); - } - - try { - await setPassword("TestKeyring", "TestNull", undefined); - } catch (err) { - t.is(err.code, "StringExpected"); - } -}); - -test.serial( - "get/setPassword with password containing extra null terminators", - async (t) => { - // "password" parameter w/ extra null terminator - await setPassword("TestKeyring", "PwNullTerm", "PW\0"); - const pwRes = await getPassword("TestKeyring", "PwNullTerm"); - if (process.platform === "linux") { - // libsecret automatically strips off null terminator - t.is(pwRes, "PW"); - } else { - t.is(pwRes, "PW\0"); - } - } -); - -test.serial("getPassword with missing data", async (t) => { - const str = await getPassword("TestKeyring", "TestMissingPW"); - t.is(str, null); -}); - -test.serial( - "findCredentials verifies that test credentials were stored", - async (t) => { - let expected = [ - { account: "TestASCII", password: "ASCII string" }, - { account: "TestBinary", password: "Hello world!" }, - { account: "TestCharSet", password: "I 💔 ASCII" }, - { account: "TestCJK", password: "「こんにちは世界」" }, - { - account: "TestUTF8", - password: "ᚻᛖ ᚳᚹᚫᚦ ᚦᚫᛏ ᚻᛖ ᛒᚢᛞᛖ ᚩᚾ ᚦᚫᛗ ᛚᚪᚾᛞᛖ ᚾᚩᚱᚦᚹᛖᚪᚱᛞᚢᛗ ᚹᛁᚦ ᚦᚪ ᚹᛖᛥᚫ", - }, - { account: "TestUTF16", password: "🌞🌙🌟🌴" }, - { account: "PwNullTerm", password: "PW\x00" }, - ]; - const actual = await findCredentials("TestKeyring"); - t.is( - actual.length, - expected.length, - `actual: ${JSON.stringify(actual)}; expected: ${JSON.stringify(expected)}` - ); - - expected.forEach((cred) => - t.not( - actual.find((c) => c === cred), - null - ) - ); - } -); - -test.serial("findCredentials works when only one credential is found", async (t) => { - await setPassword("TestKeyring2", "TestOneCred", "pass"); - - const creds = await findCredentials("TestKeyring2"); - t.deepEqual(creds, [{ - account: "TestOneCred", - password: "pass" - }]); - await deletePassword("TestKeyring2", "TestOneCred"); -}); - -test.serial("findPassword for ASCII string", async (t) => { - const pw = await findPassword("TestKeyring/TestASCII"); - t.is(pw, "ASCII string"); -}); - -test.serial("findPassword for mixed character set", async (t) => { - const pw = await findPassword("TestKeyring/TestCharSet"); - t.is(pw, "I 💔 ASCII"); -}); - -test.serial("findPassword for UTF-16", async (t) => { - const pw = await findPassword("TestKeyring/TestUTF16"); - t.is(pw, "🌞🌙🌟🌴"); -}); - -test.serial("findPassword for CJK symbols", async (t) => { - const pw = await findPassword("TestKeyring/TestCJK"); - t.is(pw, "「こんにちは世界」"); -}); - -test("deletePassword deletes all test credentials", async (t) => { - console.log( - "\nThe deletePassword test is running. There is an intended delay of 5 seconds to wait for the keyring to update." - ); - const timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - // initial timeout to give keyrings time to populate - await timeout(5000); - for (const cred of TEST_CREDENTIALS) { - const result = await deletePassword(cred.service, cred.account); - if (!result) { - t.fail(`Credential with account "${cred.account}" failed to delete.`); - } - } - - const afterDeletion = await findCredentials("TestKeyring"); - t.is( - afterDeletion.length, - 0, - `One or more credentials were still in the keyring: ${afterDeletion - .map((c) => c.account) - .join(", ")}` - ); -}); - -// Unit tests specific to Windows API calls -if (process.platform === "win32") { - test.serial( - "setPassword fails when blob exceeds CRED_MAX_CREDENTIAL_BLOB_SIZE", - async (t) => { - console.log("win32: platform-specific tests for WinAPI"); - const CRED_MAX_CREDENTIAL_BLOB_SIZE = 5 * 512; - const str = randomAsciiString(CRED_MAX_CREDENTIAL_BLOB_SIZE + 1); - try { - await setPassword("TestKeyringWindows", "MaxCredBlobSize", str); - } catch (err) { - t.not(err, null); - } - } - ); - - test.serial( - "setPassword fails when TargetName exceeds CRED_MAX_GENERIC_TARGET_NAME_LENGTH", - async (t) => { - const CRED_MAX_GENERIC_TARGET_NAME_LENGTH = 32767; - const str = randomAsciiString(CRED_MAX_GENERIC_TARGET_NAME_LENGTH + 1); - try { - await setPassword( - "TestKeyringWindows", - "MaxGenericTargetNameLen_".concat(str), - "pw" - ); - } catch (err) { - t.not(err, null); - } - } - ); - - test.serial( - "setPassword fails when account length exceeds CRED_MAX_USERNAME_LENGTH", - async (t) => { - const CRED_MAX_USERNAME_LENGTH = 512; - const str = randomAsciiString(CRED_MAX_USERNAME_LENGTH + 1); - try { - await setPassword("TestKeyringWindows", str, "pw"); - } catch (err) { - t.not(err, null); - } - } - ); - - test.serial( - "findCredentials where CredEnumerateW returns false", - async (t) => { - const found = await findCredentials("TestKeyringWindowsInvalidService"); - t.deepEqual(found, []); - } - ); - - test.serial("findCredentials where TargetName is NULL", async (t) => { - // Since rust won't accept null as a parameter in the backend, best test is an empty string - const found = await findCredentials(""); - t.is(found.length > 0, true); - }); - - test.serial( - "Error handled when CredReadW throws ERROR_NOT_FOUND", - async (t) => { - try { - const errorTest = await getPassword( - "TestKeyringWindowsInvalidService", - "FakeAccount" - ); - t.is(errorTest, null); - } catch (err) { - t.fail( - "getPassword should not throw an exception when no credentials are found (win32)" - ); - } - } - ); - - test.serial( - "CredDeleteW with a credential that does not exist", - async (t) => { - try { - await deletePassword("TestKeyringWindowsInvalidService", "FakeAccount"); - } catch (err) { - t.fail( - "deletePassword should not throw an exception for a credential that doesn't exist (win32)" - ); - } - - t.pass(); - } - ); -} diff --git a/src/secrets/src/keyring/build.rs b/src/secrets/src/keyring/build.rs deleted file mode 100644 index 1f866b6a..00000000 --- a/src/secrets/src/keyring/build.rs +++ /dev/null @@ -1,5 +0,0 @@ -extern crate napi_build; - -fn main() { - napi_build::setup(); -} diff --git a/src/secrets/src/keyring/index.d.ts b/src/secrets/src/keyring/index.d.ts deleted file mode 100644 index fe9a0998..00000000 --- a/src/secrets/src/keyring/index.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* tslint:disable */ -/* eslint-disable */ - -/* auto-generated by NAPI-RS */ - -export interface Credential { - account: string - password: string -} -export function deletePassword(service: string, account: string): Promise -export function findCredentials(service: string): Promise> -export function findPassword(service: string): Promise -export function getPassword(service: string, account: string): Promise -export function setPassword(service: string, account: string, password: string): Promise diff --git a/src/secrets/src/keyring/index.js b/src/secrets/src/keyring/index.js deleted file mode 100644 index fd3b886f..00000000 --- a/src/secrets/src/keyring/index.js +++ /dev/null @@ -1,66 +0,0 @@ -/* -* This program and the accompanying materials are made available under the terms of the -* Eclipse Public License v2.0 which accompanies this distribution, and is available at -* https://www.eclipse.org/legal/epl-v20.html -* -* SPDX-License-Identifier: EPL-2.0 -* -* Copyright Contributors to the Zowe Project. -* -*/ - -const { existsSync } = require("fs"); -const { join, normalize, parse } = require("path"); - -function findPrebuildsDir(dir) { - if (!dir || existsSync(join(dir, "package.json"))) { - return join(dir, "prebuilds"); - } - - const dirUp = normalize(join(dir, "..")); - if (parse(dirUp).base.length > 0) { - return findPrebuildsDir(dirUp); - } -} - -function getTargetName() { - switch (process.platform) { - case "win32": - return `win32-${process.arch}-msvc`; - case "linux": - const isMusl = - process.report.getReport().header.glibcVersionRuntime == null; - const abi = isMusl ? "musl" : "gnu"; - switch (process.arch) { - case "arm": - return `linux-arm-${abi}eabihf`; - default: - return `linux-${process.arch}-${abi}`; - } - case "darwin": - default: - return `${process.platform}-${process.arch}`; - } -} - -const requireFn = - typeof __webpack_require__ === "function" - ? __non_webpack_require__ - : require; - -const binaryPath = requireFn.resolve(`./keyring.${getTargetName()}.node`, { - paths: [__dirname, findPrebuildsDir(__dirname)].filter(Boolean), -}); -const { - deletePassword, - findCredentials, - findPassword, - getPassword, - setPassword, -} = requireFn(binaryPath); - -module.exports.deletePassword = deletePassword; -module.exports.findCredentials = findCredentials; -module.exports.findPassword = findPassword; -module.exports.getPassword = getPassword; -module.exports.setPassword = setPassword; diff --git a/src/secrets/src/keyring/napi.json b/src/secrets/src/keyring/napi.json deleted file mode 100644 index 354e4cdc..00000000 --- a/src/secrets/src/keyring/napi.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "napi": { - "name": "keyring", - "package": { - "name": "keyring" - }, - "triples": { - "defaults": true, - "additional": [ - "x86_64-unknown-linux-musl", - "aarch64-unknown-linux-gnu", - "i686-unknown-linux-gnu", - "i686-pc-windows-msvc", - "armv7-unknown-linux-gnueabihf", - "aarch64-apple-darwin", - "aarch64-unknown-linux-musl", - "aarch64-pc-windows-msvc" - ] - } - } -} diff --git a/src/secrets/src/keyring/rustfmt.toml b/src/secrets/src/keyring/rustfmt.toml deleted file mode 100644 index ca5602ae..00000000 --- a/src/secrets/src/keyring/rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -tab_spaces = 4 -edition = "2021" diff --git a/src/secrets/src/keyring/src/lib.rs b/src/secrets/src/keyring/src/lib.rs deleted file mode 100644 index 2965de83..00000000 --- a/src/secrets/src/keyring/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -use napi::bindgen_prelude::AsyncTask; -use napi_derive::napi; -use workers::{DeletePassword, FindCredentials, FindPassword, GetPassword, SetPassword}; - -mod os; -mod workers; - -#[napi] -fn delete_password(service: String, account: String) -> AsyncTask { - AsyncTask::new(DeletePassword { service, account }) -} - -#[napi] -fn find_credentials(service: String) -> AsyncTask { - AsyncTask::new(FindCredentials { service }) -} - -#[napi(ts_return_type = "Promise")] -fn find_password(service: String) -> AsyncTask { - AsyncTask::new(FindPassword { service }) -} - -#[napi(ts_return_type = "Promise")] -fn get_password(service: String, account: String) -> AsyncTask { - AsyncTask::new(GetPassword { service, account }) -} - -#[napi(ts_return_type = "Promise")] -fn set_password(service: String, account: String, password: String) -> AsyncTask { - AsyncTask::new(SetPassword { - service, - account, - password, - }) -} diff --git a/src/secrets/src/keyring/src/workers.rs b/src/secrets/src/keyring/src/workers.rs deleted file mode 100644 index 88ee339d..00000000 --- a/src/secrets/src/keyring/src/workers.rs +++ /dev/null @@ -1,153 +0,0 @@ -use napi::{Env, Error, JsBoolean, JsUnknown, Result, Task}; -use napi_derive::napi; - -use crate::os; - -pub struct SetPassword { - pub service: String, - pub account: String, - pub password: String, -} - -pub struct GetPassword { - pub service: String, - pub account: String, -} - -pub struct DeletePassword { - pub service: String, - pub account: String, -} - -pub struct FindCredentials { - pub service: String, -} -pub struct FindPassword { - pub service: String, -} - -#[napi(object)] -pub struct Credential { - pub account: String, - pub password: String, -} - -#[napi] -impl Task for GetPassword { - type Output = Option; - type JsValue = JsUnknown; - - fn compute(&mut self) -> Result { - match os::get_password(&self.service, &self.account) { - Ok(pw) => Ok(pw), - Err(err) => Err(napi::Error::from_reason(err.to_string())), - } - } - - fn resolve(&mut self, env: Env, output: Self::Output) -> Result { - Ok(match output { - Some(pw) => env.create_string(pw.as_str())?.into_unknown(), - None => env.get_null()?.into_unknown(), - }) - } - - fn reject(&mut self, _env: Env, err: Error) -> Result { - Err(err) - } -} - -#[napi] -impl Task for SetPassword { - type Output = bool; - type JsValue = JsUnknown; - - fn compute(&mut self) -> Result { - match os::set_password(&self.service, &self.account, &mut self.password) { - Ok(result) => Ok(result), - Err(err) => Err(napi::Error::from_reason(err.to_string())), - } - } - - fn resolve(&mut self, env: Env, _output: Self::Output) -> Result { - Ok(env.get_null()?.into_unknown()) - } - - fn reject(&mut self, _env: Env, err: Error) -> Result { - Err(err) - } -} - -#[napi] -impl Task for DeletePassword { - type Output = bool; - type JsValue = JsBoolean; - - fn compute(&mut self) -> Result { - match os::delete_password(&self.service, &self.account) { - Ok(result) => Ok(result), - Err(err) => Err(napi::Error::from_reason(err.to_string())), - } - } - - fn resolve(&mut self, env: Env, output: Self::Output) -> Result { - env.get_boolean(output) - } - - fn reject(&mut self, _env: Env, err: Error) -> Result { - Err(err) - } -} - -#[napi] -impl Task for FindCredentials { - type Output = Vec<(String, String)>; - type JsValue = Vec; - - fn compute(&mut self) -> Result { - let mut credentials: Self::Output = Vec::new(); - match os::find_credentials(&self.service, &mut credentials) { - Ok(_result) => Ok(credentials), - Err(err) => Err(napi::Error::from_reason(err.to_string())), - } - } - - fn resolve(&mut self, _env: Env, output: Self::Output) -> Result { - let mut creds = Vec::new(); - for cred in output { - creds.push(Credential { - account: cred.0, - password: cred.1, - }) - } - - Ok(creds) - } - - fn reject(&mut self, _env: Env, err: Error) -> Result { - Err(err) - } -} - -#[napi] -impl Task for FindPassword { - type Output = Option; - type JsValue = JsUnknown; - - fn compute(&mut self) -> Result { - match os::find_password(&self.service) { - Ok(pw) => Ok(pw), - Err(err) => Err(napi::Error::from_reason(err.to_string())), - } - } - - fn resolve(&mut self, env: Env, output: Self::Output) -> Result { - Ok(match output { - Some(pw) => env.create_string(pw.as_str())?.into_unknown(), - None => env.get_null()?.into_unknown(), - }) - } - - fn reject(&mut self, _env: Env, err: Error) -> Result { - Err(err) - } -}