diff --git a/.eslintcache b/.eslintcache new file mode 100644 index 0000000..eb9bd07 --- /dev/null +++ b/.eslintcache @@ -0,0 +1 @@ +[{"/home/username/Projects/VaultUI/src/PageState.ts":"1","/home/username/Projects/VaultUI/src/allPages.ts":"2","/home/username/Projects/VaultUI/src/api/apiUtils.ts":"3","/home/username/Projects/VaultUI/src/api/auth/listAuth.ts":"4","/home/username/Projects/VaultUI/src/api/auth/usernameLogin.ts":"5","/home/username/Projects/VaultUI/src/api/auth/userpass/getUserPassUser.ts":"6","/home/username/Projects/VaultUI/src/api/auth/userpass/listUserPassUsers.ts":"7","/home/username/Projects/VaultUI/src/api/kv/createOrUpdateSecret.ts":"8","/home/username/Projects/VaultUI/src/api/kv/deleteSecret.ts":"9","/home/username/Projects/VaultUI/src/api/kv/getSecret.ts":"10","/home/username/Projects/VaultUI/src/api/kv/getSecretMetadata.ts":"11","/home/username/Projects/VaultUI/src/api/kv/getSecrets.ts":"12","/home/username/Projects/VaultUI/src/api/kv/undeleteSecret.ts":"13","/home/username/Projects/VaultUI/src/api/sys/getCapabilities.ts":"14","/home/username/Projects/VaultUI/src/api/sys/getMounts.ts":"15","/home/username/Projects/VaultUI/src/api/sys/getSealStatus.ts":"16","/home/username/Projects/VaultUI/src/api/sys/lookupSelf.ts":"17","/home/username/Projects/VaultUI/src/api/sys/newMount.ts":"18","/home/username/Projects/VaultUI/src/api/sys/renewSelf.ts":"19","/home/username/Projects/VaultUI/src/api/sys/sealVault.ts":"20","/home/username/Projects/VaultUI/src/api/sys/submitUnsealKey.ts":"21","/home/username/Projects/VaultUI/src/api/totp/addNewTOTP.ts":"22","/home/username/Projects/VaultUI/src/api/totp/getTOTPCode.ts":"23","/home/username/Projects/VaultUI/src/api/totp/getTOTPKeys.ts":"24","/home/username/Projects/VaultUI/src/api/transit/getTransitKey.ts":"25","/home/username/Projects/VaultUI/src/api/transit/getTransitKeys.ts":"26","/home/username/Projects/VaultUI/src/api/transit/newTransitKey.ts":"27","/home/username/Projects/VaultUI/src/api/transit/transitDecrypt.ts":"28","/home/username/Projects/VaultUI/src/api/transit/transitEncrypt.ts":"29","/home/username/Projects/VaultUI/src/api/transit/transitRewrap.ts":"30","/home/username/Projects/VaultUI/src/api/types/auth.ts":"31","/home/username/Projects/VaultUI/src/api/types/token.ts":"32","/home/username/Projects/VaultUI/src/api/types/transit.ts":"33","/home/username/Projects/VaultUI/src/api/types/userpass/user.ts":"34","/home/username/Projects/VaultUI/src/elements/CopyableInputBox.ts":"35","/home/username/Projects/VaultUI/src/elements/CopyableModal.ts":"36","/home/username/Projects/VaultUI/src/elements/FileUploadInput.ts":"37","/home/username/Projects/VaultUI/src/elements/Form.ts":"38","/home/username/Projects/VaultUI/src/elements/HeaderAndContent.ts":"39","/home/username/Projects/VaultUI/src/elements/ListItem.ts":"40","/home/username/Projects/VaultUI/src/elements/Margin.ts":"41","/home/username/Projects/VaultUI/src/elements/MarginInline.ts":"42","/home/username/Projects/VaultUI/src/elements/NavBar.ts":"43","/home/username/Projects/VaultUI/src/elements/Option.ts":"44","/home/username/Projects/VaultUI/src/elements/QRScanner.ts":"45","/home/username/Projects/VaultUI/src/elements/Tile.ts":"46","/home/username/Projects/VaultUI/src/formatDistance.ts":"47","/home/username/Projects/VaultUI/src/globalPageState.ts":"48","/home/username/Projects/VaultUI/src/htmlUtils.ts":"49","/home/username/Projects/VaultUI/src/main.ts":"50","/home/username/Projects/VaultUI/src/pageUtils.ts":"51","/home/username/Projects/VaultUI/src/pages/Access/AccessHome.ts":"52","/home/username/Projects/VaultUI/src/pages/Access/Auth/AuthHome.ts":"53","/home/username/Projects/VaultUI/src/pages/Access/Auth/AuthViewConfig.ts":"54","/home/username/Projects/VaultUI/src/pages/Access/Auth/userpass/UserPassUserView.ts":"55","/home/username/Projects/VaultUI/src/pages/Access/Auth/userpass/UserPassUsersList.ts":"56","/home/username/Projects/VaultUI/src/pages/Home.ts":"57","/home/username/Projects/VaultUI/src/pages/Login.ts":"58","/home/username/Projects/VaultUI/src/pages/Me.ts":"59","/home/username/Projects/VaultUI/src/pages/PwGen.ts":"60","/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueDelete.ts":"61","/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueNew.ts":"62","/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueSecret.ts":"63","/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueSecretsEdit.ts":"64","/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueVersions.ts":"65","/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueView.ts":"66","/home/username/Projects/VaultUI/src/pages/Secrets/NewEngines/NewKVEngine.ts":"67","/home/username/Projects/VaultUI/src/pages/Secrets/NewEngines/NewTOTPEngine.ts":"68","/home/username/Projects/VaultUI/src/pages/Secrets/NewEngines/NewTransitEngine.ts":"69","/home/username/Projects/VaultUI/src/pages/Secrets/NewSecretsEngine.ts":"70","/home/username/Projects/VaultUI/src/pages/Secrets/SecretTitleElement.ts":"71","/home/username/Projects/VaultUI/src/pages/Secrets/SecretsHome.ts":"72","/home/username/Projects/VaultUI/src/pages/Secrets/TOTP/NewTOTP.ts":"73","/home/username/Projects/VaultUI/src/pages/Secrets/TOTP/TOTPView.ts":"74","/home/username/Projects/VaultUI/src/pages/Secrets/Transit/NewTransitKey.ts":"75","/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitDecrypt.ts":"76","/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitEncrypt.ts":"77","/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitRewrap.ts":"78","/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitView.ts":"79","/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitViewSecret.ts":"80","/home/username/Projects/VaultUI/src/pages/SetLanguage.ts":"81","/home/username/Projects/VaultUI/src/pages/SetVaultURL.ts":"82","/home/username/Projects/VaultUI/src/pages/Unseal.ts":"83","/home/username/Projects/VaultUI/src/playground.ts":"84","/home/username/Projects/VaultUI/src/translations/de.js":"85","/home/username/Projects/VaultUI/src/translations/en.js":"86","/home/username/Projects/VaultUI/src/translations/fr.js":"87","/home/username/Projects/VaultUI/src/translations/nl.js":"88","/home/username/Projects/VaultUI/src/translations/ru.js":"89","/home/username/Projects/VaultUI/src/types/Page.ts":"90","/home/username/Projects/VaultUI/src/types/internalErrors.ts":"91","/home/username/Projects/VaultUI/src/utils.ts":"92"},{"size":3392,"mtime":1621518107492,"results":"93","hashOfConfig":"94"},{"size":4068,"mtime":1621520037020,"results":"95","hashOfConfig":"94"},{"size":238,"mtime":1621516183334,"results":"96","hashOfConfig":"94"},{"size":387,"mtime":1621516183330,"results":"97","hashOfConfig":"94"},{"size":659,"mtime":1621516183330,"results":"98","hashOfConfig":"94"},{"size":453,"mtime":1621520037020,"results":"99","hashOfConfig":"94"},{"size":382,"mtime":1621516183330,"results":"100","hashOfConfig":"94"},{"size":1025,"mtime":1621516183340,"results":"101","hashOfConfig":"94"},{"size":1341,"mtime":1621516183340,"results":"102","hashOfConfig":"94"},{"size":887,"mtime":1621516183340,"results":"103","hashOfConfig":"94"},{"size":545,"mtime":1621516183340,"results":"104","hashOfConfig":"94"},{"size":791,"mtime":1621516183340,"results":"105","hashOfConfig":"94"},{"size":1069,"mtime":1621516183340,"results":"106","hashOfConfig":"94"},{"size":824,"mtime":1621516183330,"results":"107","hashOfConfig":"94"},{"size":505,"mtime":1621516183330,"results":"108","hashOfConfig":"94"},{"size":373,"mtime":1621516183330,"results":"109","hashOfConfig":"94"},{"size":505,"mtime":1621516183330,"results":"110","hashOfConfig":"94"},{"size":717,"mtime":1621516183330,"results":"111","hashOfConfig":"94"},{"size":493,"mtime":1621516183330,"results":"112","hashOfConfig":"94"},{"size":389,"mtime":1621516183330,"results":"113","hashOfConfig":"94"},{"size":515,"mtime":1621516183330,"results":"114","hashOfConfig":"94"},{"size":674,"mtime":1621516183330,"results":"115","hashOfConfig":"94"},{"size":385,"mtime":1621516183330,"results":"116","hashOfConfig":"94"},{"size":503,"mtime":1621516183334,"results":"117","hashOfConfig":"94"},{"size":565,"mtime":1621516183340,"results":"118","hashOfConfig":"94"},{"size":505,"mtime":1621516183334,"results":"119","hashOfConfig":"94"},{"size":698,"mtime":1621516183340,"results":"120","hashOfConfig":"94"},{"size":836,"mtime":1621516183340,"results":"121","hashOfConfig":"94"},{"size":836,"mtime":1621516183340,"results":"122","hashOfConfig":"94"},{"size":839,"mtime":1621516183340,"results":"123","hashOfConfig":"94"},{"size":373,"mtime":1621516183334,"results":"124","hashOfConfig":"94"},{"size":402,"mtime":1621516183334,"results":"125","hashOfConfig":"94"},{"size":920,"mtime":1621516183334,"results":"126","hashOfConfig":"94"},{"size":329,"mtime":1621520037020,"results":"127","hashOfConfig":"94"},{"size":1439,"mtime":1621516183317,"results":"128","hashOfConfig":"94"},{"size":2855,"mtime":1621516183317,"results":"129","hashOfConfig":"94"},{"size":786,"mtime":1621516183317,"results":"130","hashOfConfig":"94"},{"size":370,"mtime":1621521557122,"results":"131","hashOfConfig":"94"},{"size":470,"mtime":1621518772821,"results":"132","hashOfConfig":"94"},{"size":187,"mtime":1621516183317,"results":"133","hashOfConfig":"94"},{"size":206,"mtime":1621516183314,"results":"134","hashOfConfig":"94"},{"size":294,"mtime":1621516183317,"results":"135","hashOfConfig":"94"},{"size":1946,"mtime":1621516183317,"results":"136","hashOfConfig":"94"},{"size":246,"mtime":1621516183317,"results":"137","hashOfConfig":"94"},{"size":1240,"mtime":1621516183317,"results":"138","hashOfConfig":"94"},{"size":1167,"mtime":1621516183317,"results":"139","hashOfConfig":"94"},{"size":427,"mtime":1621516183327,"results":"140","hashOfConfig":"94"},{"size":83,"mtime":1621516183330,"results":"141","hashOfConfig":"94"},{"size":280,"mtime":1621516183327,"results":"142","hashOfConfig":"94"},{"size":3150,"mtime":1621516183327,"results":"143","hashOfConfig":"94"},{"size":2200,"mtime":1621516183327,"results":"144","hashOfConfig":"94"},{"size":2186,"mtime":1621516183327,"results":"145","hashOfConfig":"94"},{"size":2258,"mtime":1621518048588,"results":"146","hashOfConfig":"94"},{"size":2558,"mtime":1621520037020,"results":"147","hashOfConfig":"94"},{"size":2266,"mtime":1621585700493,"results":"148","hashOfConfig":"94"},{"size":1195,"mtime":1621520046767,"results":"149","hashOfConfig":"94"},{"size":2795,"mtime":1621516183317,"results":"150","hashOfConfig":"94"},{"size":4876,"mtime":1621521992463,"results":"151","hashOfConfig":"94"},{"size":3022,"mtime":1621516183317,"results":"152","hashOfConfig":"94"},{"size":4020,"mtime":1621522174342,"results":"153","hashOfConfig":"94"},{"size":1592,"mtime":1621516183324,"results":"154","hashOfConfig":"94"},{"size":2365,"mtime":1621523798611,"results":"155","hashOfConfig":"94"},{"size":5671,"mtime":1621516867868,"results":"156","hashOfConfig":"94"},{"size":2552,"mtime":1621516183320,"results":"157","hashOfConfig":"94"},{"size":1568,"mtime":1621516183320,"results":"158","hashOfConfig":"94"},{"size":3104,"mtime":1621516183320,"results":"159","hashOfConfig":"94"},{"size":2588,"mtime":1621523634694,"results":"160","hashOfConfig":"94"},{"size":1973,"mtime":1621521067481,"results":"161","hashOfConfig":"94"},{"size":1999,"mtime":1621523539064,"results":"162","hashOfConfig":"94"},{"size":1467,"mtime":1621516183324,"results":"163","hashOfConfig":"94"},{"size":1851,"mtime":1621516183324,"results":"164","hashOfConfig":"94"},{"size":3127,"mtime":1621516867868,"results":"165","hashOfConfig":"94"},{"size":3369,"mtime":1621523100533,"results":"166","hashOfConfig":"94"},{"size":3735,"mtime":1621516183324,"results":"167","hashOfConfig":"94"},{"size":2825,"mtime":1621523539064,"results":"168","hashOfConfig":"94"},{"size":3575,"mtime":1621522679278,"results":"169","hashOfConfig":"94"},{"size":3585,"mtime":1621522712871,"results":"170","hashOfConfig":"94"},{"size":3678,"mtime":1621523100533,"results":"171","hashOfConfig":"94"},{"size":2238,"mtime":1621516183320,"results":"172","hashOfConfig":"94"},{"size":2305,"mtime":1621516183320,"results":"173","hashOfConfig":"94"},{"size":1985,"mtime":1621521691035,"results":"174","hashOfConfig":"94"},{"size":1361,"mtime":1621522372243,"results":"175","hashOfConfig":"94"},{"size":5326,"mtime":1621521334308,"results":"176","hashOfConfig":"94"},{"size":697,"mtime":1621516183327,"results":"177","hashOfConfig":"94"},{"size":736,"mtime":1620831400010,"results":"178","hashOfConfig":"94"},{"size":9487,"mtime":1621519891930,"results":"179","hashOfConfig":"94"},{"size":5783,"mtime":1621331186858,"results":"180","hashOfConfig":"94"},{"size":737,"mtime":1620831400010,"results":"181","hashOfConfig":"94"},{"size":8289,"mtime":1621331199668,"results":"182","hashOfConfig":"94"},{"size":637,"mtime":1621516183330,"results":"183","hashOfConfig":"94"},{"size":147,"mtime":1621516183330,"results":"184","hashOfConfig":"94"},{"size":870,"mtime":1621585633253,"results":"185","hashOfConfig":"94"},{"filePath":"186","messages":"187","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"3eomw3",{"filePath":"188","messages":"189","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"190","messages":"191","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"192","messages":"193","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"194","messages":"195","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"196","messages":"197","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"198","messages":"199","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"200","messages":"201","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"202","messages":"203","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"204","messages":"205","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"206","messages":"207","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"208","messages":"209","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"210","messages":"211","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"212","messages":"213","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"214","messages":"215","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"216","messages":"217","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"218","messages":"219","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"220","messages":"221","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"222","messages":"223","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"224","messages":"225","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"226","messages":"227","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"228","messages":"229","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"230","messages":"231","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"232","messages":"233","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"234","messages":"235","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"236","messages":"237","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"238","messages":"239","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"240","messages":"241","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"242","messages":"243","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"244","messages":"245","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"246","messages":"247","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"248","messages":"249","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"250","messages":"251","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"252","messages":"253","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"254","messages":"255","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"256","messages":"257","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"258","messages":"259","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"260","messages":"261","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"262","messages":"263","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"264","messages":"265","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"266","messages":"267","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"268","messages":"269","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"270","messages":"271","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"272","messages":"273","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"274","messages":"275","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"276","messages":"277","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"278","messages":"279","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"280","messages":"281","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"282","messages":"283","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"284","messages":"285","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"286","messages":"287","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"288","messages":"289","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"290","messages":"291","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"292","messages":"293","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"294","messages":"295","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"296","messages":"297","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"298","messages":"299","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"300","messages":"301","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"302","messages":"303","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"304","messages":"305","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"306","messages":"307","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"308","messages":"309","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"310","messages":"311","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"312","messages":"313","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"314","messages":"315","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"316","messages":"317","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"318","messages":"319","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"320","messages":"321","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"322","messages":"323","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"324","messages":"325","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"326","messages":"327","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"328","messages":"329","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"330","messages":"331","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"332","messages":"333","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"334","messages":"335","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"336","messages":"337","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"338","messages":"339","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"340","messages":"341","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"342","messages":"343","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"344","messages":"345","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"346","messages":"347","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"348","messages":"349","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"350","messages":"351","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"352","messages":"353","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"354","messages":"355","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"356","messages":"357","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"358","messages":"359","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"360","messages":"361","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"362","messages":"363","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"364","messages":"365","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"366","messages":"367","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"368","messages":"369","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/username/Projects/VaultUI/src/PageState.ts",[],"/home/username/Projects/VaultUI/src/allPages.ts",[],"/home/username/Projects/VaultUI/src/api/apiUtils.ts",[],"/home/username/Projects/VaultUI/src/api/auth/listAuth.ts",[],"/home/username/Projects/VaultUI/src/api/auth/usernameLogin.ts",[],"/home/username/Projects/VaultUI/src/api/auth/userpass/getUserPassUser.ts",[],"/home/username/Projects/VaultUI/src/api/auth/userpass/listUserPassUsers.ts",[],"/home/username/Projects/VaultUI/src/api/kv/createOrUpdateSecret.ts",[],"/home/username/Projects/VaultUI/src/api/kv/deleteSecret.ts",[],"/home/username/Projects/VaultUI/src/api/kv/getSecret.ts",[],"/home/username/Projects/VaultUI/src/api/kv/getSecretMetadata.ts",[],"/home/username/Projects/VaultUI/src/api/kv/getSecrets.ts",[],"/home/username/Projects/VaultUI/src/api/kv/undeleteSecret.ts",[],"/home/username/Projects/VaultUI/src/api/sys/getCapabilities.ts",[],"/home/username/Projects/VaultUI/src/api/sys/getMounts.ts",[],"/home/username/Projects/VaultUI/src/api/sys/getSealStatus.ts",[],"/home/username/Projects/VaultUI/src/api/sys/lookupSelf.ts",[],"/home/username/Projects/VaultUI/src/api/sys/newMount.ts",[],"/home/username/Projects/VaultUI/src/api/sys/renewSelf.ts",[],"/home/username/Projects/VaultUI/src/api/sys/sealVault.ts",[],"/home/username/Projects/VaultUI/src/api/sys/submitUnsealKey.ts",[],"/home/username/Projects/VaultUI/src/api/totp/addNewTOTP.ts",[],"/home/username/Projects/VaultUI/src/api/totp/getTOTPCode.ts",[],"/home/username/Projects/VaultUI/src/api/totp/getTOTPKeys.ts",[],"/home/username/Projects/VaultUI/src/api/transit/getTransitKey.ts",[],"/home/username/Projects/VaultUI/src/api/transit/getTransitKeys.ts",[],"/home/username/Projects/VaultUI/src/api/transit/newTransitKey.ts",[],"/home/username/Projects/VaultUI/src/api/transit/transitDecrypt.ts",[],"/home/username/Projects/VaultUI/src/api/transit/transitEncrypt.ts",[],"/home/username/Projects/VaultUI/src/api/transit/transitRewrap.ts",[],"/home/username/Projects/VaultUI/src/api/types/auth.ts",[],"/home/username/Projects/VaultUI/src/api/types/token.ts",[],"/home/username/Projects/VaultUI/src/api/types/transit.ts",[],"/home/username/Projects/VaultUI/src/api/types/userpass/user.ts",[],"/home/username/Projects/VaultUI/src/elements/CopyableInputBox.ts",[],"/home/username/Projects/VaultUI/src/elements/CopyableModal.ts",[],"/home/username/Projects/VaultUI/src/elements/FileUploadInput.ts",[],"/home/username/Projects/VaultUI/src/elements/Form.ts",[],"/home/username/Projects/VaultUI/src/elements/HeaderAndContent.ts",[],"/home/username/Projects/VaultUI/src/elements/ListItem.ts",[],"/home/username/Projects/VaultUI/src/elements/Margin.ts",[],"/home/username/Projects/VaultUI/src/elements/MarginInline.ts",[],"/home/username/Projects/VaultUI/src/elements/NavBar.ts",[],"/home/username/Projects/VaultUI/src/elements/Option.ts",[],"/home/username/Projects/VaultUI/src/elements/QRScanner.ts",[],"/home/username/Projects/VaultUI/src/elements/Tile.ts",[],"/home/username/Projects/VaultUI/src/formatDistance.ts",[],"/home/username/Projects/VaultUI/src/globalPageState.ts",[],"/home/username/Projects/VaultUI/src/htmlUtils.ts",[],"/home/username/Projects/VaultUI/src/main.ts",[],"/home/username/Projects/VaultUI/src/pageUtils.ts",[],"/home/username/Projects/VaultUI/src/pages/Access/AccessHome.ts",[],"/home/username/Projects/VaultUI/src/pages/Access/Auth/AuthHome.ts",[],"/home/username/Projects/VaultUI/src/pages/Access/Auth/AuthViewConfig.ts",[],"/home/username/Projects/VaultUI/src/pages/Access/Auth/userpass/UserPassUserView.ts",[],"/home/username/Projects/VaultUI/src/pages/Access/Auth/userpass/UserPassUsersList.ts",[],"/home/username/Projects/VaultUI/src/pages/Home.ts",[],"/home/username/Projects/VaultUI/src/pages/Login.ts",[],"/home/username/Projects/VaultUI/src/pages/Me.ts",[],"/home/username/Projects/VaultUI/src/pages/PwGen.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueDelete.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueNew.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueSecret.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueSecretsEdit.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueVersions.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/KeyValue/KeyValueView.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/NewEngines/NewKVEngine.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/NewEngines/NewTOTPEngine.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/NewEngines/NewTransitEngine.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/NewSecretsEngine.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/SecretTitleElement.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/SecretsHome.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/TOTP/NewTOTP.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/TOTP/TOTPView.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/Transit/NewTransitKey.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitDecrypt.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitEncrypt.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitRewrap.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitView.ts",[],"/home/username/Projects/VaultUI/src/pages/Secrets/Transit/TransitViewSecret.ts",[],"/home/username/Projects/VaultUI/src/pages/SetLanguage.ts",[],"/home/username/Projects/VaultUI/src/pages/SetVaultURL.ts",[],"/home/username/Projects/VaultUI/src/pages/Unseal.ts",[],"/home/username/Projects/VaultUI/src/playground.ts",[],"/home/username/Projects/VaultUI/src/translations/de.js",[],"/home/username/Projects/VaultUI/src/translations/en.js",[],"/home/username/Projects/VaultUI/src/translations/fr.js",[],"/home/username/Projects/VaultUI/src/translations/nl.js",[],"/home/username/Projects/VaultUI/src/translations/ru.js",[],"/home/username/Projects/VaultUI/src/types/Page.ts",[],"/home/username/Projects/VaultUI/src/types/internalErrors.ts",[],"/home/username/Projects/VaultUI/src/utils.ts",[]] \ No newline at end of file diff --git a/package.json b/package.json index 52d8691..5bf0adf 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "webpack": "^5.37.0", "webpack-cli": "^4.7.0", "webpack-dev-server": "^3.11.2", - "z-makeelement": "^1.0.2", + "z-makeelement": "^1.0.3", "z-pagerouter": "^1.0.1" } } diff --git a/runLinter.sh b/runLinter.sh index 8eab877..576443b 100755 --- a/runLinter.sh +++ b/runLinter.sh @@ -1,3 +1,3 @@ #!/bin/bash -npx eslint -c .eslintrc.json "$@" --ext .js,.ts \ No newline at end of file +npx eslint --cache -c .eslintrc.json "$@" --ext .js,.ts \ No newline at end of file diff --git a/src/allPages.ts b/src/allPages.ts index 8d4bdad..4b087ae 100644 --- a/src/allPages.ts +++ b/src/allPages.ts @@ -36,6 +36,7 @@ import { UnsealPage } from "./pages/Unseal"; import { UserPassUserViewPage } from "./pages/Access/Auth/userpass/UserPassUserView"; import { UserPassUsersListPage } from "./pages/Access/Auth/userpass/UserPassUsersList"; import { getObjectKeys } from "./utils"; +import { UserPassUserEditPage } from "./pages/Access/Auth/userpass/UserPassUserEdit"; type pagesList = { [key: string]: Page; @@ -49,6 +50,7 @@ export const allPages: pagesList = { AUTH_VIEW_CONFIG: new AuthViewConfigPage(), USERPASS_USERS_LIST: new UserPassUsersListPage(), USERPASS_USER_VIEW: new UserPassUserViewPage(), + USERPASS_USER_EDIT: new UserPassUserEditPage(), ME: new MePage(), TOTP: new TOTPViewPage(), NEW_TOTP: new NewTOTPPage(), diff --git a/src/elements/Form.ts b/src/elements/Form.ts index e3b8f76..dbc4232 100644 --- a/src/elements/Form.ts +++ b/src/elements/Form.ts @@ -1,12 +1,14 @@ -import { makeElement } from "z-makeelement"; +import { makeElement, ElementInfo } from "z-makeelement"; export function Form( children: Element[], submit: (form: HTMLFormElement) => unknown, + options: Partial = {} ): HTMLFormElement { const form = makeElement({ tag: "form", children: children, + ...options, }) as HTMLFormElement; form.addEventListener("submit", (e: Event) => { diff --git a/src/elements/InputWithTitle.ts b/src/elements/InputWithTitle.ts new file mode 100644 index 0000000..a5a0b15 --- /dev/null +++ b/src/elements/InputWithTitle.ts @@ -0,0 +1,23 @@ +import { makeElement } from "z-makeelement"; +import { Margin } from "./Margin"; + +export function InputWithTitle( + title: string, + children: Element | Element[], +): Element { + return Margin([ + makeElement({ + tag: "label", + class: "uk-form-label", + children: makeElement({ + tag: "span", + text: title + }) + }), + makeElement({ + tag: "div", + class: "uk-form-controls uk-form-controls-text uk-margin-small-top", + children: children + }) + ]); +} diff --git a/src/pages/Access/Auth/userpass/UserPassUserEdit.ts b/src/pages/Access/Auth/userpass/UserPassUserEdit.ts new file mode 100644 index 0000000..85f4fef --- /dev/null +++ b/src/pages/Access/Auth/userpass/UserPassUserEdit.ts @@ -0,0 +1,157 @@ +import { HeaderAndContent } from "../../../../elements/HeaderAndContent"; +import { Page } from "../../../../types/Page"; +import { getUserPassUser } from "../../../../api/auth/userpass/getUserPassUser"; +import { makeElement } from "z-makeelement"; +import { toStr } from "../../../../utils"; +import i18next from "i18next"; +import { notImplemented } from "../../../../pageUtils"; +import { Margin } from "../../../../elements/Margin"; +import { Form } from "../../../../elements/Form"; +import { InputWithTitle } from "../../../../elements/InputWithTitle"; + +export class UserPassUserEditPage extends Page { + constructor() { + super(); + } + async goBack(): Promise { + await this.router.changePage("USERPASS_USER_VIEW"); + } + + async render(): Promise { + const user = await getUserPassUser(this.state.authPath, this.state.userPassUser); + + await this.router.setPageContent( + Form( + [ + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + type: "password", + name: "password", + placeholder: i18next.t("userpass_common_password") + }, + }), + + InputWithTitle( + i18next.t("userpass_common_cidrs"), + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + name: "cidrs", + value: user.token_bound_cidrs.join() + }, + }), + ), + InputWithTitle( + i18next.t("userpass_common_exp_max_ttl"), + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + name: "exp_max_ttl", + type: "number", + value: toStr(user.token_explicit_max_ttl) + }, + }), + ), + InputWithTitle( + i18next.t("userpass_common_max_ttl"), + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + name: "max_ttl", + type: "number", + value: toStr(user.token_max_ttl) + }, + }), + ), + InputWithTitle( + i18next.t("userpass_common_default_policy_attached"), + makeElement({ + tag: "input", + class: "uk-checkbox", + attributes: { + name: "def_pol_attached", + type: "checkbox", + value: toStr(user.token_no_default_policy) + }, + }), + ), + InputWithTitle( + i18next.t("userpass_common_max_token_uses"), + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + name: "max_uses", + type: "number", + value: toStr(user.token_num_uses) + }, + }), + ), + InputWithTitle( + i18next.t("userpass_common_token_peroid"), + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + name: "period", + type: "number", + value: toStr(user.token_period) + }, + }), + ), + InputWithTitle( + i18next.t("userpass_common_policies"), + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + name: "policies", + value: user.token_policies.join() + }, + }), + ), + InputWithTitle( + i18next.t("userpass_common_initial_ttl"), + makeElement({ + tag: "input", + class: "uk-input uk-form-width-large", + attributes: { + name: "initial_ttl", + type: "number", + value: toStr(user.token_ttl) + }, + }), + ), + + makeElement({ + tag: "p", + id: "errorText", + class: "uk-text-danger", + }), + makeElement({ + tag: "button", + class: ["uk-button", "uk-button-primary"], + text: i18next.t("userpass_user_edit_submit_btn"), + attributes: { + type: "submit", + }, + }), + ], + async (form: HTMLFormElement) => { + const formData = new FormData(form); + notImplemented(); + }, + ), + ); + + } + + get name(): string { + return i18next.t("userpass_user_edit_title"); + } +} diff --git a/src/pages/Access/Auth/userpass/UserPassUserView.ts b/src/pages/Access/Auth/userpass/UserPassUserView.ts index 13bd1e5..decbc94 100644 --- a/src/pages/Access/Auth/userpass/UserPassUserView.ts +++ b/src/pages/Access/Auth/userpass/UserPassUserView.ts @@ -2,7 +2,9 @@ import { HeaderAndContent } from "../../../../elements/HeaderAndContent"; import { Page } from "../../../../types/Page"; import { getUserPassUser } from "../../../../api/auth/userpass/getUserPassUser"; import { makeElement } from "z-makeelement"; +import { toStr } from "../../../../utils"; import i18next from "i18next"; +import { notImplemented } from "../../../../pageUtils"; export class UserPassUserViewPage extends Page { constructor() { @@ -13,60 +15,62 @@ export class UserPassUserViewPage extends Page { } async render(): Promise { + const contentElement = makeElement({ tag: "div" }); + await this.router.setPageContent(contentElement); + + contentElement.appendChild( + makeElement({ + tag: "button", + class: ["uk-button", "uk-margin", "uk-button-primary"], + onclick: async () => { + await this.router.changePage("USERPASS_USER_EDIT"); + }, + text: i18next.t("userpass_user_view_edit_btn"), + }), + ); + const tableElement = makeElement({ tag: "table", class: "uk-table", }); - await this.router.setPageContent(tableElement); - const contentElement = makeElement({ tag: "tbody" }); - tableElement.appendChild(contentElement); + contentElement.appendChild(tableElement); + + const tableBody = makeElement({ tag: "tbody" }); + tableElement.appendChild(tableBody); + const user = await getUserPassUser(this.state.authPath, this.state.userPassUser); - contentElement.appendChild( - HeaderAndContent(i18next.t("userpass_user_view_cidrs"), user.token_bound_cidrs.join()), + tableBody.appendChild( + HeaderAndContent(i18next.t("userpass_common_cidrs"), user.token_bound_cidrs.join()), ); - contentElement.appendChild( + tableBody.appendChild( HeaderAndContent( - i18next.t("userpass_user_view_exp_max_ttl"), - String(user.token_explicit_max_ttl).toString(), + i18next.t("userpass_common_exp_max_ttl"), + toStr(user.token_explicit_max_ttl), ), ); - contentElement.appendChild( + tableBody.appendChild( + HeaderAndContent(i18next.t("userpass_common_max_ttl"), toStr(user.token_max_ttl)), + ); + tableBody.appendChild( HeaderAndContent( - i18next.t("userpass_user_view_max_ttl"), - String(user.token_max_ttl).toString(), + i18next.t("userpass_common_default_policy_attached"), + toStr(user.token_no_default_policy), ), ); - contentElement.appendChild( - HeaderAndContent( - i18next.t("userpass_user_view_default_policy_attached"), - String(user.token_no_default_policy).toString(), - ), + tableBody.appendChild( + HeaderAndContent(i18next.t("userpass_common_max_token_uses"), toStr(user.token_num_uses)), ); - contentElement.appendChild( - HeaderAndContent( - i18next.t("userpass_user_view_max_token_uses"), - String(user.token_num_uses).toString(), - ), + tableBody.appendChild( + HeaderAndContent(i18next.t("userpass_common_token_peroid"), toStr(user.token_period)), ); - contentElement.appendChild( - HeaderAndContent( - i18next.t("userpass_user_view_token_peroid"), - String(user.token_period).toString(), - ), + tableBody.appendChild( + HeaderAndContent(i18next.t("userpass_common_policies"), user.token_policies.join()), ); - contentElement.appendChild( - HeaderAndContent(i18next.t("userpass_user_view_policies"), user.token_policies.join()), - ); - contentElement.appendChild( - HeaderAndContent( - i18next.t("userpass_user_view_initial_ttl"), - String(user.token_ttl).toString(), - ), - ); - contentElement.appendChild( - HeaderAndContent(i18next.t("userpass_user_view_type"), user.token_type), + tableBody.appendChild( + HeaderAndContent(i18next.t("userpass_common_initial_ttl"), toStr(user.token_ttl)), ); + tableBody.appendChild(HeaderAndContent(i18next.t("userpass_common_type"), user.token_type)); } get name(): string { diff --git a/src/scss/uikit.scss b/src/scss/uikit.scss index 5f74dea..4a5cdd5 100644 --- a/src/scss/uikit.scss +++ b/src/scss/uikit.scss @@ -45,6 +45,7 @@ $form-select-option-color: $global-muted-color; // Common @import "uikit/src/scss/components/spinner.scss"; @import "uikit/src/scss/components/alert.scss"; +@import "uikit/src/scss/components/label.scss"; // JavaScript @import "uikit/src/scss/components/modal.scss"; diff --git a/src/translations/en.js b/src/translations/en.js index eb56136..126cede 100644 --- a/src/translations/en.js +++ b/src/translations/en.js @@ -237,18 +237,27 @@ module.exports = { auth_view_config_max_lease_ttl: "Max Lease TTL", auth_view_config_token_type: "Token Type", + // UserPass Common + userpass_common_password: "Password", + userpass_common_cidrs: "Generated Token's Bound CIDRs", + userpass_common_exp_max_ttl: "Generated Token's Explicit Maximum TTL", + userpass_common_max_ttl: "Generated Token's Maximum TTL", + userpass_common_default_policy_attached: "Do Not Attach 'default' Policy To Generated Tokens", + userpass_common_max_token_uses: "Maximum Uses of Generated Tokens", + userpass_common_token_peroid: "Generated Token's Period", + userpass_common_policies: "Generated Token's Policies", + userpass_common_initial_ttl: "Generated Token's Initial TTL", + userpass_common_type: "Generated Token's Type", + // userpass Users List userpass_users_list_title: "Users List", // userpass User View userpass_user_view_title: "User View", - userpass_user_view_cidrs: "Generated Token's Bound CIDRs", - userpass_user_view_exp_max_ttl: "Generated Token's Explicit Maximum TTL", - userpass_user_view_max_ttl: "Generated Token's Maximum TTL", - userpass_user_view_default_policy_attached: "Do Not Attach 'default' Policy To Generated Tokens", - userpass_user_view_max_token_uses: "Maximum Uses of Generated Tokens", - userpass_user_view_token_peroid: "Generated Token's Period", - userpass_user_view_policies: "Generated Token's Policies", - userpass_user_view_initial_ttl: "Generated Token's Initial TTL", - userpass_user_view_type: "Generated Token's Type", + userpass_user_view_edit_btn: "Edit", + + // userpass user edit + userpass_user_edit_title: "User Edit", + userpass_user_edit_submit_btn: "Submit", + }; diff --git a/src/utils.ts b/src/utils.ts index 9d2a858..e433735 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,6 +2,8 @@ export function removeDoubleSlash(str: string): string { return str.replace(/\/\/+/g, "/"); } +export const toStr = (item: unknown): string => String(item).toString(); + export const getObjectKeys = (obj: Record): string[] => Object.getOwnPropertyNames(obj); export const objectToMap = (obj: Record): Map =>