diff --git a/server/web_ui/pkg/README.md b/server/web_ui/pkg/README.md index 7c40aa143..aede17ec3 100644 --- a/server/web_ui/pkg/README.md +++ b/server/web_ui/pkg/README.md @@ -6,65 +6,73 @@ ## About -Kanidm is a simple and secure identity management platform, which provides services to allow other -systems and application to authenticate against. The project aims for the highest levels of -reliability, security and ease of use. +Kanidm is a simple and secure identity management platform, allowing other applications and services +to offload the challenge of authenticating and storing identities to Kanidm. -The goal of this project is to be a complete identity management provider, covering the broadest -possible set of requirements and integrations. You should not need any other components (like -Keycloak) when you use Kanidm. We want to create a project that will be suitable for everything from -personal home deployments, to the largest enterprise needs. +The goal of this project is to be a complete identity provider, covering the broadest possible set +of requirements and integrations. You should not need any other components (like Keycloak) when you +use Kanidm - we already have everything you need! To achieve this we rely heavily on strict defaults, simple configuration, and self-healing -components. +components. This allows Kanidm to run from small home labs, for families, small business, and all +the way to the largest enterprise needs. -The project is still growing and some areas are developing at a fast pace. The core of the server -however is reliable and we make all effort to ensure upgrades will always work. +If you want to host your own authentication service, then Kanidm is for you! + +
Supported Features Kanidm supports: +- Webauthn (passkeys) for secure cryptographic authentication - Oauth2/OIDC Authentication provider for web SSO -- Read only LDAPS gateway -- Linux/Unix integration (with offline authentication) +- Oauth Application Portal/Gateway allowing easy access to linked applications +- Linux/Unix integration with offline authentication - SSH key distribution to Linux/Unix systems -- RADIUS for network authentication -- Passkeys / Webauthn for secure cryptographic authentication -- A self service web ui -- Complete CLI tooling for administration +- RADIUS for network and VPN authentication +- Read only LDAPS gateway for Legacy Systems +- Complete CLI tooling for Administration +- User Self Service the WebUI -If you want to host your own centralised authentication service, then Kanidm is for you! +
## Documentation / Getting Started / Install -If you want to deploy Kanidm to see what it can do, you should read the Kanidm book. +If you want to read more about what Kanidm can do, you should read our documentation. - [Kanidm book (Latest stable)](https://kanidm.github.io/kanidm/stable/) -- [Kanidm book (Latest commit)](https://kanidm.github.io/kanidm/master/) -We also publish +We also have a set of [support guidelines](https://github.com/kanidm/kanidm/blob/master/project_docs/RELEASE_AND_SUPPORT.md) -for what the project will support. +for what the project team will support ## Code of Conduct / Ethics -See our [code of conduct] +All interactions with the project are covered by our [code of conduct]. -See our documentation on [rights and ethics] +When we develop features we follow our projects guidelines on [rights and ethics] [code of conduct]: https://github.com/kanidm/kanidm/blob/master/CODE_OF_CONDUCT.md [rights and ethics]: https://github.com/kanidm/kanidm/blob/master/project_docs/ethics/README.md ## Getting in Contact / Questions -We have a [gitter community channel] where we can talk. Firstyear is also happy to answer questions -via email, which can be found on their github profile. +We have a [gitter community channel] where project members are always happy to answer questions. +Alternately you can open a new [github discussion]. [gitter community channel]: https://gitter.im/kanidm/community +[github discussion]: https://github.com/kanidm/kanidm/discussions + +## What does Kanidm mean? + +Kanidm is a portmanteau of 'kani' and 'idm'. Kani is Japanese for crab, related to Rust's mascot +ferris the crab. identity management is often abbreviated to 'idm', and is a common industry term +for these services. + +Kanidm is pronounced as "kar - nee - dee - em". ## Comparison with other services -### LLDAP - +
LLDAP [LLDAP](https://github.com/nitnelave/lldap) is a similar project aiming for a small and easy to administer LDAP server with a web administration portal. Both projects use the [Kanidm LDAP bindings](https://github.com/kanidm/ldap3), and have many similar ideas. @@ -77,20 +85,23 @@ may make it easier to administer and deploy for you. If Kanidm is too complex for your needs, you should check out LLDAP as a smaller alternative. If you want a project which has a broader feature set out of the box, then Kanidm might be a better fit. -### 389-ds / OpenLDAP +
+
389-ds / OpenLDAP Both 389-ds and OpenLDAP are generic LDAP servers. This means they only provide LDAP and you need to -bring your own IDM configuration on top. +bring your own IDM components - you need your own OIDC portal, webui's for self service, commandline +tools to administer and more. If you need the highest levels of customisation possible from your LDAP deployment, then these are -probably better alternatives. If you want a service that is easier to setup and focused on IDM, then +probably better alternatives. If you want a service that is easy to setup and focused on IDM, then Kanidm is a better choice. Kanidm was originally inspired by many elements of both 389-ds and OpenLDAP. Already Kanidm is as -fast as (or faster than) 389-ds for performance and scaling. +fast as (or faster than) 389-ds for performance and scaling as a directory service. -### FreeIPA +
+
FreeIPA FreeIPA is another identity management service for Linux/Unix, and ships a huge number of features from LDAP, Kerberos, DNS, Certificate Authority, and more. @@ -103,16 +114,30 @@ Kanidm is probably for you. In testing with 3000 users + 1500 groups, Kanidm is search operations and 5 times faster for modification and addition of entries (your results may differ however, but generally Kanidm is much faster than FreeIPA). +
+ +
Keycloak +Keycloak is an OIDC/Oauth2/SAML provider. It allows you to layer on Webauthn to existing IDM systems. +Keycloak can operate as a stand alone IDM but generally is a component attached to an existing LDAP +server or similar. + +Keycloak requires a significant amount of configuration and experience to deploy. It allows high +levels of customisation to every detail of it's authentication work flows, which makes it harder to +start with in many cases. + +Kanidm does NOT require Keycloak to provide services such as Oauth2 and integrates many of the +elements in a simpler and correct way out of the box in comparison. + +
+ ## Developer Getting Started -If you want to develop on the server, there is a getting started [guide for developers]. IDM is a +If you want to contribute to Kanidm there is a getting started [guide for developers]. IDM is a diverse topic and we encourage contributions of many kinds in the project, from people of all backgrounds. +When developing the server you should refer to the latest commit documentation instead. + +- [Kanidm book (Latest commit)](https://kanidm.github.io/kanidm/master/) + [guide for developers]: https://kanidm.github.io/kanidm/master/DEVELOPER_README.html - -## What does Kanidm mean? - -The original project name was rsidm while it was a thought experiment. Now that it's growing and -developing, we gave it a better project name. Kani is Japanese for "crab". Rust's mascot is a crab. -IDM is the common industry term for identity management services. diff --git a/server/web_ui/pkg/kanidmd_web_ui.js b/server/web_ui/pkg/kanidmd_web_ui.js index 4409be48c..c3bcb8a28 100644 --- a/server/web_ui/pkg/kanidmd_web_ui.js +++ b/server/web_ui/pkg/kanidmd_web_ui.js @@ -234,19 +234,19 @@ function addBorrowedObject(obj) { } function __wbg_adapter_48(arg0, arg1, arg2) { try { - wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h32972de9dc093e1b(arg0, arg1, addBorrowedObject(arg2)); + wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h81cab36ffd7a0f2a(arg0, arg1, addBorrowedObject(arg2)); } finally { heap[stack_pointer++] = undefined; } } function __wbg_adapter_51(arg0, arg1, arg2) { - wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8cb5efc0ceb7dbaf(arg0, arg1, addHeapObject(arg2)); + wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hf5c80722c0530c5d(arg0, arg1, addHeapObject(arg2)); } function __wbg_adapter_54(arg0, arg1, arg2) { try { - wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h6e1863c427195afd(arg0, arg1, addBorrowedObject(arg2)); + wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h4764cc6fa79b1493(arg0, arg1, addBorrowedObject(arg2)); } finally { heap[stack_pointer++] = undefined; } @@ -552,49 +552,6 @@ function __wbg_get_imports() { const ret = getObject(arg0).fetch(getObject(arg1)); return addHeapObject(ret); }; - imports.wbg.__wbg_instanceof_HtmlFormElement_a67ff2b843593f03 = function(arg0) { - let result; - try { - result = getObject(arg0) instanceof HTMLFormElement; - } catch { - result = false; - } - const ret = result; - return ret; - }; - imports.wbg.__wbg_instanceof_Response_7ade9a5a066d1a55 = function(arg0) { - let result; - try { - result = getObject(arg0) instanceof Response; - } catch { - result = false; - } - const ret = result; - return ret; - }; - imports.wbg.__wbg_status_d2b2d0889f7e970f = function(arg0) { - const ret = getObject(arg0).status; - return ret; - }; - imports.wbg.__wbg_headers_2de03c88f895093b = function(arg0) { - const ret = getObject(arg0).headers; - return addHeapObject(ret); - }; - imports.wbg.__wbg_json_6c19bb86f10d6184 = function() { return handleError(function (arg0) { - const ret = getObject(arg0).json(); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_text_65fa1887e8f7b4ac = function() { return handleError(function (arg0) { - const ret = getObject(arg0).text(); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_state_d5ffeae11b280151 = function() { return handleError(function (arg0) { - const ret = getObject(arg0).state; - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_pushState_b98021531274a207 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) { - getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5)); - }, arguments) }; imports.wbg.__wbg_value_664b8ba8bd4419b0 = function(arg0, arg1) { const ret = getObject(arg1).value; const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -619,6 +576,13 @@ function __wbg_get_imports() { const ret = getObject(arg0).host; return addHeapObject(ret); }; + imports.wbg.__wbg_state_d5ffeae11b280151 = function() { return handleError(function (arg0) { + const ret = getObject(arg0).state; + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_pushState_b98021531274a207 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) { + getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5)); + }, arguments) }; imports.wbg.__wbg_href_d45a5745a211a3da = function(arg0, arg1) { const ret = getObject(arg1).href; const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -639,24 +603,6 @@ function __wbg_get_imports() { imports.wbg.__wbg_setItem_e9a65f0e6892d9c9 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4)); }, arguments) }; - imports.wbg.__wbg_new_5cb136b036dd2286 = function() { return handleError(function () { - const ret = new URLSearchParams(); - return addHeapObject(ret); - }, arguments) }; - imports.wbg.__wbg_instanceof_WorkerGlobalScope_5188d176509513d4 = function(arg0) { - let result; - try { - result = getObject(arg0) instanceof WorkerGlobalScope; - } catch { - result = false; - } - const ret = result; - return ret; - }; - imports.wbg.__wbg_fetch_621998933558ad27 = function(arg0, arg1) { - const ret = getObject(arg0).fetch(getObject(arg1)); - return addHeapObject(ret); - }; imports.wbg.__wbg_instanceof_HtmlInputElement_a15913e00980dd9c = function(arg0) { let result; try { @@ -684,8 +630,29 @@ function __wbg_get_imports() { imports.wbg.__wbg_setvalue_7605619324f70225 = function(arg0, arg1, arg2) { getObject(arg0).value = getStringFromWasm0(arg1, arg2); }; - imports.wbg.__wbg_log_dc06ec929fc95a20 = function(arg0) { - console.log(getObject(arg0)); + imports.wbg.__wbg_add_9c791198ad871a5a = function() { return handleError(function (arg0, arg1, arg2) { + getObject(arg0).add(getStringFromWasm0(arg1, arg2)); + }, arguments) }; + imports.wbg.__wbg_remove_7643c63b1abb966b = function() { return handleError(function (arg0, arg1, arg2) { + getObject(arg0).remove(getStringFromWasm0(arg1, arg2)); + }, arguments) }; + imports.wbg.__wbg_new_5cb136b036dd2286 = function() { return handleError(function () { + const ret = new URLSearchParams(); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_instanceof_WorkerGlobalScope_5188d176509513d4 = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof WorkerGlobalScope; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_fetch_621998933558ad27 = function(arg0, arg1) { + const ret = getObject(arg0).fetch(getObject(arg1)); + return addHeapObject(ret); }; imports.wbg.__wbg_instanceof_Element_6fe31b975e43affc = function(arg0) { let result; @@ -728,11 +695,18 @@ function __wbg_get_imports() { imports.wbg.__wbg_setAttribute_1b177bcd399b9b56 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4)); }, arguments) }; - imports.wbg.__wbg_add_9c791198ad871a5a = function() { return handleError(function (arg0, arg1, arg2) { - getObject(arg0).add(getStringFromWasm0(arg1, arg2)); - }, arguments) }; - imports.wbg.__wbg_remove_7643c63b1abb966b = function() { return handleError(function (arg0, arg1, arg2) { - getObject(arg0).remove(getStringFromWasm0(arg1, arg2)); + imports.wbg.__wbg_instanceof_HtmlElement_bf2d86870dcd8306 = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof HTMLElement; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_focus_6baebc9f44af9925 = function() { return handleError(function (arg0) { + getObject(arg0).focus(); }, arguments) }; imports.wbg.__wbg_new_143b41b4342650bb = function() { return handleError(function () { const ret = new Headers(); @@ -767,23 +741,6 @@ function __wbg_get_imports() { const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2)); return addHeapObject(ret); }, arguments) }; - imports.wbg.__wbg_instanceof_HtmlElement_bf2d86870dcd8306 = function(arg0) { - let result; - try { - result = getObject(arg0) instanceof HTMLElement; - } catch { - result = false; - } - const ret = result; - return ret; - }; - imports.wbg.__wbg_focus_6baebc9f44af9925 = function() { return handleError(function (arg0) { - getObject(arg0).focus(); - }, arguments) }; - imports.wbg.__wbg_credentials_f0e7b21ccae12a71 = function(arg0) { - const ret = getObject(arg0).credentials; - return addHeapObject(ret); - }; imports.wbg.__wbg_create_5e9a0f618bfcf68e = function() { return handleError(function (arg0, arg1) { const ret = getObject(arg0).create(getObject(arg1)); return addHeapObject(ret); @@ -792,6 +749,17 @@ function __wbg_get_imports() { const ret = getObject(arg0).get(getObject(arg1)); return addHeapObject(ret); }, arguments) }; + imports.wbg.__wbg_credentials_f0e7b21ccae12a71 = function(arg0) { + const ret = getObject(arg0).credentials; + return addHeapObject(ret); + }; + imports.wbg.__wbg_getClientExtensionResults_33e0afe04994016a = function(arg0) { + const ret = getObject(arg0).getClientExtensionResults(); + return addHeapObject(ret); + }; + imports.wbg.__wbg_log_dc06ec929fc95a20 = function(arg0) { + console.log(getObject(arg0)); + }; imports.wbg.__wbg_instanceof_Event_32e538860e9889fb = function(arg0) { let result; try { @@ -829,10 +797,6 @@ function __wbg_get_imports() { const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2)); return addHeapObject(ret); }; - imports.wbg.__wbg_getClientExtensionResults_33e0afe04994016a = function(arg0) { - const ret = getObject(arg0).getClientExtensionResults(); - return addHeapObject(ret); - }; imports.wbg.__wbg_href_68df54cac0a34be4 = function() { return handleError(function (arg0, arg1) { const ret = getObject(arg1).href; const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -902,12 +866,6 @@ function __wbg_get_imports() { const ret = getObject(arg0).removeChild(getObject(arg1)); return addHeapObject(ret); }, arguments) }; - imports.wbg.__wbg_addEventListener_3a7d7c4177ce91d1 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { - getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4)); - }, arguments) }; - imports.wbg.__wbg_removeEventListener_315d6f929fccf484 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { - getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0); - }, arguments) }; imports.wbg.__wbg_href_1833451470322cf1 = function(arg0, arg1) { const ret = getObject(arg1).href; const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -950,6 +908,48 @@ function __wbg_get_imports() { const ret = new URL(getStringFromWasm0(arg0, arg1), getStringFromWasm0(arg2, arg3)); return addHeapObject(ret); }, arguments) }; + imports.wbg.__wbg_addEventListener_3a7d7c4177ce91d1 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4)); + }, arguments) }; + imports.wbg.__wbg_removeEventListener_315d6f929fccf484 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { + getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0); + }, arguments) }; + imports.wbg.__wbg_instanceof_HtmlFormElement_a67ff2b843593f03 = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof HTMLFormElement; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_Response_7ade9a5a066d1a55 = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof Response; + } catch { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_status_d2b2d0889f7e970f = function(arg0) { + const ret = getObject(arg0).status; + return ret; + }; + imports.wbg.__wbg_headers_2de03c88f895093b = function(arg0) { + const ret = getObject(arg0).headers; + return addHeapObject(ret); + }; + imports.wbg.__wbg_json_6c19bb86f10d6184 = function() { return handleError(function (arg0) { + const ret = getObject(arg0).json(); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_text_65fa1887e8f7b4ac = function() { return handleError(function (arg0) { + const ret = getObject(arg0).text(); + return addHeapObject(ret); + }, arguments) }; imports.wbg.__wbg_get_7303ed2ef026b2f5 = function(arg0, arg1) { const ret = getObject(arg0)[arg1 >>> 0]; return addHeapObject(ret); @@ -1162,16 +1162,16 @@ function __wbg_get_imports() { const ret = wasm.memory; return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper4692 = function(arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 1092, __wbg_adapter_48); + imports.wbg.__wbindgen_closure_wrapper4722 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1080, __wbg_adapter_48); return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper5577 = function(arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 1423, __wbg_adapter_51); + imports.wbg.__wbindgen_closure_wrapper5555 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1396, __wbg_adapter_51); return addHeapObject(ret); }; - imports.wbg.__wbindgen_closure_wrapper5655 = function(arg0, arg1, arg2) { - const ret = makeMutClosure(arg0, arg1, 1453, __wbg_adapter_54); + imports.wbg.__wbindgen_closure_wrapper5562 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1400, __wbg_adapter_54); return addHeapObject(ret); }; diff --git a/server/web_ui/pkg/kanidmd_web_ui_bg.wasm b/server/web_ui/pkg/kanidmd_web_ui_bg.wasm index aeacc72b6..2cf5a0660 100644 Binary files a/server/web_ui/pkg/kanidmd_web_ui_bg.wasm and b/server/web_ui/pkg/kanidmd_web_ui_bg.wasm differ diff --git a/server/web_ui/pkg/package.json b/server/web_ui/pkg/package.json index 41a046c91..0d90e989c 100644 --- a/server/web_ui/pkg/package.json +++ b/server/web_ui/pkg/package.json @@ -18,7 +18,5 @@ ], "module": "kanidmd_web_ui.js", "homepage": "https://github.com/kanidm/kanidm/", - "sideEffects": [ - "./snippets/*" - ] + "sideEffects": false } \ No newline at end of file diff --git a/server/web_ui/src/views/apps.rs b/server/web_ui/src/views/apps.rs index 09b1688f5..b07a9b731 100644 --- a/server/web_ui/src/views/apps.rs +++ b/server/web_ui/src/views/apps.rs @@ -107,7 +107,11 @@ impl AppsApp {

{ "Applications list" }

- if !apps.is_empty() { + if apps.is_empty() { +
+
{ "No linked applications available" }
+
+ } else {
{ apps.iter().map(|applink| {