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.
- package/account/i18n/withJsx/GenericI18n.d.ts +1 -1
- package/account/i18n/withJsx/GenericI18n.js.map +1 -1
- package/account/i18n/withJsx/useI18n.js.map +1 -1
- package/account/pages/PageProps.d.ts +1 -1
- package/bin/375.index.js +4089 -0
- package/bin/{20.index.js → 490.index.js} +378 -56
- package/bin/{36.index.js → 503.index.js} +53 -2
- package/bin/{450.index.js → 525.index.js} +2 -4085
- package/bin/653.index.js +108 -110
- package/bin/682.index.js +1885 -0
- package/bin/735.index.js +107 -109
- package/bin/921.index.js +1 -1
- package/bin/main.js +8 -2
- package/bin/shared/constants.d.ts +3 -0
- package/bin/shared/constants.js +3 -0
- package/bin/shared/constants.js.map +1 -1
- package/bin/start-keycloak/getSupportedDockerImageTags.d.ts +8 -0
- package/bin/start-keycloak/realmConfig/ParsedRealmJson.d.ts +38 -0
- package/bin/start-keycloak/realmConfig/defaultConfig/defaultConfig.d.ts +8 -0
- package/bin/start-keycloak/realmConfig/defaultConfig/index.d.ts +1 -0
- package/bin/start-keycloak/realmConfig/dumpContainerConfig.d.ts +9 -0
- package/bin/start-keycloak/realmConfig/index.d.ts +1 -0
- package/bin/start-keycloak/realmConfig/prepareRealmConfig.d.ts +15 -0
- package/bin/start-keycloak/realmConfig/realmConfig.d.ts +16 -0
- package/login/DefaultPage.d.ts +2 -1
- package/login/DefaultPage.js.map +1 -1
- package/login/UserProfileFormFields.d.ts +1 -1
- package/login/UserProfileFormFields.js.map +1 -1
- package/login/UserProfileFormFieldsProps.d.ts +1 -0
- package/login/i18n/withJsx/GenericI18n.d.ts +1 -1
- package/login/i18n/withJsx/GenericI18n.js.map +1 -1
- package/login/i18n/withJsx/useI18n.js.map +1 -1
- package/login/lib/useUserProfileForm.d.ts +1 -1
- package/login/lib/useUserProfileForm.js.map +1 -1
- package/login/pages/IdpReviewUserProfile.d.ts +2 -1
- package/login/pages/IdpReviewUserProfile.js.map +1 -1
- package/login/pages/Login.d.ts +1 -1
- package/login/pages/Login.js.map +1 -1
- package/login/pages/LoginPassword.d.ts +1 -1
- package/login/pages/LoginPassword.js.map +1 -1
- package/login/pages/LoginUpdatePassword.d.ts +1 -1
- package/login/pages/LoginUpdatePassword.js.map +1 -1
- package/login/pages/LoginUpdateProfile.d.ts +2 -1
- package/login/pages/LoginUpdateProfile.js.map +1 -1
- package/login/pages/PageProps.d.ts +1 -1
- package/login/pages/Register.d.ts +2 -1
- package/login/pages/Register.js.map +1 -1
- package/login/pages/UpdateEmail.d.ts +2 -1
- package/login/pages/UpdateEmail.js.map +1 -1
- package/package.json +35 -14
- package/src/account/i18n/withJsx/GenericI18n.tsx +1 -0
- package/src/account/i18n/withJsx/useI18n.tsx +1 -0
- package/src/account/pages/PageProps.ts +1 -0
- package/src/bin/shared/constants.ts +6 -0
- package/src/bin/start-keycloak/getSupportedDockerImageTags.ts +230 -0
- package/src/bin/start-keycloak/keycloakify-logging-1.0.3.jar +0 -0
- package/src/bin/start-keycloak/realmConfig/ParsedRealmJson.ts +118 -0
- package/src/bin/start-keycloak/realmConfig/defaultConfig/defaultConfig.ts +75 -0
- package/src/bin/start-keycloak/realmConfig/defaultConfig/index.ts +1 -0
- package/src/bin/start-keycloak/{myrealm-realm-18.json → realmConfig/defaultConfig/realm-kc-18.json} +123 -60
- package/src/bin/start-keycloak/{myrealm-realm-19.json → realmConfig/defaultConfig/realm-kc-19.json} +81 -41
- package/src/bin/start-keycloak/{myrealm-realm-20.json → realmConfig/defaultConfig/realm-kc-20.json} +83 -42
- package/src/bin/start-keycloak/{myrealm-realm-21.json → realmConfig/defaultConfig/realm-kc-21.json} +58 -17
- package/src/bin/start-keycloak/{myrealm-realm-23.json → realmConfig/defaultConfig/realm-kc-23.json} +64 -20
- package/src/bin/start-keycloak/{myrealm-realm-24.json → realmConfig/defaultConfig/realm-kc-24.json} +63 -19
- package/src/bin/start-keycloak/{myrealm-realm-25.json → realmConfig/defaultConfig/realm-kc-25.json} +75 -20
- package/src/bin/start-keycloak/{myrealm-realm-26.json → realmConfig/defaultConfig/realm-kc-26.json} +86 -20
- package/src/bin/start-keycloak/realmConfig/dumpContainerConfig.ts +147 -0
- package/src/bin/start-keycloak/realmConfig/index.ts +1 -0
- package/src/bin/start-keycloak/realmConfig/prepareRealmConfig.ts +302 -0
- package/src/bin/start-keycloak/realmConfig/realmConfig.ts +151 -0
- package/src/bin/start-keycloak/start-keycloak.ts +160 -184
- package/src/bin/start-keycloak/startViteDevServer.ts +1 -0
- package/src/login/DefaultPage.tsx +1 -0
- package/src/login/UserProfileFormFields.tsx +1 -0
- package/src/login/UserProfileFormFieldsProps.tsx +1 -0
- package/src/login/i18n/withJsx/GenericI18n.tsx +1 -0
- package/src/login/i18n/withJsx/useI18n.tsx +1 -0
- package/src/login/lib/useUserProfileForm.tsx +1 -0
- package/src/login/pages/IdpReviewUserProfile.tsx +1 -0
- package/src/login/pages/Login.tsx +1 -0
- package/src/login/pages/LoginPassword.tsx +1 -0
- package/src/login/pages/LoginUpdatePassword.tsx +1 -0
- package/src/login/pages/LoginUpdateProfile.tsx +1 -0
- package/src/login/pages/PageProps.ts +1 -0
- package/src/login/pages/Register.tsx +1 -0
- package/src/login/pages/UpdateEmail.tsx +1 -0
- package/src/tools/JSX.ts +5 -0
- package/tools/JSX.d.ts +5 -0
- package/tools/JSX.js +2 -0
- package/tools/JSX.js.map +1 -0
- package/vite-plugin/index.js +6 -0
- package/bin/392.index.js +0 -740
- 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
|
+
})();
|
Binary file
|
@@ -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";
|