keycloakify 11.4.0-rc.0 → 11.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +2 -0
  2. package/account/i18n/noJsx/getI18n.js +5 -7
  3. package/account/i18n/noJsx/getI18n.js.map +1 -1
  4. package/account/i18n/withJsx/useI18n.js +15 -4
  5. package/account/i18n/withJsx/useI18n.js.map +1 -1
  6. package/bin/20.index.js +0 -85
  7. package/bin/33.index.js +55 -212
  8. package/bin/356.index.js +106 -45
  9. package/bin/36.index.js +1 -2922
  10. package/bin/{526.index.js → 392.index.js} +89 -3
  11. package/bin/40.index.js +1 -86
  12. package/bin/453.index.js +85 -22
  13. package/bin/573.index.js +4 -86
  14. package/bin/653.index.js +752 -0
  15. package/bin/658.index.js +197 -0
  16. package/bin/735.index.js +343 -116
  17. package/bin/786.index.js +78 -14
  18. package/bin/805.index.js +15 -18
  19. package/bin/921.index.js +79 -18
  20. package/bin/97.index.js +64 -13
  21. package/bin/main.js +165 -86
  22. package/bin/shared/constants.d.ts +2 -0
  23. package/bin/shared/constants.js +3 -1
  24. package/bin/shared/constants.js.map +1 -1
  25. package/bin/start-keycloak/startViteDevServer.d.ts +7 -0
  26. package/bin/tools/crawlAsync.d.ts +1 -1
  27. package/bin/tools/isTrackedByGit.d.ts +3 -0
  28. package/bin/tools/runPrettier.d.ts +5 -5
  29. package/bin/tools/untrackFromGit.d.ts +3 -0
  30. package/lib/getKcClsx.js +1 -2
  31. package/lib/getKcClsx.js.map +1 -1
  32. package/login/KcContext/KcContext.d.ts +2 -2
  33. package/login/KcContext/kcContextMocks.d.ts +1 -1
  34. package/login/TemplateProps.d.ts +0 -1
  35. package/login/i18n/noJsx/getI18n.js +5 -7
  36. package/login/i18n/noJsx/getI18n.js.map +1 -1
  37. package/login/i18n/withJsx/useI18n.js +15 -4
  38. package/login/i18n/withJsx/useI18n.js.map +1 -1
  39. package/login/pages/LoginConfigTotp.js +1 -1
  40. package/login/pages/LoginConfigTotp.js.map +1 -1
  41. package/login/pages/LoginPasskeysConditionalAuthenticate.js +16 -18
  42. package/login/pages/LoginPasskeysConditionalAuthenticate.js.map +1 -1
  43. package/package.json +17 -7
  44. package/src/account/i18n/noJsx/getI18n.tsx +5 -7
  45. package/src/account/i18n/withJsx/useI18n.tsx +18 -4
  46. package/src/bin/eject-page.ts +28 -10
  47. package/src/bin/initialize-account-theme/initializeAccountTheme_singlePage.ts +3 -18
  48. package/src/bin/initialize-account-theme/updateAccountThemeImplementationInConfig.ts +1 -2
  49. package/src/bin/keycloakify/generateFtl/kcContextDeclarationTemplate.ftl +39 -0
  50. package/src/bin/keycloakify/generateResources/generateResources.ts +6 -2
  51. package/src/bin/main.ts +51 -4
  52. package/src/bin/postinstall/getUiModuleFileSourceCodeReadyToBeCopied.ts +30 -19
  53. package/src/bin/postinstall/installUiModulesPeerDependencies.ts +3 -3
  54. package/src/bin/postinstall/managedGitignoreFile.ts +4 -3
  55. package/src/bin/postinstall/postinstall.ts +24 -2
  56. package/src/bin/postinstall/uiModuleMeta.ts +14 -9
  57. package/src/bin/shared/buildContext.ts +1 -2
  58. package/src/bin/shared/constants.ts +4 -1
  59. package/src/bin/start-keycloak/myrealm-realm-25.json +21 -34
  60. package/src/bin/start-keycloak/myrealm-realm-26.json +32 -35
  61. package/src/bin/start-keycloak/start-keycloak.ts +93 -1
  62. package/src/bin/start-keycloak/startViteDevServer.ts +39 -0
  63. package/src/bin/tools/crawlAsync.ts +6 -6
  64. package/src/bin/tools/isTrackedByGit.ts +29 -0
  65. package/src/bin/tools/listInstalledModules.ts +1 -2
  66. package/src/bin/tools/npmInstall.ts +396 -1
  67. package/src/bin/tools/runPrettier.ts +63 -14
  68. package/src/bin/tools/untrackFromGit.ts +24 -0
  69. package/src/bin/tsconfig.json +1 -1
  70. package/src/bin/update-kc-gen.ts +17 -2
  71. package/src/lib/getKcClsx.ts +1 -2
  72. package/src/login/KcContext/KcContext.ts +2 -2
  73. package/src/login/KcContext/kcContextMocks.ts +1 -1
  74. package/src/login/TemplateProps.ts +0 -1
  75. package/src/login/i18n/noJsx/getI18n.tsx +5 -7
  76. package/src/login/i18n/withJsx/useI18n.tsx +18 -4
  77. package/src/login/pages/LoginConfigTotp.tsx +18 -20
  78. package/src/login/pages/LoginPasskeysConditionalAuthenticate.tsx +51 -52
  79. package/src/tools/StatefulObservable/StatefulObservable.ts +1 -2
  80. package/src/tools/deepAssign.ts +1 -2
  81. package/src/tools/extractLastParenthesisContent.ts +43 -0
  82. package/src/vite-plugin/vite-plugin.ts +67 -0
  83. package/stories/login/pages/Info.stories.tsx +3 -39
  84. package/tools/StatefulObservable/StatefulObservable.js +1 -2
  85. package/tools/StatefulObservable/StatefulObservable.js.map +1 -1
  86. package/tools/deepAssign.js +1 -2
  87. package/tools/deepAssign.js.map +1 -1
  88. package/tools/extractLastParenthesisContent.d.ts +6 -0
  89. package/tools/extractLastParenthesisContent.js +36 -0
  90. package/tools/extractLastParenthesisContent.js.map +1 -0
  91. package/vite-plugin/index.js +326 -186
  92. package/bin/124.index.js +0 -348
  93. package/stories/login/pages/LoginDeviceVerifyUserCode.stories.tsx +0 -18
@@ -38,6 +38,7 @@
38
38
  "bruteForceProtected": false,
39
39
  "permanentLockout": false,
40
40
  "maxTemporaryLockouts": 0,
41
+ "bruteForceStrategy": "MULTIPLE",
41
42
  "maxFailureWaitSeconds": 900,
42
43
  "minimumQuickLoginWaitSeconds": 60,
43
44
  "waitIncrementSeconds": 60,
@@ -604,6 +605,7 @@
604
605
  "frontchannelLogout": false,
605
606
  "protocol": "openid-connect",
606
607
  "attributes": {
608
+ "realm_client": "false",
607
609
  "post.logout.redirect.uris": "+"
608
610
  },
609
611
  "authenticationFlowBindingOverrides": {},
@@ -628,14 +630,16 @@
628
630
  "id": "d8f14dc4-5f0f-4a1d-8c0b-cfe78ee55cb3",
629
631
  "clientId": "account-console",
630
632
  "name": "${client_account-console}",
633
+ "description": "",
631
634
  "rootUrl": "${authBaseUrl}",
635
+ "adminUrl": "",
632
636
  "baseUrl": "/realms/myrealm/account/",
633
637
  "surrogateAuthRequired": false,
634
638
  "enabled": true,
635
639
  "alwaysDisplayInConsole": false,
636
640
  "clientAuthenticatorType": "client-secret",
637
- "redirectUris": ["/realms/myrealm/account/*"],
638
- "webOrigins": [],
641
+ "redirectUris": ["*"],
642
+ "webOrigins": ["*"],
639
643
  "notBefore": 0,
640
644
  "bearerOnly": false,
641
645
  "consentRequired": false,
@@ -647,8 +651,14 @@
647
651
  "frontchannelLogout": false,
648
652
  "protocol": "openid-connect",
649
653
  "attributes": {
654
+ "realm_client": "false",
655
+ "oidc.ciba.grant.enabled": "false",
656
+ "backchannel.logout.session.required": "true",
650
657
  "post.logout.redirect.uris": "+",
651
- "pkce.code.challenge.method": "S256"
658
+ "oauth2.device.authorization.grant.enabled": "false",
659
+ "display.on.consent.screen": "false",
660
+ "pkce.code.challenge.method": "S256",
661
+ "backchannel.logout.revoke.offline.tokens": "false"
652
662
  },
653
663
  "authenticationFlowBindingOverrides": {},
654
664
  "fullScopeAllowed": false,
@@ -699,10 +709,12 @@
699
709
  "frontchannelLogout": false,
700
710
  "protocol": "openid-connect",
701
711
  "attributes": {
712
+ "realm_client": "false",
713
+ "client.use.lightweight.access.token.enabled": "true",
702
714
  "post.logout.redirect.uris": "+"
703
715
  },
704
716
  "authenticationFlowBindingOverrides": {},
705
- "fullScopeAllowed": false,
717
+ "fullScopeAllowed": true,
706
718
  "nodeReRegistrationTimeout": 0,
707
719
  "defaultClientScopes": [
708
720
  "web-origins",
@@ -740,6 +752,7 @@
740
752
  "frontchannelLogout": false,
741
753
  "protocol": "openid-connect",
742
754
  "attributes": {
755
+ "realm_client": "true",
743
756
  "post.logout.redirect.uris": "+"
744
757
  },
745
758
  "authenticationFlowBindingOverrides": {},
@@ -789,6 +802,7 @@
789
802
  "frontchannelLogout": true,
790
803
  "protocol": "openid-connect",
791
804
  "attributes": {
805
+ "realm_client": "false",
792
806
  "oidc.ciba.grant.enabled": "false",
793
807
  "backchannel.logout.session.required": "true",
794
808
  "login_theme": "keycloakify-starter",
@@ -855,6 +869,7 @@
855
869
  "frontchannelLogout": false,
856
870
  "protocol": "openid-connect",
857
871
  "attributes": {
872
+ "realm_client": "true",
858
873
  "post.logout.redirect.uris": "+"
859
874
  },
860
875
  "authenticationFlowBindingOverrides": {},
@@ -898,11 +913,13 @@
898
913
  "frontchannelLogout": false,
899
914
  "protocol": "openid-connect",
900
915
  "attributes": {
916
+ "realm_client": "false",
917
+ "client.use.lightweight.access.token.enabled": "true",
901
918
  "post.logout.redirect.uris": "+",
902
919
  "pkce.code.challenge.method": "S256"
903
920
  },
904
921
  "authenticationFlowBindingOverrides": {},
905
- "fullScopeAllowed": false,
922
+ "fullScopeAllowed": true,
906
923
  "nodeReRegistrationTimeout": 0,
907
924
  "protocolMappers": [
908
925
  {
@@ -1574,14 +1591,14 @@
1574
1591
  "subComponents": {},
1575
1592
  "config": {
1576
1593
  "allowed-protocol-mapper-types": [
1594
+ "saml-user-attribute-mapper",
1595
+ "oidc-sha256-pairwise-sub-mapper",
1577
1596
  "oidc-full-name-mapper",
1578
- "oidc-usermodel-attribute-mapper",
1597
+ "saml-user-property-mapper",
1579
1598
  "oidc-address-mapper",
1580
- "saml-user-attribute-mapper",
1581
1599
  "oidc-usermodel-property-mapper",
1582
- "saml-user-property-mapper",
1583
1600
  "saml-role-list-mapper",
1584
- "oidc-sha256-pairwise-sub-mapper"
1601
+ "oidc-usermodel-attribute-mapper"
1585
1602
  ]
1586
1603
  }
1587
1604
  },
@@ -1611,14 +1628,14 @@
1611
1628
  "subComponents": {},
1612
1629
  "config": {
1613
1630
  "allowed-protocol-mapper-types": [
1614
- "oidc-sha256-pairwise-sub-mapper",
1615
- "oidc-usermodel-property-mapper",
1616
- "oidc-address-mapper",
1617
1631
  "oidc-usermodel-attribute-mapper",
1618
1632
  "oidc-full-name-mapper",
1619
- "saml-user-attribute-mapper",
1633
+ "oidc-usermodel-property-mapper",
1634
+ "oidc-address-mapper",
1620
1635
  "saml-user-property-mapper",
1621
- "saml-role-list-mapper"
1636
+ "saml-role-list-mapper",
1637
+ "saml-user-attribute-mapper",
1638
+ "oidc-sha256-pairwise-sub-mapper"
1622
1639
  ]
1623
1640
  }
1624
1641
  },
@@ -1671,13 +1688,6 @@
1671
1688
  "providerId": "rsa-generated",
1672
1689
  "subComponents": {},
1673
1690
  "config": {
1674
- "privateKey": [
1675
- "MIIEowIBAAKCAQEAsYUWzVfZMd6ywpBmLJYeF1U9Mgd/z3xWvl1Yq76oRPPfpcqQitN+cktWqu0hPerCVSl2ltwXDMrUwFzswG9MiM9hb+BLEld7kYiYkcFNt3lCtmmeRQEae7JwWimzeNV96Qlz0tHY8f9Zh0ffPDsLTN1HGAeRJJhI7mNQm6qCJNMCfVA/O5SWumsIn2XLnSMiQ05AACVHOLUq6rAZ2zCCaYmXTmJkuSOb8e26V303P6l63DSe5HSNXDdI00tjfFFf37q870zhvfsotrjjx0RMijy9Kjj8OZF+pFHpDRaGEi8tpQxZDnCTofTieB/Vp3QP+aTlvAyD3Q1ZnJxGQCLygwIDAQABAoIBABUJ9XMJGNQzamiVwuOWN7ht4UP8ezYvgdEA8NaLUO0PIYVIKyD7l4OwkHPPM9PfRACM2qG0MZp8sCyg4WxIeepy+D979oRqJYUmNRLSipqWlASuItRXIPjiY99uYXdjh2R8Os5pvCD+MZxPX9KHGuaVXmzSJMO7YAAPeYkMHcLYTp/U0c65Ztaaz1zz1FeyvpjkLr9SHiMcIN51zFmhvT1tcRIqy4zidisjrTSUr/KPVxeJtrEfyhTGk3z41yJf5YbeaxaMjJR5x0WXzt1fWVmA/V1bWa2Zlj9d8AxDReA1p7Lpstz34PRoCMj9bmFguI2+RTw6K0D++Jydfxmh8vUCgYEA5Zwk2r3TFO3i3V70LOn6CLzn15yLeuSIJ9p2os70jQOmFMCreLdcUbCaiUe7UV/IIVftbcxhFm9zECXZXX0wubcmHZqyptlbuAn1de4QkLJixXo1A7ZQXBEZk22WN2naXHQF5oK6lh/VSLcZBajTsyvBm5JWXrd8djjG06MugA8CgYEAxexKI5IwcLhpMDV9UPQb/+lDWHVqCT2xwYxnZ85y+5gmrOyyT7mIChz3DFYiaw4CHJWmBkIDBaiDgLEgQk4QXWzYshXawShBHnv1h08bVMMw98Ivec7ZRkV+/ET30YRwC2Uyk4bm4HpwVV5GCFhC4aAvRcCA1CIJk3MwcOwksk0CgYEAqxyaOomMbOR7VQ4WWgJkW26sOHppV8RH06tzDhG9HfnCI2USZHwBSL+b6wKSDiqbMn4cat8M23NjBH2wZ4OMdFqRBS7sRHtnZtfFHYW0wqCuCwzvxTxw1qvHq57Xe6RfHtc4LnjuJELE59PLyfPvEG9jcVS1GREUp+XYBpBtbvECgYAMhWBDU9JAr0noRNoCrw6+Z9Fc3UCyCPcf2XQJOyRHCl8X/XliVchna2GtpB1VTHORv13bc32hdAGtuIbj6vBaGLK0wXEvWw6TkR/9SWHfQOHuKpi6Sf2w1mCsMOjElm5IKkTC1Hvyo4xLukUP7hV9FJcpAH6l7OlSLK1Z13aS2QKBgB6w4gvmVEQruHV5+K60OatuFojr+kxJwmzCb5uKOULUFezT2pA3p3l6IWxGL2XtM+LD0SiZE3KZJUzf+LatYlBU9ek4F1krkVNUTRZpzUa0oADbymCL1chM4oPIs7sISQlFIH2wOSZt6Blvcw0E0wfjd9Gv/LHxcMnlRb1t1sLk"
1676
- ],
1677
- "keyUse": ["SIG"],
1678
- "certificate": [
1679
- "MIICnTCCAYUCBgGQBsyplzANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MDYxMTEwMTQ1NFoXDTM0MDYxMTEwMTYzNFowEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALGFFs1X2THessKQZiyWHhdVPTIHf898Vr5dWKu+qETz36XKkIrTfnJLVqrtIT3qwlUpdpbcFwzK1MBc7MBvTIjPYW/gSxJXe5GImJHBTbd5QrZpnkUBGnuycFops3jVfekJc9LR2PH/WYdH3zw7C0zdRxgHkSSYSO5jUJuqgiTTAn1QPzuUlrprCJ9ly50jIkNOQAAlRzi1KuqwGdswgmmJl05iZLkjm/Htuld9Nz+petw0nuR0jVw3SNNLY3xRX9+6vO9M4b37KLa448dETIo8vSo4/DmRfqRR6Q0WhhIvLaUMWQ5wk6H04ngf1ad0D/mk5bwMg90NWZycRkAi8oMCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAVS+gJshIFX6cmBGI8UaOOI/9+XFb4Gi+DHaHVWVVHTd14MoqNK1bmmyTHbGIZbvK8UqgJ9+FhJX1ejx17d4KBzkZI3tYvPnVacHvaw1CIUMZ1Ini6u+UGUTnIlnQzCG0pcTKjOZXf3ih1B2CKdwyC7XeXyEJHicAIG7XfzYfYd9DYHvA+h6hrXaQcNJMW7WFNbtb3fJhtlv5P1Iw+ZEGdj15ukMI0bg2OEQA0F3jIw6QZpigSAGuai3HOY6OgoPO82d7TyTYlNhuwyutWr9izl6QMc2R7BmRfW9XQj4ICR2VWJiL9nqz+SOyqnjQiOObuw8Vywb8c36R1Ym1aaGjOw=="
1680
- ],
1681
1691
  "priority": ["100"]
1682
1692
  }
1683
1693
  },
@@ -1687,13 +1697,6 @@
1687
1697
  "providerId": "rsa-enc-generated",
1688
1698
  "subComponents": {},
1689
1699
  "config": {
1690
- "privateKey": [
1691
- "MIIEogIBAAKCAQEAkQtefHy82e8d5dVWN00LnGI5YmBOTKh0tgqayVRjqLH6u3NfgJVVIe0tFnxa7Wka/ySHrn1KSsW52czZ4uPXLUo4sXBkQxyyFXeZiWN8H+9WiUQ+0hefZF4es5ZPhY2VpeMK9XAnphC362LFLVycXulkpJcQ+4DjI99To4LLyJmjQvsVaJ7amoVJ5xd62eUv+D7f2+jwuaTwjGE3+MWZADXjVxsUY1qJuGLGKnLkNNxJNMDhvnKYw+aa3Z4V90fQVyjN1Volgw3DdA59o4wrWEy+2xHc6j2ESi8+cM60fWzZU9sp2XkyJoCnV7nmwk7pZkDy3zvAkeOWzrr3OWeR3wIDAQABAoIBACWMcet8R0+L7YuATQ+H7IeRjhV/pQWHXp9541RXem1DlgtM9N5Oynk78z4s90Uavphqlo1/deohgdl2hLmODjh1THPzCqGtHhUcnyzICmwiA58JgdHVt7e9/eiz8uY6HxGQ01dyr3D4RwSyzyTNItYXSayqRwU0+phgykA8LhFCAQM/UkRXDf6UCFKBhDyE7VPBaDv0xyxNb7dKtE7C6Qo5t5D40xCfQ8ni8OcD5RvshQq5xOWcw7igxAhlmXCu1fuO2CDiSiqXLMENs4NlwilQ3caMXAIzUiblaKwCrrK2noBoitx6vuOR2tKmIZSlTyDAG4vLQQtOHk53hBoupGECgYEAx4jSmLM9uUzNwNY1zfs8iNswxbU3YibNe2Q+IFmOQofvTaq1jBBxdPWX5ifIbuTvOAA33pmJRh+BtWzOBBQC7Z4i9mdfvyWB6s8t9nnTnWIY5Hj+hV5gaqae59MjdudsORR887fxzPIeAwwaETfKaZnYpC6zLaE3BXwhIcjlFTcCgYEAuhcKf16JkEYNIwanVHpUXjFxwAThAogHWZAngRokmai67Iulx+rSUhhtOIXtmjj/EaObsrqo5yCKAVZ5EbPTOajdd9RtFzH6q3bRjRdp8o8ZVx4c1vMNaOnLbvK4YzJlKSZN9N7m255Mg+/ea3veKVZsSVHDMnuYmH8GjncjPJkCgYAOIUlQmPjZA3BapJDA2nbJ9kO47IFUiQzqHQotPkpNudSfemRK2+s87htoqA6Qk9PA8nsCX3sSJS8JSwA317bxXs55Bo8IOT6/AxbtKmlq7sR2gX78sNdBFjWQkyoixHasgB/tHmyYJ9kqPBQoffvuiH+H+OqlY5JC6CxseQ6H9wKBgF69Hj4MDjLiRwve9k9+2/b8azHcCgX05PEG/+WtPpbwHQIScnseJKdhAjH1lSqf+9OqHLlYaGcK3Nejg42spEvFmcLI5iUZ78lde3++PNUdX0RH81zHbrtL06MPdSojXPcfJi8VUCjdJY1CEFVeQZOACS8mrh7EZ8KzYM4k/055AoGAYqjBv3WS8ul7kAsjpZKpIw1QZZaTjBSmLpjB6X8InF+Zihjgm80Dd4RMFnMnEawhFBvnpklvyw5Ce6NSwcC137kN3NVpJypykkXuYkimg7OxgJjR7YFdbQWJWlc+1eB81WTHcEOHVI/DmeV2yVJcv6kA2iC+3/JA0VoJxvrRBKc="
1692
- ],
1693
- "keyUse": ["ENC"],
1694
- "certificate": [
1695
- "MIICnTCCAYUCBgGQBsyq0jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdteXJlYWxtMB4XDTI0MDYxMTEwMTQ1NFoXDTM0MDYxMTEwMTYzNFowEjEQMA4GA1UEAwwHbXlyZWFsbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJELXnx8vNnvHeXVVjdNC5xiOWJgTkyodLYKmslUY6ix+rtzX4CVVSHtLRZ8Wu1pGv8kh659SkrFudnM2eLj1y1KOLFwZEMcshV3mYljfB/vVolEPtIXn2ReHrOWT4WNlaXjCvVwJ6YQt+tixS1cnF7pZKSXEPuA4yPfU6OCy8iZo0L7FWie2pqFSecXetnlL/g+39vo8Lmk8IxhN/jFmQA141cbFGNaibhixipy5DTcSTTA4b5ymMPmmt2eFfdH0FcozdVaJYMNw3QOfaOMK1hMvtsR3Oo9hEovPnDOtH1s2VPbKdl5MiaAp1e55sJO6WZA8t87wJHjls669zlnkd8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAD9wQ+CJ0FRgls3JrUzxwHLgrJ3Yo4+mDFpSe1rh2XYK5FEIWDWSqxaXI3p0cOZq75RZmI2xV8oaiJMUz9WMZkbNe/KtGRzHY1N9AZooicGIsnFu1t++b8taFxxpvKWZgnbOum2PZlfcNiXL0QeMv0wwhfn9zKA9W1DRcqYGbIamoyVlumvbNyIjqXJKwGYIOW6GNt7v3wJl5AJw8qAU/O/DQwWwmzcnFGNRxRxAwI7we8EiQ5JlG0Wi+nyAQn74o3RhNr3zsY0ndmFx9bFV4BBo2AiYGozCDOCCG5HvrmoDbrm//wmGRv0tCwueBzWHL2mhtbZ6sGWmMWfiTJ2HPpg=="
1696
- ],
1697
1700
  "priority": ["100"],
1698
1701
  "algorithm": ["RSA-OAEP"]
1699
1702
  }
@@ -1704,8 +1707,6 @@
1704
1707
  "providerId": "aes-generated",
1705
1708
  "subComponents": {},
1706
1709
  "config": {
1707
- "kid": ["1c1d0c8a-6f0b-48a9-a66f-488489137d85"],
1708
- "secret": ["N4wzheVYYBWxFn9VGWTPQQ"],
1709
1710
  "priority": ["100"]
1710
1711
  }
1711
1712
  },
@@ -1715,10 +1716,6 @@
1715
1716
  "providerId": "hmac-generated",
1716
1717
  "subComponents": {},
1717
1718
  "config": {
1718
- "kid": ["ce43821c-6cfd-4ea9-a29a-a724a37e6955"],
1719
- "secret": [
1720
- "j_8WeQHYt5R6coay0IOUeu9hGvCoJsgnENSoYm0gDlDx6IHOg-f6p17QIaesNmgrzXtJDRpYMhSjpTMHOnHCHLxwUM4eVg9TcszffndB850Yj3PHPeCc5aoHcpYzWN9NDZZ02nBYA04nfbkdlLXiGlpS3I3e502e4DX3rFtbFZ0"
1721
- ],
1722
1719
  "priority": ["100"],
1723
1720
  "algorithm": ["HS512"]
1724
1721
  }
@@ -2388,7 +2385,7 @@
2388
2385
  "clientSessionMaxLifespan": "0",
2389
2386
  "organizationsEnabled": "false"
2390
2387
  },
2391
- "keycloakVersion": "25.0.0",
2388
+ "keycloakVersion": "26.0.6",
2392
2389
  "userManagedAccessAllowed": false,
2393
2390
  "organizationsEnabled": false,
2394
2391
  "clientProfiles": {
@@ -1,7 +1,7 @@
1
1
  import type { BuildContext } from "../shared/buildContext";
2
2
  import { exclude } from "tsafe/exclude";
3
3
  import { promptKeycloakVersion } from "../shared/promptKeycloakVersion";
4
- import { CONTAINER_NAME } from "../shared/constants";
4
+ import { CONTAINER_NAME, KEYCLOAKIFY_SPA_DEV_SERVER_PORT } from "../shared/constants";
5
5
  import { SemVer } from "../tools/SemVer";
6
6
  import { assert, type Equals } from "tsafe/assert";
7
7
  import * as fs from "fs";
@@ -27,6 +27,7 @@ import { isInside } from "../tools/isInside";
27
27
  import { existsAsync } from "../tools/fs.existsAsync";
28
28
  import { rm } from "../tools/fs.rm";
29
29
  import { downloadAndExtractArchive } from "../tools/downloadAndExtractArchive";
30
+ import { startViteDevServer } from "./startViteDevServer";
30
31
 
31
32
  export async function command(params: {
32
33
  buildContext: BuildContext;
@@ -379,6 +380,54 @@ export async function command(params: {
379
380
  const port =
380
381
  cliCommandOptions.port ?? buildContext.startKeycloakOptions.port ?? DEFAULT_PORT;
381
382
 
383
+ const devServerPort = (() => {
384
+ const hasSpaUi =
385
+ buildContext.implementedThemeTypes.admin.isImplemented ||
386
+ (buildContext.implementedThemeTypes.account.isImplemented &&
387
+ buildContext.implementedThemeTypes.account.type === "Single-Page");
388
+
389
+ if (!hasSpaUi) {
390
+ return undefined;
391
+ }
392
+
393
+ if (buildContext.bundler !== "vite") {
394
+ console.log(
395
+ chalk.yellow(
396
+ [
397
+ `WARNING: Since you are using ${buildContext.bundler} instead of Vite,`,
398
+ `you'll have to wait serval seconds for the changes you made on your account or admin theme to be reflected in the browser.\n`,
399
+ `For a better development experience, consider migrating to Vite.`
400
+ ].join(" ")
401
+ )
402
+ );
403
+
404
+ return undefined;
405
+ }
406
+
407
+ if (keycloakMajorVersionNumber < 25) {
408
+ console.log(
409
+ chalk.yellow(
410
+ [
411
+ `WARNING: Your account or admin theme can't be tested with hot module replacement on Keycloak ${keycloakMajorVersionNumber}.`,
412
+ `This mean that you'll have to wait serval seconds for the changes to be reflected in the browser.`,
413
+ `For a better development experience, select a more recent version of Keycloak.`
414
+ ].join("\n")
415
+ )
416
+ );
417
+
418
+ return undefined;
419
+ }
420
+
421
+ return port + 1;
422
+ })();
423
+
424
+ if (devServerPort !== undefined) {
425
+ startViteDevServer({
426
+ buildContext,
427
+ port: devServerPort
428
+ });
429
+ }
430
+
382
431
  const SPACE_PLACEHOLDER = "SPACE_PLACEHOLDER_xKLmdPd";
383
432
 
384
433
  const dockerRunArgs: string[] = [
@@ -386,6 +435,11 @@ export async function command(params: {
386
435
  `--name${SPACE_PLACEHOLDER}${CONTAINER_NAME}`,
387
436
  `-e${SPACE_PLACEHOLDER}KEYCLOAK_ADMIN=admin`,
388
437
  `-e${SPACE_PLACEHOLDER}KEYCLOAK_ADMIN_PASSWORD=admin`,
438
+ ...(devServerPort === undefined
439
+ ? []
440
+ : [
441
+ `-e${SPACE_PLACEHOLDER}${KEYCLOAKIFY_SPA_DEV_SERVER_PORT}=${devServerPort}`
442
+ ]),
389
443
  ...(buildContext.startKeycloakOptions.dockerExtraArgs.length === 0
390
444
  ? []
391
445
  : [
@@ -592,6 +646,44 @@ export async function command(params: {
592
646
  }
593
647
  )
594
648
  .on("all", async (...[, filePath]) => {
649
+ ignore_account_spa: {
650
+ const doImplementAccountSpa =
651
+ buildContext.implementedThemeTypes.account.isImplemented &&
652
+ buildContext.implementedThemeTypes.account.type === "Single-Page";
653
+
654
+ if (!doImplementAccountSpa) {
655
+ break ignore_account_spa;
656
+ }
657
+
658
+ if (
659
+ !isInside({
660
+ dirPath: pathJoin(buildContext.themeSrcDirPath, "account"),
661
+ filePath
662
+ })
663
+ ) {
664
+ break ignore_account_spa;
665
+ }
666
+
667
+ return;
668
+ }
669
+
670
+ ignore_admin: {
671
+ if (!buildContext.implementedThemeTypes.admin.isImplemented) {
672
+ break ignore_admin;
673
+ }
674
+
675
+ if (
676
+ !isInside({
677
+ dirPath: pathJoin(buildContext.themeSrcDirPath, "admin"),
678
+ filePath
679
+ })
680
+ ) {
681
+ break ignore_admin;
682
+ }
683
+
684
+ return;
685
+ }
686
+
595
687
  console.log(`Detected changes in ${filePath}`);
596
688
 
597
689
  await waitForDebounce();
@@ -0,0 +1,39 @@
1
+ import * as child_process from "child_process";
2
+ import { assert } from "tsafe/assert";
3
+ import type { BuildContext } from "../shared/buildContext";
4
+ import chalk from "chalk";
5
+ import { VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES } from "../shared/constants";
6
+
7
+ export type BuildContextLike = {
8
+ projectDirPath: string;
9
+ };
10
+
11
+ assert<BuildContext extends BuildContextLike ? true : false>();
12
+
13
+ export function startViteDevServer(params: {
14
+ buildContext: BuildContextLike;
15
+ port: number;
16
+ }): void {
17
+ const { buildContext, port } = params;
18
+
19
+ console.log(chalk.blue(`$ npx vite dev --port ${port}`));
20
+
21
+ const child = child_process.spawn("npx", ["vite", "dev", "--port", `${port}`], {
22
+ cwd: buildContext.projectDirPath,
23
+ env: {
24
+ ...process.env,
25
+ [VITE_PLUGIN_SUB_SCRIPTS_ENV_NAMES.READ_KC_CONTEXT_FROM_URL]: "true"
26
+ },
27
+ shell: true
28
+ });
29
+
30
+ child.stdout.on("data", data => {
31
+ if (!data.toString("utf8").includes("[vite] hmr")) {
32
+ return;
33
+ }
34
+
35
+ process.stdout.write(data);
36
+ });
37
+
38
+ child.stderr.on("data", data => process.stderr.write(data));
39
+ }
@@ -6,19 +6,19 @@ import { assert, type Equals } from "tsafe/assert";
6
6
  export async function crawlAsync(params: {
7
7
  dirPath: string;
8
8
  returnedPathsType: "absolute" | "relative to dirPath";
9
- onFileFound: (filePath: string) => void;
9
+ onFileFound: (filePath: string) => Promise<void>;
10
10
  }) {
11
11
  const { dirPath, returnedPathsType, onFileFound } = params;
12
12
 
13
13
  await crawlAsyncRec({
14
14
  dirPath,
15
- onFileFound: ({ filePath }) => {
15
+ onFileFound: async ({ filePath }) => {
16
16
  switch (returnedPathsType) {
17
17
  case "absolute":
18
- onFileFound(filePath);
18
+ await onFileFound(filePath);
19
19
  return;
20
20
  case "relative to dirPath":
21
- onFileFound(pathRelative(dirPath, filePath));
21
+ await onFileFound(pathRelative(dirPath, filePath));
22
22
  return;
23
23
  }
24
24
  assert<Equals<typeof returnedPathsType, never>>();
@@ -28,7 +28,7 @@ export async function crawlAsync(params: {
28
28
 
29
29
  async function crawlAsyncRec(params: {
30
30
  dirPath: string;
31
- onFileFound: (params: { filePath: string }) => void;
31
+ onFileFound: (params: { filePath: string }) => Promise<void>;
32
32
  }) {
33
33
  const { dirPath, onFileFound } = params;
34
34
 
@@ -45,7 +45,7 @@ async function crawlAsyncRec(params: {
45
45
  return;
46
46
  }
47
47
 
48
- onFileFound({ filePath: fileOrDirPath });
48
+ await onFileFound({ filePath: fileOrDirPath });
49
49
  })
50
50
  );
51
51
  }
@@ -0,0 +1,29 @@
1
+ import * as child_process from "child_process";
2
+ import { dirname as pathDirname, basename as pathBasename } from "path";
3
+ import { Deferred } from "evt/tools/Deferred";
4
+
5
+ export function getIsTrackedByGit(params: { filePath: string }): Promise<boolean> {
6
+ const { filePath } = params;
7
+
8
+ const dIsTracked = new Deferred<boolean>();
9
+
10
+ child_process.exec(
11
+ `git ls-files --error-unmatch ${pathBasename(filePath)}`,
12
+ { cwd: pathDirname(filePath) },
13
+ error => {
14
+ if (error === null) {
15
+ dIsTracked.resolve(true);
16
+ return;
17
+ }
18
+
19
+ if (error.code === 1) {
20
+ dIsTracked.resolve(false);
21
+ return;
22
+ }
23
+
24
+ dIsTracked.reject(error);
25
+ }
26
+ );
27
+
28
+ return dIsTracked.pr;
29
+ }
@@ -1,9 +1,8 @@
1
- import { assert, type Equals } from "tsafe/assert";
1
+ import { assert, type Equals, is } from "tsafe/assert";
2
2
  import { id } from "tsafe/id";
3
3
  import { z } from "zod";
4
4
  import { join as pathJoin, dirname as pathDirname } from "path";
5
5
  import * as fsPr from "fs/promises";
6
- import { is } from "tsafe/is";
7
6
  import { getInstalledModuleDirPath } from "../tools/getInstalledModuleDirPath";
8
7
  import { exclude } from "tsafe/exclude";
9
8