keycloakify 11.4.4 → 11.5.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 (94) hide show
  1. package/account/i18n/withJsx/GenericI18n.d.ts +1 -1
  2. package/account/i18n/withJsx/GenericI18n.js.map +1 -1
  3. package/account/i18n/withJsx/useI18n.js.map +1 -1
  4. package/account/pages/PageProps.d.ts +1 -1
  5. package/bin/375.index.js +4089 -0
  6. package/bin/{20.index.js → 490.index.js} +378 -56
  7. package/bin/{36.index.js → 503.index.js} +53 -2
  8. package/bin/{450.index.js → 525.index.js} +2 -4085
  9. package/bin/653.index.js +108 -110
  10. package/bin/682.index.js +1885 -0
  11. package/bin/735.index.js +107 -109
  12. package/bin/921.index.js +1 -1
  13. package/bin/main.js +8 -2
  14. package/bin/shared/constants.d.ts +3 -0
  15. package/bin/shared/constants.js +3 -0
  16. package/bin/shared/constants.js.map +1 -1
  17. package/bin/start-keycloak/getSupportedDockerImageTags.d.ts +8 -0
  18. package/bin/start-keycloak/realmConfig/ParsedRealmJson.d.ts +38 -0
  19. package/bin/start-keycloak/realmConfig/defaultConfig/defaultConfig.d.ts +8 -0
  20. package/bin/start-keycloak/realmConfig/defaultConfig/index.d.ts +1 -0
  21. package/bin/start-keycloak/realmConfig/dumpContainerConfig.d.ts +9 -0
  22. package/bin/start-keycloak/realmConfig/index.d.ts +1 -0
  23. package/bin/start-keycloak/realmConfig/prepareRealmConfig.d.ts +15 -0
  24. package/bin/start-keycloak/realmConfig/realmConfig.d.ts +16 -0
  25. package/login/DefaultPage.d.ts +2 -1
  26. package/login/DefaultPage.js.map +1 -1
  27. package/login/UserProfileFormFields.d.ts +1 -1
  28. package/login/UserProfileFormFields.js.map +1 -1
  29. package/login/UserProfileFormFieldsProps.d.ts +1 -0
  30. package/login/i18n/withJsx/GenericI18n.d.ts +1 -1
  31. package/login/i18n/withJsx/GenericI18n.js.map +1 -1
  32. package/login/i18n/withJsx/useI18n.js.map +1 -1
  33. package/login/lib/useUserProfileForm.d.ts +1 -1
  34. package/login/lib/useUserProfileForm.js.map +1 -1
  35. package/login/pages/IdpReviewUserProfile.d.ts +2 -1
  36. package/login/pages/IdpReviewUserProfile.js.map +1 -1
  37. package/login/pages/Login.d.ts +1 -1
  38. package/login/pages/Login.js.map +1 -1
  39. package/login/pages/LoginPassword.d.ts +1 -1
  40. package/login/pages/LoginPassword.js.map +1 -1
  41. package/login/pages/LoginUpdatePassword.d.ts +1 -1
  42. package/login/pages/LoginUpdatePassword.js.map +1 -1
  43. package/login/pages/LoginUpdateProfile.d.ts +2 -1
  44. package/login/pages/LoginUpdateProfile.js.map +1 -1
  45. package/login/pages/PageProps.d.ts +1 -1
  46. package/login/pages/Register.d.ts +2 -1
  47. package/login/pages/Register.js.map +1 -1
  48. package/login/pages/UpdateEmail.d.ts +2 -1
  49. package/login/pages/UpdateEmail.js.map +1 -1
  50. package/package.json +35 -14
  51. package/src/account/i18n/withJsx/GenericI18n.tsx +1 -0
  52. package/src/account/i18n/withJsx/useI18n.tsx +1 -0
  53. package/src/account/pages/PageProps.ts +1 -0
  54. package/src/bin/shared/constants.ts +6 -0
  55. package/src/bin/start-keycloak/getSupportedDockerImageTags.ts +230 -0
  56. package/src/bin/start-keycloak/keycloakify-logging-1.0.3.jar +0 -0
  57. package/src/bin/start-keycloak/realmConfig/ParsedRealmJson.ts +118 -0
  58. package/src/bin/start-keycloak/realmConfig/defaultConfig/defaultConfig.ts +75 -0
  59. package/src/bin/start-keycloak/realmConfig/defaultConfig/index.ts +1 -0
  60. package/src/bin/start-keycloak/{myrealm-realm-18.json → realmConfig/defaultConfig/realm-kc-18.json} +123 -60
  61. package/src/bin/start-keycloak/{myrealm-realm-19.json → realmConfig/defaultConfig/realm-kc-19.json} +81 -41
  62. package/src/bin/start-keycloak/{myrealm-realm-20.json → realmConfig/defaultConfig/realm-kc-20.json} +83 -42
  63. package/src/bin/start-keycloak/{myrealm-realm-21.json → realmConfig/defaultConfig/realm-kc-21.json} +58 -17
  64. package/src/bin/start-keycloak/{myrealm-realm-23.json → realmConfig/defaultConfig/realm-kc-23.json} +64 -20
  65. package/src/bin/start-keycloak/{myrealm-realm-24.json → realmConfig/defaultConfig/realm-kc-24.json} +63 -19
  66. package/src/bin/start-keycloak/{myrealm-realm-25.json → realmConfig/defaultConfig/realm-kc-25.json} +75 -20
  67. package/src/bin/start-keycloak/{myrealm-realm-26.json → realmConfig/defaultConfig/realm-kc-26.json} +86 -20
  68. package/src/bin/start-keycloak/realmConfig/dumpContainerConfig.ts +147 -0
  69. package/src/bin/start-keycloak/realmConfig/index.ts +1 -0
  70. package/src/bin/start-keycloak/realmConfig/prepareRealmConfig.ts +302 -0
  71. package/src/bin/start-keycloak/realmConfig/realmConfig.ts +151 -0
  72. package/src/bin/start-keycloak/start-keycloak.ts +160 -184
  73. package/src/bin/start-keycloak/startViteDevServer.ts +1 -0
  74. package/src/login/DefaultPage.tsx +1 -0
  75. package/src/login/UserProfileFormFields.tsx +1 -0
  76. package/src/login/UserProfileFormFieldsProps.tsx +1 -0
  77. package/src/login/i18n/withJsx/GenericI18n.tsx +1 -0
  78. package/src/login/i18n/withJsx/useI18n.tsx +1 -0
  79. package/src/login/lib/useUserProfileForm.tsx +1 -0
  80. package/src/login/pages/IdpReviewUserProfile.tsx +1 -0
  81. package/src/login/pages/Login.tsx +1 -0
  82. package/src/login/pages/LoginPassword.tsx +1 -0
  83. package/src/login/pages/LoginUpdatePassword.tsx +1 -0
  84. package/src/login/pages/LoginUpdateProfile.tsx +1 -0
  85. package/src/login/pages/PageProps.ts +1 -0
  86. package/src/login/pages/Register.tsx +1 -0
  87. package/src/login/pages/UpdateEmail.tsx +1 -0
  88. package/src/tools/JSX.ts +5 -0
  89. package/tools/JSX.d.ts +5 -0
  90. package/tools/JSX.js +2 -0
  91. package/tools/JSX.js.map +1 -0
  92. package/vite-plugin/index.js +6 -0
  93. package/bin/392.index.js +0 -740
  94. package/bin/932.index.js +0 -327
@@ -0,0 +1,230 @@
1
+ import fetch from "make-fetch-happen";
2
+ import type { BuildContext } from "../shared/buildContext";
3
+ import { assert, type Equals } from "tsafe/assert";
4
+ import { id } from "tsafe/id";
5
+ import { z } from "zod";
6
+ import { SemVer } from "../tools/SemVer";
7
+ import { exclude } from "tsafe/exclude";
8
+ import { getSupportedKeycloakMajorVersions } from "./realmConfig/defaultConfig";
9
+ import { join as pathJoin, dirname as pathDirname } from "path";
10
+ import * as fs from "fs/promises";
11
+ import { existsAsync } from "../tools/fs.existsAsync";
12
+ import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion";
13
+
14
+ export type BuildContextLike = {
15
+ fetchOptions: BuildContext["fetchOptions"];
16
+ cacheDirPath: string;
17
+ };
18
+
19
+ assert<BuildContext extends BuildContextLike ? true : false>;
20
+
21
+ export async function getSupportedDockerImageTags(params: {
22
+ buildContext: BuildContextLike;
23
+ }) {
24
+ const { buildContext } = params;
25
+
26
+ {
27
+ const result = await getCachedValue({ cacheDirPath: buildContext.cacheDirPath });
28
+
29
+ if (result !== undefined) {
30
+ return result;
31
+ }
32
+ }
33
+
34
+ const tags: string[] = [];
35
+
36
+ await (async function callee(url: string) {
37
+ const r = await fetch(url, buildContext.fetchOptions);
38
+
39
+ await Promise.all([
40
+ (async () => {
41
+ tags.push(
42
+ ...z
43
+ .object({
44
+ tags: z.array(z.string())
45
+ })
46
+ .parse(await r.json()).tags
47
+ );
48
+ })(),
49
+ (async () => {
50
+ const link = r.headers.get("link");
51
+
52
+ if (link === null) {
53
+ return;
54
+ }
55
+
56
+ const split = link.split(";").map(s => s.trim());
57
+
58
+ assert(split.length === 2);
59
+
60
+ assert(split[1] === 'rel="next"');
61
+
62
+ const match = split[0].match(/^<(.+)>$/);
63
+
64
+ assert(match !== null);
65
+
66
+ const nextUrl = new URL(url).origin + match[1];
67
+
68
+ await callee(nextUrl);
69
+ })()
70
+ ]);
71
+ })("https://quay.io/v2/keycloak/keycloak/tags/list");
72
+
73
+ const arr = tags
74
+ .map(tag => ({
75
+ tag,
76
+ version: (() => {
77
+ if (tag.includes("-")) {
78
+ return undefined;
79
+ }
80
+
81
+ let version: SemVer;
82
+
83
+ try {
84
+ version = SemVer.parse(tag);
85
+ } catch {
86
+ return undefined;
87
+ }
88
+
89
+ return version;
90
+ })()
91
+ }))
92
+ .map(({ tag, version }) => (version === undefined ? undefined : { tag, version }))
93
+ .filter(exclude(undefined));
94
+
95
+ const versionByMajor: Record<number, SemVer | undefined> = {};
96
+
97
+ for (const { version } of arr) {
98
+ const version_current = versionByMajor[version.major];
99
+
100
+ if (
101
+ version_current === undefined ||
102
+ SemVer.compare(version_current, version) === -1
103
+ ) {
104
+ versionByMajor[version.major] = version;
105
+ }
106
+ }
107
+
108
+ const supportedKeycloakMajorVersions = getSupportedKeycloakMajorVersions();
109
+
110
+ const result = Object.entries(versionByMajor)
111
+ .sort(([a], [b]) => parseInt(b) - parseInt(a))
112
+ .map(([, version]) => version)
113
+ .map(version => {
114
+ assert(version !== undefined);
115
+
116
+ if (!supportedKeycloakMajorVersions.includes(version.major)) {
117
+ return undefined;
118
+ }
119
+
120
+ return SemVer.stringify(version);
121
+ })
122
+ .filter(exclude(undefined));
123
+
124
+ await setCachedValue({ cacheDirPath: buildContext.cacheDirPath, result });
125
+
126
+ return result;
127
+ }
128
+
129
+ const { getCachedValue, setCachedValue } = (() => {
130
+ type Cache = {
131
+ keycloakifyVersion: string;
132
+ time: number;
133
+ result: string[];
134
+ };
135
+
136
+ const zCache = (() => {
137
+ type TargetType = Cache;
138
+
139
+ const zTargetType = z.object({
140
+ keycloakifyVersion: z.string(),
141
+ time: z.number(),
142
+ result: z.array(z.string())
143
+ });
144
+
145
+ type InferredType = z.infer<typeof zTargetType>;
146
+
147
+ assert<Equals<TargetType, InferredType>>;
148
+
149
+ return id<z.ZodType<TargetType>>(zTargetType);
150
+ })();
151
+
152
+ let inMemoryCachedResult: Cache["result"] | undefined = undefined;
153
+
154
+ function getCacheFilePath(params: { cacheDirPath: string }) {
155
+ const { cacheDirPath } = params;
156
+
157
+ return pathJoin(cacheDirPath, "supportedDockerImageTags.json");
158
+ }
159
+
160
+ async function getCachedValue(params: { cacheDirPath: string }) {
161
+ const { cacheDirPath } = params;
162
+
163
+ if (inMemoryCachedResult !== undefined) {
164
+ return inMemoryCachedResult;
165
+ }
166
+
167
+ const cacheFilePath = getCacheFilePath({ cacheDirPath });
168
+
169
+ if (!(await existsAsync(cacheFilePath))) {
170
+ return undefined;
171
+ }
172
+
173
+ let cache: Cache | undefined;
174
+
175
+ try {
176
+ cache = zCache.parse(JSON.parse(await fs.readFile(cacheFilePath, "utf8")));
177
+ } catch {
178
+ return undefined;
179
+ }
180
+
181
+ if (cache.keycloakifyVersion !== readThisNpmPackageVersion()) {
182
+ return undefined;
183
+ }
184
+
185
+ if (Date.now() - cache.time > 3_600 * 24) {
186
+ return undefined;
187
+ }
188
+
189
+ inMemoryCachedResult = cache.result;
190
+
191
+ return cache.result;
192
+ }
193
+
194
+ async function setCachedValue(params: {
195
+ cacheDirPath: string;
196
+ result: Cache["result"];
197
+ }) {
198
+ const { cacheDirPath, result } = params;
199
+
200
+ inMemoryCachedResult = result;
201
+
202
+ const cacheFilePath = getCacheFilePath({ cacheDirPath });
203
+
204
+ {
205
+ const dirPath = pathDirname(cacheFilePath);
206
+
207
+ if (!(await existsAsync(dirPath))) {
208
+ await fs.mkdir(dirPath, { recursive: true });
209
+ }
210
+ }
211
+
212
+ await fs.writeFile(
213
+ cacheFilePath,
214
+ JSON.stringify(
215
+ zCache.parse({
216
+ keycloakifyVersion: readThisNpmPackageVersion(),
217
+ time: Date.now(),
218
+ result
219
+ }),
220
+ null,
221
+ 2
222
+ )
223
+ );
224
+ }
225
+
226
+ return {
227
+ getCachedValue,
228
+ setCachedValue
229
+ };
230
+ })();
@@ -0,0 +1,118 @@
1
+ import { z } from "zod";
2
+ import { assert, type Equals } from "tsafe/assert";
3
+ import { is } from "tsafe/is";
4
+ import { id } from "tsafe/id";
5
+ import * as fs from "fs";
6
+
7
+ export type ParsedRealmJson = {
8
+ realm: string;
9
+ loginTheme?: string;
10
+ accountTheme?: string;
11
+ adminTheme?: string;
12
+ emailTheme?: string;
13
+ eventsListeners: string[];
14
+ users: {
15
+ id: string;
16
+ email: string;
17
+ username: string;
18
+ credentials: {
19
+ type: string /* "password" or something else */;
20
+ }[];
21
+ clientRoles?: Record<string, string[]>;
22
+ }[];
23
+ roles: {
24
+ client: Record<
25
+ string,
26
+ {
27
+ name: string;
28
+ containerId: string; // client id
29
+ }[]
30
+ >;
31
+ };
32
+ clients: {
33
+ id: string;
34
+ clientId: string; // example: realm-management
35
+ baseUrl?: string;
36
+ redirectUris?: string[];
37
+ webOrigins?: string[];
38
+ attributes?: {
39
+ "post.logout.redirect.uris"?: string;
40
+ };
41
+ protocol?: string;
42
+ protocolMappers?: unknown[];
43
+ }[];
44
+ };
45
+
46
+ const zParsedRealmJson = (() => {
47
+ type TargetType = ParsedRealmJson;
48
+
49
+ const zTargetType = z.object({
50
+ realm: z.string(),
51
+ loginTheme: z.string().optional(),
52
+ accountTheme: z.string().optional(),
53
+ adminTheme: z.string().optional(),
54
+ emailTheme: z.string().optional(),
55
+ eventsListeners: z.array(z.string()),
56
+ users: z.array(
57
+ z.object({
58
+ id: z.string(),
59
+ email: z.string(),
60
+ username: z.string(),
61
+ credentials: z.array(
62
+ z.object({
63
+ type: z.string()
64
+ })
65
+ ),
66
+ clientRoles: z.record(z.array(z.string())).optional()
67
+ })
68
+ ),
69
+ roles: z.object({
70
+ client: z.record(
71
+ z.array(
72
+ z.object({
73
+ name: z.string(),
74
+ containerId: z.string()
75
+ })
76
+ )
77
+ )
78
+ }),
79
+ clients: z.array(
80
+ z.object({
81
+ id: z.string(),
82
+ clientId: z.string(),
83
+ baseUrl: z.string().optional(),
84
+ redirectUris: z.array(z.string()).optional(),
85
+ webOrigins: z.array(z.string()).optional(),
86
+ attributes: z
87
+ .object({
88
+ "post.logout.redirect.uris": z.string().optional()
89
+ })
90
+ .optional(),
91
+ protocol: z.string().optional(),
92
+ protocolMappers: z.array(z.unknown()).optional()
93
+ })
94
+ )
95
+ });
96
+
97
+ type InferredType = z.infer<typeof zTargetType>;
98
+
99
+ assert<Equals<TargetType, InferredType>>;
100
+
101
+ return id<z.ZodType<TargetType>>(zTargetType);
102
+ })();
103
+
104
+ export function readRealmJsonFile(params: {
105
+ realmJsonFilePath: string;
106
+ }): ParsedRealmJson {
107
+ const { realmJsonFilePath } = params;
108
+
109
+ const parsedRealmJson = JSON.parse(
110
+ fs.readFileSync(realmJsonFilePath).toString("utf8")
111
+ ) as unknown;
112
+
113
+ zParsedRealmJson.parse(parsedRealmJson);
114
+
115
+ assert(is<ParsedRealmJson>(parsedRealmJson));
116
+
117
+ return parsedRealmJson;
118
+ }
@@ -0,0 +1,75 @@
1
+ import { join as pathJoin, dirname as pathDirname } from "path";
2
+ import { getThisCodebaseRootDirPath } from "../../../tools/getThisCodebaseRootDirPath";
3
+ import * as fs from "fs";
4
+ import { exclude } from "tsafe/exclude";
5
+ import { assert } from "tsafe/assert";
6
+ import { type ParsedRealmJson, readRealmJsonFile } from "../ParsedRealmJson";
7
+
8
+ export function getDefaultRealmJsonFilePath(params: {
9
+ keycloakMajorVersionNumber: number;
10
+ }) {
11
+ const { keycloakMajorVersionNumber } = params;
12
+
13
+ return pathJoin(
14
+ getThisCodebaseRootDirPath(),
15
+ "src",
16
+ "bin",
17
+ "start-keycloak",
18
+ "realmConfig",
19
+ "defaultConfig",
20
+ `realm-kc-${keycloakMajorVersionNumber}.json`
21
+ );
22
+ }
23
+
24
+ export const { getSupportedKeycloakMajorVersions } = (() => {
25
+ let cache: number[] | undefined = undefined;
26
+
27
+ function getSupportedKeycloakMajorVersions(): number[] {
28
+ if (cache !== undefined) {
29
+ return cache;
30
+ }
31
+
32
+ cache = fs
33
+ .readdirSync(
34
+ pathDirname(
35
+ getDefaultRealmJsonFilePath({ keycloakMajorVersionNumber: 0 })
36
+ )
37
+ )
38
+ .map(fileBasename => {
39
+ const match = fileBasename.match(/^realm-kc-(\d+)\.json$/);
40
+
41
+ if (match === null) {
42
+ return undefined;
43
+ }
44
+
45
+ const n = parseInt(match[1]);
46
+
47
+ assert(!isNaN(n));
48
+
49
+ return n;
50
+ })
51
+ .filter(exclude(undefined))
52
+ .sort((a, b) => b - a);
53
+
54
+ return cache;
55
+ }
56
+
57
+ return { getSupportedKeycloakMajorVersions };
58
+ })();
59
+
60
+ export function getDefaultConfig(params: {
61
+ keycloakMajorVersionNumber: number;
62
+ }): ParsedRealmJson {
63
+ const { keycloakMajorVersionNumber } = params;
64
+
65
+ assert(
66
+ getSupportedKeycloakMajorVersions().includes(keycloakMajorVersionNumber),
67
+ `We do not have a default config for Keycloak ${keycloakMajorVersionNumber}`
68
+ );
69
+
70
+ return readRealmJsonFile({
71
+ realmJsonFilePath: getDefaultRealmJsonFilePath({
72
+ keycloakMajorVersionNumber
73
+ })
74
+ });
75
+ }
@@ -0,0 +1 @@
1
+ export * from "./defaultConfig";