@zitadel/components 1.0.0-alpha.22 → 1.0.0-alpha.23
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/dist/atoms/index.d.mts +1 -1
- package/dist/atoms/index.mjs +1 -1
- package/dist/{atoms-Boaxh79f.mjs → atoms-DbcPXAO0.mjs} +2 -1
- package/dist/atoms-DbcPXAO0.mjs.map +1 -0
- package/dist/{index-BaS893QZ.d.mts → index-1PzVwdYA.d.mts} +290 -101
- package/dist/index-1PzVwdYA.d.mts.map +1 -0
- package/dist/{index-DMPCvLh_.d.mts → index-BRd9vg2q.d.mts} +12333 -6546
- package/dist/index-BRd9vg2q.d.mts.map +1 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/manifests.mjs +1 -1
- package/dist/orchestrator/index.d.mts +2 -2
- package/dist/orchestrator/index.mjs +2 -2
- package/dist/{orchestrator-BPX0Uc77.mjs → orchestrator-BVmKaCqz.mjs} +602 -121
- package/dist/orchestrator-BVmKaCqz.mjs.map +1 -0
- package/dist/standalone.mjs +603 -121
- package/package.json +3 -3
- package/dist/atoms-Boaxh79f.mjs.map +0 -1
- package/dist/index-BaS893QZ.d.mts.map +0 -1
- package/dist/index-DMPCvLh_.d.mts.map +0 -1
- package/dist/orchestrator-BPX0Uc77.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as focusVisibleStyles, E as emit, S as __decorate, T as t, d as hookName, w as baseHostStyles } from "./atoms-
|
|
2
|
-
import { i as tokensCss, t as THEME_SELECTORS } from "./tokens-T4N9VJz3.mjs";
|
|
1
|
+
import { C as focusVisibleStyles, E as emit, S as __decorate, T as t, d as hookName, w as baseHostStyles } from "./atoms-DbcPXAO0.mjs";
|
|
2
|
+
import { i as tokensCss, r as tokens, t as THEME_SELECTORS } from "./tokens-T4N9VJz3.mjs";
|
|
3
3
|
import { manifestRegistry } from "./manifests.mjs";
|
|
4
4
|
import { t as default_default } from "./default-Dnjq9iBt.mjs";
|
|
5
5
|
import { LitElement, css, html, nothing } from "lit";
|
|
@@ -331,18 +331,28 @@ function validateBranding(input, context = {}) {
|
|
|
331
331
|
out.layout = CreateFlow201BrandingLayout.centered;
|
|
332
332
|
}
|
|
333
333
|
out.logo_url = sanitiseUrl(out.logo_url, "logo_url", issues, { allowed: allowLoopbackHttp });
|
|
334
|
-
out.font_url
|
|
334
|
+
if (out.typography?.font_url) out.typography = {
|
|
335
|
+
...out.typography,
|
|
336
|
+
font_url: sanitiseUrl(out.typography.font_url, "typography.font_url", issues)
|
|
337
|
+
};
|
|
335
338
|
out.hero_url = sanitiseUrl(out.hero_url, "hero_url", issues, { allowed: allowLoopbackHttp });
|
|
336
|
-
if (out.
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
339
|
+
if (out.theme?.light || out.theme?.dark) out.theme = {
|
|
340
|
+
...out.theme,
|
|
341
|
+
...sanitiseSideLogo(out.theme.light, "light", issues, allowLoopbackHttp),
|
|
342
|
+
...sanitiseSideLogo(out.theme.dark, "dark", issues, allowLoopbackHttp)
|
|
340
343
|
};
|
|
341
344
|
return {
|
|
342
345
|
branding: out,
|
|
343
346
|
issues
|
|
344
347
|
};
|
|
345
348
|
}
|
|
349
|
+
function sanitiseSideLogo(side, name, issues, allowLoopbackHttp) {
|
|
350
|
+
if (!side) return {};
|
|
351
|
+
return { [name]: {
|
|
352
|
+
...side,
|
|
353
|
+
logo_url: sanitiseUrl(side.logo_url, `theme.${name}.logo_url`, issues, { allowed: allowLoopbackHttp })
|
|
354
|
+
} };
|
|
355
|
+
}
|
|
346
356
|
function sanitiseUrl(value, field, issues, loopbackHttp) {
|
|
347
357
|
if (value == null || value === "") return;
|
|
348
358
|
try {
|
|
@@ -360,6 +370,34 @@ function sanitiseUrl(value, field, issues, loopbackHttp) {
|
|
|
360
370
|
}
|
|
361
371
|
}
|
|
362
372
|
//#endregion
|
|
373
|
+
//#region src/orchestrator/branding.ts
|
|
374
|
+
/**
|
|
375
|
+
* Which sides the revision actually publishes. A side is published when the
|
|
376
|
+
* revision names it at all — an empty side object still says "this surface is
|
|
377
|
+
* mine", it just takes the maintained defaults for every key.
|
|
378
|
+
*/
|
|
379
|
+
function publishedSides(branding) {
|
|
380
|
+
const theme = branding?.theme;
|
|
381
|
+
const sides = [];
|
|
382
|
+
if (theme?.light) sides.push("light");
|
|
383
|
+
if (theme?.dark) sides.push("dark");
|
|
384
|
+
return sides;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* The mark for the resolved surface. A logo is pixels and is never recoloured,
|
|
388
|
+
* so a side without its own file shows no mark rather than borrowing the other
|
|
389
|
+
* side's. The legacy top-level `logo_url` is a single-mark fallback and applies
|
|
390
|
+
* only when neither side names one.
|
|
391
|
+
*/
|
|
392
|
+
function resolveLogoUrl(branding, theme) {
|
|
393
|
+
if (!branding) return void 0;
|
|
394
|
+
const sides = branding.theme;
|
|
395
|
+
const sideLogo = theme === "light" ? sides?.light?.logo_url : sides?.dark?.logo_url;
|
|
396
|
+
if (sideLogo) return sideLogo;
|
|
397
|
+
if (sides?.light?.logo_url || sides?.dark?.logo_url) return void 0;
|
|
398
|
+
return branding.logo_url;
|
|
399
|
+
}
|
|
400
|
+
//#endregion
|
|
363
401
|
//#region src/orchestrator/exportparts.ts
|
|
364
402
|
/**
|
|
365
403
|
* Forwards atom-internal CSS Shadow Parts through the orchestrator boundary.
|
|
@@ -864,7 +902,7 @@ const en = {
|
|
|
864
902
|
"error.password_required": "Please enter a password",
|
|
865
903
|
"error.password_incorrect": "Wrong email or password.",
|
|
866
904
|
"error.email_exists": "An account with this email already exists.",
|
|
867
|
-
/**
|
|
905
|
+
/** Sign-in error, inline on the password field. */
|
|
868
906
|
"error.invalid_credentials": "Wrong email or password.",
|
|
869
907
|
"error.required": "This field is required.",
|
|
870
908
|
"error.field_required": "{0} is required.",
|
|
@@ -1187,16 +1225,17 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1187
1225
|
createFlowDefinition: () => createFlowDefinition,
|
|
1188
1226
|
createGrant: () => createGrant,
|
|
1189
1227
|
createHandoff: () => createHandoff,
|
|
1228
|
+
createIdp: () => createIdp,
|
|
1190
1229
|
createProject: () => createProject,
|
|
1191
1230
|
createRelease: () => createRelease,
|
|
1192
1231
|
createSchema: () => createSchema,
|
|
1193
1232
|
createSession: () => createSession,
|
|
1194
1233
|
createTeam: () => createTeam,
|
|
1195
1234
|
createUser: () => createUser,
|
|
1196
|
-
deleteFlowDefinition: () => deleteFlowDefinition,
|
|
1197
1235
|
deleteGrant: () => deleteGrant,
|
|
1198
1236
|
deleteTeam: () => deleteTeam,
|
|
1199
1237
|
deleteUserByID: () => deleteUserByID,
|
|
1238
|
+
deleteVariable: () => deleteVariable,
|
|
1200
1239
|
exchangeHandoff: () => exchangeHandoff,
|
|
1201
1240
|
finishUserPasskeyRegistration: () => finishUserPasskeyRegistration,
|
|
1202
1241
|
getAuthAttempt: () => getAuthAttempt,
|
|
@@ -1211,16 +1250,17 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1211
1250
|
getCreateFlowUrl: () => getCreateFlowUrl,
|
|
1212
1251
|
getCreateGrantUrl: () => getCreateGrantUrl,
|
|
1213
1252
|
getCreateHandoffUrl: () => getCreateHandoffUrl,
|
|
1253
|
+
getCreateIdpUrl: () => getCreateIdpUrl,
|
|
1214
1254
|
getCreateProjectUrl: () => getCreateProjectUrl,
|
|
1215
1255
|
getCreateReleaseUrl: () => getCreateReleaseUrl,
|
|
1216
1256
|
getCreateSchemaUrl: () => getCreateSchemaUrl,
|
|
1217
1257
|
getCreateSessionUrl: () => getCreateSessionUrl,
|
|
1218
1258
|
getCreateTeamUrl: () => getCreateTeamUrl,
|
|
1219
1259
|
getCreateUserUrl: () => getCreateUserUrl,
|
|
1220
|
-
getDeleteFlowDefinitionUrl: () => getDeleteFlowDefinitionUrl,
|
|
1221
1260
|
getDeleteGrantUrl: () => getDeleteGrantUrl,
|
|
1222
1261
|
getDeleteTeamUrl: () => getDeleteTeamUrl,
|
|
1223
1262
|
getDeleteUserByIDUrl: () => getDeleteUserByIDUrl,
|
|
1263
|
+
getDeleteVariableUrl: () => getDeleteVariableUrl,
|
|
1224
1264
|
getEnvironmentByName: () => getEnvironmentByName,
|
|
1225
1265
|
getEvent: () => getEvent,
|
|
1226
1266
|
getExchangeHandoffUrl: () => getExchangeHandoffUrl,
|
|
@@ -1237,6 +1277,8 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1237
1277
|
getGetFlowStepUrl: () => getGetFlowStepUrl,
|
|
1238
1278
|
getGetGrantUrl: () => getGetGrantUrl,
|
|
1239
1279
|
getGetHealthUrl: () => getGetHealthUrl,
|
|
1280
|
+
getGetIdpByIdUrl: () => getGetIdpByIdUrl,
|
|
1281
|
+
getGetIdpRevisionByIdUrl: () => getGetIdpRevisionByIdUrl,
|
|
1240
1282
|
getGetLiveUrl: () => getGetLiveUrl,
|
|
1241
1283
|
getGetMySessionUrl: () => getGetMySessionUrl,
|
|
1242
1284
|
getGetMyUserUrl: () => getGetMyUserUrl,
|
|
@@ -1247,14 +1289,20 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1247
1289
|
getGetSessionUrl: () => getGetSessionUrl,
|
|
1248
1290
|
getGetTeamUrl: () => getGetTeamUrl,
|
|
1249
1291
|
getGetUserByIDUrl: () => getGetUserByIDUrl,
|
|
1292
|
+
getGetVariableUrl: () => getGetVariableUrl,
|
|
1293
|
+
getGetVariablesUrl: () => getGetVariablesUrl,
|
|
1250
1294
|
getGrant: () => getGrant,
|
|
1251
1295
|
getHealth: () => getHealth,
|
|
1296
|
+
getIdpById: () => getIdpById,
|
|
1297
|
+
getIdpRevisionById: () => getIdpRevisionById,
|
|
1252
1298
|
getInitClaimUrl: () => getInitClaimUrl,
|
|
1253
1299
|
getIssueChallengeUrl: () => getIssueChallengeUrl,
|
|
1254
1300
|
getListBrandingUrl: () => getListBrandingUrl,
|
|
1255
1301
|
getListEnvironmentsUrl: () => getListEnvironmentsUrl,
|
|
1256
1302
|
getListEventsUrl: () => getListEventsUrl,
|
|
1257
1303
|
getListFlowDefinitionsUrl: () => getListFlowDefinitionsUrl,
|
|
1304
|
+
getListIdpRevisionsUrl: () => getListIdpRevisionsUrl,
|
|
1305
|
+
getListMyProjectsUrl: () => getListMyProjectsUrl,
|
|
1258
1306
|
getListReleasesUrl: () => getListReleasesUrl,
|
|
1259
1307
|
getListSchemasUrl: () => getListSchemasUrl,
|
|
1260
1308
|
getListUserPasskeysUrl: () => getListUserPasskeysUrl,
|
|
@@ -1262,9 +1310,12 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1262
1310
|
getLive: () => getLive,
|
|
1263
1311
|
getMySession: () => getMySession,
|
|
1264
1312
|
getMyUser: () => getMyUser,
|
|
1313
|
+
getPatchMyUserUrl: () => getPatchMyUserUrl,
|
|
1265
1314
|
getPatchProjectUrl: () => getPatchProjectUrl,
|
|
1315
|
+
getPatchUserByIDUrl: () => getPatchUserByIDUrl,
|
|
1266
1316
|
getProject: () => getProject,
|
|
1267
1317
|
getQueryGrantsUrl: () => getQueryGrantsUrl,
|
|
1318
|
+
getQueryIdpsUrl: () => getQueryIdpsUrl,
|
|
1268
1319
|
getQueryProjectsUrl: () => getQueryProjectsUrl,
|
|
1269
1320
|
getQuerySessionsUrl: () => getQuerySessionsUrl,
|
|
1270
1321
|
getQueryTeamsUrl: () => getQueryTeamsUrl,
|
|
@@ -1278,9 +1329,11 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1278
1329
|
getSetUserPasswordUrl: () => getSetUserPasswordUrl,
|
|
1279
1330
|
getSubmitFlowStepUrl: () => getSubmitFlowStepUrl,
|
|
1280
1331
|
getTeam: () => getTeam,
|
|
1281
|
-
getUpdateFlowDefinitionUrl: () => getUpdateFlowDefinitionUrl,
|
|
1282
1332
|
getUpdateTeamUrl: () => getUpdateTeamUrl,
|
|
1333
|
+
getUpdateVariablesUrl: () => getUpdateVariablesUrl,
|
|
1283
1334
|
getUserByID: () => getUserByID,
|
|
1335
|
+
getVariable: () => getVariable,
|
|
1336
|
+
getVariables: () => getVariables,
|
|
1284
1337
|
getVerifyChallengeProofUrl: () => getVerifyChallengeProofUrl,
|
|
1285
1338
|
initClaim: () => initClaim,
|
|
1286
1339
|
issueChallenge: () => issueChallenge,
|
|
@@ -1288,12 +1341,17 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1288
1341
|
listEnvironments: () => listEnvironments,
|
|
1289
1342
|
listEvents: () => listEvents,
|
|
1290
1343
|
listFlowDefinitions: () => listFlowDefinitions,
|
|
1344
|
+
listIdpRevisions: () => listIdpRevisions,
|
|
1345
|
+
listMyProjects: () => listMyProjects,
|
|
1291
1346
|
listReleases: () => listReleases,
|
|
1292
1347
|
listSchemas: () => listSchemas,
|
|
1293
1348
|
listUserPasskeys: () => listUserPasskeys,
|
|
1294
1349
|
listUserTeams: () => listUserTeams,
|
|
1350
|
+
patchMyUser: () => patchMyUser,
|
|
1295
1351
|
patchProject: () => patchProject,
|
|
1352
|
+
patchUserByID: () => patchUserByID,
|
|
1296
1353
|
queryGrants: () => queryGrants,
|
|
1354
|
+
queryIdps: () => queryIdps,
|
|
1297
1355
|
queryProjects: () => queryProjects,
|
|
1298
1356
|
querySessions: () => querySessions,
|
|
1299
1357
|
queryTeams: () => queryTeams,
|
|
@@ -1302,8 +1360,8 @@ var zitadelNextGen_exports = /* @__PURE__ */ __exportAll({
|
|
|
1302
1360
|
revokeSession: () => revokeSession,
|
|
1303
1361
|
setUserPassword: () => setUserPassword,
|
|
1304
1362
|
submitFlowStep: () => submitFlowStep,
|
|
1305
|
-
updateFlowDefinition: () => updateFlowDefinition,
|
|
1306
1363
|
updateTeam: () => updateTeam,
|
|
1364
|
+
updateVariables: () => updateVariables,
|
|
1307
1365
|
verifyChallengeProof: () => verifyChallengeProof
|
|
1308
1366
|
});
|
|
1309
1367
|
const getGetHealthUrl = () => {
|
|
@@ -1373,9 +1431,14 @@ const getQueryUsersUrl = () => {
|
|
|
1373
1431
|
/**
|
|
1374
1432
|
* Returns the users of a project, paginated with a cursor.
|
|
1375
1433
|
|
|
1376
|
-
The project comes from the credential, not from a parameter: the
|
|
1377
|
-
is bound to the
|
|
1378
|
-
|
|
1434
|
+
The project comes from the credential, not from a parameter: the
|
|
1435
|
+
operation is bound to the credential's home project by construction
|
|
1436
|
+
(oauth2 secret or user-bound session). This is why it takes no
|
|
1437
|
+
`project_id`, unlike the other query endpoints.
|
|
1438
|
+
|
|
1439
|
+
Accepts either a project secret (`oauth2`) or a user-bound Console
|
|
1440
|
+
session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
|
|
1441
|
+
is a follow-up (#1140).
|
|
1379
1442
|
|
|
1380
1443
|
* @summary Query users
|
|
1381
1444
|
*/
|
|
@@ -1407,6 +1470,28 @@ const getUserByID = async (userId, params, options) => {
|
|
|
1407
1470
|
method: "GET"
|
|
1408
1471
|
});
|
|
1409
1472
|
};
|
|
1473
|
+
const getPatchUserByIDUrl = (userId) => {
|
|
1474
|
+
return `${getProxyPath()}/users/${userId}`;
|
|
1475
|
+
};
|
|
1476
|
+
/**
|
|
1477
|
+
* Partially updates a user's schema-defined attributes, and optionally
|
|
1478
|
+
moves the user to another registered schema. The merged result is
|
|
1479
|
+
validated against the schema before commit. Concurrent writes are
|
|
1480
|
+
last-write-wins.
|
|
1481
|
+
|
|
1482
|
+
* @summary Update user by ID
|
|
1483
|
+
*/
|
|
1484
|
+
const patchUserByID = async (userId, patchUserByIDBody, options) => {
|
|
1485
|
+
return customFetch(getPatchUserByIDUrl(userId), {
|
|
1486
|
+
...options,
|
|
1487
|
+
method: "PATCH",
|
|
1488
|
+
headers: {
|
|
1489
|
+
"Content-Type": "application/json",
|
|
1490
|
+
...options?.headers
|
|
1491
|
+
},
|
|
1492
|
+
body: JSON.stringify(patchUserByIDBody)
|
|
1493
|
+
});
|
|
1494
|
+
};
|
|
1410
1495
|
const getDeleteUserByIDUrl = (userId) => {
|
|
1411
1496
|
return `${getProxyPath()}/users/${userId}`;
|
|
1412
1497
|
};
|
|
@@ -1537,6 +1622,52 @@ const getMyUser = async (options) => {
|
|
|
1537
1622
|
method: "GET"
|
|
1538
1623
|
});
|
|
1539
1624
|
};
|
|
1625
|
+
const getPatchMyUserUrl = () => {
|
|
1626
|
+
return `${getProxyPath()}/users/me`;
|
|
1627
|
+
};
|
|
1628
|
+
/**
|
|
1629
|
+
* Partially updates the caller's own schema-defined attributes. The merged
|
|
1630
|
+
result is validated against the user's schema before commit. Concurrent
|
|
1631
|
+
writes are last-write-wins.
|
|
1632
|
+
|
|
1633
|
+
* @summary Update my user information
|
|
1634
|
+
*/
|
|
1635
|
+
const patchMyUser = async (patchMyUserBody, options) => {
|
|
1636
|
+
return customFetch(getPatchMyUserUrl(), {
|
|
1637
|
+
...options,
|
|
1638
|
+
method: "PATCH",
|
|
1639
|
+
headers: {
|
|
1640
|
+
"Content-Type": "application/json",
|
|
1641
|
+
...options?.headers
|
|
1642
|
+
},
|
|
1643
|
+
body: JSON.stringify(patchMyUserBody)
|
|
1644
|
+
});
|
|
1645
|
+
};
|
|
1646
|
+
const getListMyProjectsUrl = (params) => {
|
|
1647
|
+
const normalizedParams = new URLSearchParams();
|
|
1648
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
1649
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
1650
|
+
});
|
|
1651
|
+
const stringifiedParams = normalizedParams.toString();
|
|
1652
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/users/me/projects?${stringifiedParams}` : `${getProxyPath()}/users/me/projects`;
|
|
1653
|
+
};
|
|
1654
|
+
/**
|
|
1655
|
+
* The projects the signed-in user holds an active grant on, either directly or
|
|
1656
|
+
through a team they are a member of. Ordered by project id and paged with an
|
|
1657
|
+
opaque cursor.
|
|
1658
|
+
|
|
1659
|
+
This is not the same question as `queryProjects`, which answers with the one
|
|
1660
|
+
project the calling credential is bound to. Here the session is the caller
|
|
1661
|
+
and the grants are the answer, so the list spans projects.
|
|
1662
|
+
|
|
1663
|
+
* @summary List the projects I can act on
|
|
1664
|
+
*/
|
|
1665
|
+
const listMyProjects = async (params, options) => {
|
|
1666
|
+
return customFetch(getListMyProjectsUrl(params), {
|
|
1667
|
+
...options,
|
|
1668
|
+
method: "GET"
|
|
1669
|
+
});
|
|
1670
|
+
};
|
|
1540
1671
|
const getCreateFlowUrl = () => {
|
|
1541
1672
|
return `${getProxyPath()}/flow`;
|
|
1542
1673
|
};
|
|
@@ -2222,42 +2353,6 @@ const getFlowDefinition = async (id, options) => {
|
|
|
2222
2353
|
method: "GET"
|
|
2223
2354
|
});
|
|
2224
2355
|
};
|
|
2225
|
-
const getUpdateFlowDefinitionUrl = (id) => {
|
|
2226
|
-
return `${getProxyPath()}/flow_definitions/${id}`;
|
|
2227
|
-
};
|
|
2228
|
-
/**
|
|
2229
|
-
* Update a flow definition by id. This endpoint replaces the existing flow definition.
|
|
2230
|
-
If `flow_definition.status` is omitted, the current status is preserved
|
|
2231
|
-
|
|
2232
|
-
* @summary Update a flow definition by id
|
|
2233
|
-
*/
|
|
2234
|
-
const updateFlowDefinition = async (id, updateFlowDefinitionBody, options) => {
|
|
2235
|
-
return customFetch(getUpdateFlowDefinitionUrl(id), {
|
|
2236
|
-
...options,
|
|
2237
|
-
method: "PUT",
|
|
2238
|
-
headers: {
|
|
2239
|
-
"Content-Type": "application/json",
|
|
2240
|
-
...options?.headers
|
|
2241
|
-
},
|
|
2242
|
-
body: JSON.stringify(updateFlowDefinitionBody)
|
|
2243
|
-
});
|
|
2244
|
-
};
|
|
2245
|
-
const getDeleteFlowDefinitionUrl = (id) => {
|
|
2246
|
-
return `${getProxyPath()}/flow_definitions/${id}`;
|
|
2247
|
-
};
|
|
2248
|
-
/**
|
|
2249
|
-
* Delete a flow definition by id.
|
|
2250
|
-
If the flow definition is currently being used by a flow, the deletion will fail.
|
|
2251
|
-
If the flow definition is the last active flow definition for a given purpose, the deletion will fail to prevent disruption of new flows being started for that purpose.
|
|
2252
|
-
|
|
2253
|
-
* @summary Delete a flow definition by id
|
|
2254
|
-
*/
|
|
2255
|
-
const deleteFlowDefinition = async (id, options) => {
|
|
2256
|
-
return customFetch(getDeleteFlowDefinitionUrl(id), {
|
|
2257
|
-
...options,
|
|
2258
|
-
method: "DELETE"
|
|
2259
|
-
});
|
|
2260
|
-
};
|
|
2261
2356
|
const getCreateTeamUrl = (params) => {
|
|
2262
2357
|
const normalizedParams = new URLSearchParams();
|
|
2263
2358
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
@@ -2331,6 +2426,11 @@ users whose lifecycle it owns are deactivated with it.
|
|
|
2331
2426
|
The request is idempotent. Deleting a team that is already deactivated
|
|
2332
2427
|
or doesn't exist succeeds without changing anything.
|
|
2333
2428
|
|
|
2429
|
+
A team that still owns a project is refused with `409
|
|
2430
|
+
team.owns_project`: deactivating it would leave the project owned by a
|
|
2431
|
+
dead team and so unmanageable. No endpoint releases that ownership yet,
|
|
2432
|
+
so such a team cannot currently be deactivated through the API.
|
|
2433
|
+
|
|
2334
2434
|
* @summary Delete team
|
|
2335
2435
|
*/
|
|
2336
2436
|
const deleteTeam = async (teamId, options) => {
|
|
@@ -2410,8 +2510,7 @@ const getCreateBrandingUrl = (params) => {
|
|
|
2410
2510
|
/**
|
|
2411
2511
|
* Publishes a new immutable branding revision for the project. Branding
|
|
2412
2512
|
revisions cannot be updated or deleted; every edit publishes a new
|
|
2413
|
-
revision, and flow responses resolve the latest revision per project
|
|
2414
|
-
(see ADR 040).
|
|
2513
|
+
revision, and flow responses resolve the latest revision per project.
|
|
2415
2514
|
|
|
2416
2515
|
The `liquid_template` is validated lexically on save (size, encoding,
|
|
2417
2516
|
banned patterns such as `<script>` tags, inline event handlers, and the
|
|
@@ -2442,9 +2541,9 @@ const getListBrandingUrl = (params) => {
|
|
|
2442
2541
|
/**
|
|
2443
2542
|
* Lists branding revisions for the project, newest first, capped at the
|
|
2444
2543
|
100 most recent. The first entry is the revision flow responses
|
|
2445
|
-
currently resolve. Deliberately unpaginated in v1 — list endpoints
|
|
2446
|
-
|
|
2447
|
-
|
|
2544
|
+
currently resolve. Deliberately unpaginated in v1 — list endpoints gain a
|
|
2545
|
+
real query mechanism together; advertising pagination parameters the
|
|
2546
|
+
server ignores would be worse than none.
|
|
2448
2547
|
|
|
2449
2548
|
* @summary List branding revisions
|
|
2450
2549
|
*/
|
|
@@ -2467,6 +2566,142 @@ const getBrandingById = async (id, options) => {
|
|
|
2467
2566
|
method: "GET"
|
|
2468
2567
|
});
|
|
2469
2568
|
};
|
|
2569
|
+
const getCreateIdpUrl = (params) => {
|
|
2570
|
+
const normalizedParams = new URLSearchParams();
|
|
2571
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
2572
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
2573
|
+
});
|
|
2574
|
+
const stringifiedParams = normalizedParams.toString();
|
|
2575
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/idps?${stringifiedParams}` : `${getProxyPath()}/idps`;
|
|
2576
|
+
};
|
|
2577
|
+
/**
|
|
2578
|
+
* Creates or revises a connection document. If the slug does not already
|
|
2579
|
+
exist, a new connection is created. If a connection with that slug already
|
|
2580
|
+
exists, a revision is created.
|
|
2581
|
+
|
|
2582
|
+
A revision gets a new `revision_id` and does not modify the connection
|
|
2583
|
+
`id`, so identity links that reference the connection keep resolving while
|
|
2584
|
+
releases and auth attempts stay pinned to the revision they captured.
|
|
2585
|
+
|
|
2586
|
+
Identity fields are fixed for the life of the connection and a revision
|
|
2587
|
+
that changes one is rejected: `protocol`, `subject_claim`, and the
|
|
2588
|
+
endpoints that name the authority (`issuer` for OIDC, `token_endpoint`
|
|
2589
|
+
and `userinfo_endpoint` for OAuth 2.0). Their values decide which provider
|
|
2590
|
+
account a stored subject belongs to, so changing one would silently
|
|
2591
|
+
repoint existing identities at a different provider.
|
|
2592
|
+
|
|
2593
|
+
`subject_claim` is optional for OIDC and required for OAuth 2.0. For an
|
|
2594
|
+
OIDC connection, `sub` is used as the default value. If a revision updates
|
|
2595
|
+
`subject_claim` to a different value than the one set during creation, the
|
|
2596
|
+
request is rejected.
|
|
2597
|
+
|
|
2598
|
+
The document is validated against the `idp-connection.json` schema before
|
|
2599
|
+
anything is stored.
|
|
2600
|
+
|
|
2601
|
+
* @summary Create or revise an identity provider connection
|
|
2602
|
+
*/
|
|
2603
|
+
const createIdp = async (createIdpBody, params, options) => {
|
|
2604
|
+
return customFetch(getCreateIdpUrl(params), {
|
|
2605
|
+
...options,
|
|
2606
|
+
method: "POST",
|
|
2607
|
+
headers: {
|
|
2608
|
+
"Content-Type": "application/json",
|
|
2609
|
+
...options?.headers
|
|
2610
|
+
},
|
|
2611
|
+
body: JSON.stringify(createIdpBody)
|
|
2612
|
+
});
|
|
2613
|
+
};
|
|
2614
|
+
const getQueryIdpsUrl = (params) => {
|
|
2615
|
+
const normalizedParams = new URLSearchParams();
|
|
2616
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
2617
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
2618
|
+
});
|
|
2619
|
+
const stringifiedParams = normalizedParams.toString();
|
|
2620
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/query?${stringifiedParams}` : `${getProxyPath()}/idps/query`;
|
|
2621
|
+
};
|
|
2622
|
+
/**
|
|
2623
|
+
* Returns the identity provider connections of a project, paginated with a
|
|
2624
|
+
cursor. One row per connection, carrying its newest revision.
|
|
2625
|
+
|
|
2626
|
+
* @summary Query identity provider connections
|
|
2627
|
+
*/
|
|
2628
|
+
const queryIdps = async (queryIdpsBody, params, options) => {
|
|
2629
|
+
return customFetch(getQueryIdpsUrl(params), {
|
|
2630
|
+
...options,
|
|
2631
|
+
method: "POST",
|
|
2632
|
+
headers: {
|
|
2633
|
+
"Content-Type": "application/json",
|
|
2634
|
+
...options?.headers
|
|
2635
|
+
},
|
|
2636
|
+
body: JSON.stringify(queryIdpsBody)
|
|
2637
|
+
});
|
|
2638
|
+
};
|
|
2639
|
+
const getGetIdpByIdUrl = (id, params) => {
|
|
2640
|
+
const normalizedParams = new URLSearchParams();
|
|
2641
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
2642
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
2643
|
+
});
|
|
2644
|
+
const stringifiedParams = normalizedParams.toString();
|
|
2645
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/${id}?${stringifiedParams}` : `${getProxyPath()}/idps/${id}`;
|
|
2646
|
+
};
|
|
2647
|
+
/**
|
|
2648
|
+
* Reads a connection by its id, at its newest revision.
|
|
2649
|
+
`GET /idps/{id}/revisions` lists every revision of the connection.
|
|
2650
|
+
|
|
2651
|
+
The lookup is scoped to the project in `project_id`.
|
|
2652
|
+
|
|
2653
|
+
* @summary Get an identity provider connection by id
|
|
2654
|
+
*/
|
|
2655
|
+
const getIdpById = async (id, params, options) => {
|
|
2656
|
+
return customFetch(getGetIdpByIdUrl(id, params), {
|
|
2657
|
+
...options,
|
|
2658
|
+
method: "GET"
|
|
2659
|
+
});
|
|
2660
|
+
};
|
|
2661
|
+
const getListIdpRevisionsUrl = (id, params) => {
|
|
2662
|
+
const normalizedParams = new URLSearchParams();
|
|
2663
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
2664
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
2665
|
+
});
|
|
2666
|
+
const stringifiedParams = normalizedParams.toString();
|
|
2667
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/${id}/revisions?${stringifiedParams}` : `${getProxyPath()}/idps/${id}/revisions`;
|
|
2668
|
+
};
|
|
2669
|
+
/**
|
|
2670
|
+
* Returns every revision of one connection, newest first, paginated with a
|
|
2671
|
+
cursor. The order is fixed, so there is no `sorting`.
|
|
2672
|
+
|
|
2673
|
+
The lookup is scoped to the project in `project_id`.
|
|
2674
|
+
|
|
2675
|
+
* @summary List the revisions of an identity provider connection
|
|
2676
|
+
*/
|
|
2677
|
+
const listIdpRevisions = async (id, params, options) => {
|
|
2678
|
+
return customFetch(getListIdpRevisionsUrl(id, params), {
|
|
2679
|
+
...options,
|
|
2680
|
+
method: "GET"
|
|
2681
|
+
});
|
|
2682
|
+
};
|
|
2683
|
+
const getGetIdpRevisionByIdUrl = (revisionId, params) => {
|
|
2684
|
+
const normalizedParams = new URLSearchParams();
|
|
2685
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
2686
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
2687
|
+
});
|
|
2688
|
+
const stringifiedParams = normalizedParams.toString();
|
|
2689
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/idps/revisions/${revisionId}?${stringifiedParams}` : `${getProxyPath()}/idps/revisions/${revisionId}`;
|
|
2690
|
+
};
|
|
2691
|
+
/**
|
|
2692
|
+
* Reads one revision of a connection by its `revision_id`, the value an auth
|
|
2693
|
+
attempt or a release pins.
|
|
2694
|
+
|
|
2695
|
+
The lookup is scoped to the project in `project_id`.
|
|
2696
|
+
|
|
2697
|
+
* @summary Get one revision of an identity provider connection
|
|
2698
|
+
*/
|
|
2699
|
+
const getIdpRevisionById = async (revisionId, params, options) => {
|
|
2700
|
+
return customFetch(getGetIdpRevisionByIdUrl(revisionId, params), {
|
|
2701
|
+
...options,
|
|
2702
|
+
method: "GET"
|
|
2703
|
+
});
|
|
2704
|
+
};
|
|
2470
2705
|
const getCreateReleaseUrl = (params) => {
|
|
2471
2706
|
const normalizedParams = new URLSearchParams();
|
|
2472
2707
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
@@ -2566,10 +2801,23 @@ const getCreateGrantUrl = (params) => {
|
|
|
2566
2801
|
/**
|
|
2567
2802
|
* Bind a user or team to `project.viewer`, `project.editor`, or
|
|
2568
2803
|
`project.admin` on the project identified by the `project-id` header.
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2804
|
+
Name the principal with `user` (`user_id` or `identifier`) or `team`
|
|
2805
|
+
(`team_id` or `name`). IDs are `asgn_<opaque>`. Owning-team
|
|
2806
|
+
(`project.team`) grants are not created here — claim owns that path. An
|
|
2807
|
+
unrevoked grant with the same principal and relation occupies the unique
|
|
2808
|
+
key even after `expires_at`; DELETE it before re-creating.
|
|
2809
|
+
Create does not accept `expand`. The `user_id` and team locators
|
|
2810
|
+
return 201, whose `user` / `team` carry only `user_id` / `team_id`,
|
|
2811
|
+
and still 404 / 409 when the principal is missing or the tuple
|
|
2812
|
+
already exists. Creating by `user.identifier` answers 202 with no
|
|
2813
|
+
body on every outcome. Granting the session caller's own user is
|
|
2814
|
+
`grant.invalid` on either user locator. Read the grant back for
|
|
2815
|
+
identifier and display.
|
|
2816
|
+
|
|
2817
|
+
Accepts either a project secret (`oauth2`) or a user-bound Console
|
|
2818
|
+
session cookie (`nextgenSession`). Session callers are authorized as
|
|
2819
|
+
the human against the target project (home may differ). CSRF/Origin
|
|
2820
|
+
for cookie mutations is a follow-up (#1140).
|
|
2573
2821
|
|
|
2574
2822
|
* @summary Create grant
|
|
2575
2823
|
*/
|
|
@@ -2599,10 +2847,16 @@ viewer, editor, or admin), including expired grants so a client can
|
|
|
2599
2847
|
DELETE before re-granting. Project-secret setup (`sk_proj`) and
|
|
2600
2848
|
owning-team (`relation=team`) rows are not returned. Grants are not in
|
|
2601
2849
|
`resource_scope_index`; project scope is required on the query (same as
|
|
2602
|
-
get). Requires `project.read`. `expand: ["principal"]`
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2850
|
+
get). Requires `project.read`. `expand: ["principal"]` adds envelope
|
|
2851
|
+
fields on `user` / `team` and additionally requires `user.read` and
|
|
2852
|
+
`team.read` for project secrets (documented on the expand enum; those
|
|
2853
|
+
scopes cannot be ANDed onto this security block because they are
|
|
2854
|
+
body-conditional). A user-bound Console session that already passed
|
|
2855
|
+
the project Check may expand without those scopes.
|
|
2856
|
+
|
|
2857
|
+
Accepts either a project secret (`oauth2`) or a user-bound Console
|
|
2858
|
+
session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
|
|
2859
|
+
is a follow-up (#1140).
|
|
2606
2860
|
|
|
2607
2861
|
* @summary Query grants
|
|
2608
2862
|
*/
|
|
@@ -2634,6 +2888,14 @@ still ignores expired grants. Grants are not registered in
|
|
|
2634
2888
|
`resource_scope_index`; project scope is required on the query (same as
|
|
2635
2889
|
events). Misses, revoked rows, project-secret setup (`sk_proj`),
|
|
2636
2890
|
owning-team (`relation=team`) rows, and cross-project ids return 404.
|
|
2891
|
+
`expand=principal` adds envelope fields on `user` or `team` and requires
|
|
2892
|
+
`user.read` and `team.read` in addition to `project.read` for project
|
|
2893
|
+
secrets. A user-bound Console session that already passed the project
|
|
2894
|
+
Check may expand without those scopes.
|
|
2895
|
+
|
|
2896
|
+
Accepts either a project secret (`oauth2`) or a user-bound Console
|
|
2897
|
+
session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
|
|
2898
|
+
is a follow-up (#1140).
|
|
2637
2899
|
|
|
2638
2900
|
* @summary Get grant
|
|
2639
2901
|
*/
|
|
@@ -2657,6 +2919,10 @@ Already-revoked, missing, project-secret setup, and owning-team grants
|
|
|
2657
2919
|
return 404. The row is not un-revoked. Expired grants can still be
|
|
2658
2920
|
revoked so the unique binding can be reused.
|
|
2659
2921
|
|
|
2922
|
+
Accepts either a project secret (`oauth2`) or a user-bound Console
|
|
2923
|
+
session cookie (`nextgenSession`). CSRF/Origin for cookie mutations
|
|
2924
|
+
is a follow-up (#1140).
|
|
2925
|
+
|
|
2660
2926
|
* @summary Revoke grant
|
|
2661
2927
|
*/
|
|
2662
2928
|
const deleteGrant = async (id, params, options) => {
|
|
@@ -2723,6 +2989,122 @@ const getEvent = async (id, params, options) => {
|
|
|
2723
2989
|
method: "GET"
|
|
2724
2990
|
});
|
|
2725
2991
|
};
|
|
2992
|
+
const getGetVariablesUrl = (params) => {
|
|
2993
|
+
const normalizedParams = new URLSearchParams();
|
|
2994
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
2995
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
2996
|
+
});
|
|
2997
|
+
const stringifiedParams = normalizedParams.toString();
|
|
2998
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/variables?${stringifiedParams}` : `${getProxyPath()}/variables`;
|
|
2999
|
+
};
|
|
3000
|
+
/**
|
|
3001
|
+
* Returns the variables entered at the owner this request addresses, keyed by
|
|
3002
|
+
name — one environment of the project with `environment_name`, the project
|
|
3003
|
+
level itself without it.
|
|
3004
|
+
|
|
3005
|
+
Owners are separate, not a ladder: an environment does not inherit the
|
|
3006
|
+
project's variables and the project does not see its environments'. Reading
|
|
3007
|
+
everything a project holds therefore means reading each owner in turn.
|
|
3008
|
+
|
|
3009
|
+
Secret values are not returned. A secret appears as `{"secret": true}`,
|
|
3010
|
+
which says a value is held without disclosing it.
|
|
3011
|
+
|
|
3012
|
+
* @summary Get variables
|
|
3013
|
+
*/
|
|
3014
|
+
const getVariables = async (params, options) => {
|
|
3015
|
+
return customFetch(getGetVariablesUrl(params), {
|
|
3016
|
+
...options,
|
|
3017
|
+
method: "GET"
|
|
3018
|
+
});
|
|
3019
|
+
};
|
|
3020
|
+
const getUpdateVariablesUrl = (params) => {
|
|
3021
|
+
const normalizedParams = new URLSearchParams();
|
|
3022
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
3023
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
3024
|
+
});
|
|
3025
|
+
const stringifiedParams = normalizedParams.toString();
|
|
3026
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/variables?${stringifiedParams}` : `${getProxyPath()}/variables`;
|
|
3027
|
+
};
|
|
3028
|
+
/**
|
|
3029
|
+
* Enters, replaces and removes variables at the owner this request
|
|
3030
|
+
addresses.
|
|
3031
|
+
|
|
3032
|
+
Every name in the body is applied at exactly that owner — the project, or
|
|
3033
|
+
the environment named by `environment_name` — and reaches no other. Names
|
|
3034
|
+
not in the body are untouched.
|
|
3035
|
+
|
|
3036
|
+
A bare scalar enters a non-secret value. `{"value": …, "secret": true}`
|
|
3037
|
+
stores the value encrypted under the project's active `secret` key, after
|
|
3038
|
+
which it can be referenced but not read back. `null` removes the name from
|
|
3039
|
+
this owner (RFC 7386), which is how several variables are removed in one
|
|
3040
|
+
request; removing a name this owner does not hold is a no-op rather than an
|
|
3041
|
+
error.
|
|
3042
|
+
|
|
3043
|
+
The body is applied whole or not at all, so a rejected request leaves the
|
|
3044
|
+
owner exactly as it was. Writing the same name and owner twice replaces the
|
|
3045
|
+
value rather than duplicating it, which makes a retry safe.
|
|
3046
|
+
|
|
3047
|
+
* @summary Update variables
|
|
3048
|
+
*/
|
|
3049
|
+
const updateVariables = async (updateVariablesBody, params, options) => {
|
|
3050
|
+
return customFetch(getUpdateVariablesUrl(params), {
|
|
3051
|
+
...options,
|
|
3052
|
+
method: "PATCH",
|
|
3053
|
+
headers: {
|
|
3054
|
+
"Content-Type": "application/json",
|
|
3055
|
+
...options?.headers
|
|
3056
|
+
},
|
|
3057
|
+
body: JSON.stringify(updateVariablesBody)
|
|
3058
|
+
});
|
|
3059
|
+
};
|
|
3060
|
+
const getGetVariableUrl = (variableName, params) => {
|
|
3061
|
+
const normalizedParams = new URLSearchParams();
|
|
3062
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
3063
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
3064
|
+
});
|
|
3065
|
+
const stringifiedParams = normalizedParams.toString();
|
|
3066
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/variables/${variableName}?${stringifiedParams}` : `${getProxyPath()}/variables/${variableName}`;
|
|
3067
|
+
};
|
|
3068
|
+
/**
|
|
3069
|
+
* Reads one variable by name from the owner this request addresses — one
|
|
3070
|
+
environment of the project with `environment_name`, the project level
|
|
3071
|
+
itself without it.
|
|
3072
|
+
|
|
3073
|
+
A name that owner has not entered answers `var.not_found`, even when
|
|
3074
|
+
another owner of the same project holds it: nothing is inherited. A secret
|
|
3075
|
+
is found but not disclosed: the response is `{"secret": true}`.
|
|
3076
|
+
|
|
3077
|
+
* @summary Get a variable
|
|
3078
|
+
*/
|
|
3079
|
+
const getVariable = async (variableName, params, options) => {
|
|
3080
|
+
return customFetch(getGetVariableUrl(variableName, params), {
|
|
3081
|
+
...options,
|
|
3082
|
+
method: "GET"
|
|
3083
|
+
});
|
|
3084
|
+
};
|
|
3085
|
+
const getDeleteVariableUrl = (variableName, params) => {
|
|
3086
|
+
const normalizedParams = new URLSearchParams();
|
|
3087
|
+
Object.entries(params || {}).forEach(([key, value]) => {
|
|
3088
|
+
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : value.toString());
|
|
3089
|
+
});
|
|
3090
|
+
const stringifiedParams = normalizedParams.toString();
|
|
3091
|
+
return stringifiedParams.length > 0 ? `${getProxyPath()}/variables/${variableName}?${stringifiedParams}` : `${getProxyPath()}/variables/${variableName}`;
|
|
3092
|
+
};
|
|
3093
|
+
/**
|
|
3094
|
+
* Removes the variable this owner entered under this name.
|
|
3095
|
+
|
|
3096
|
+
A variable is deletable only by the owner that entered it. Deleting a name
|
|
3097
|
+
another owner of the same project holds answers `var.not_found` and leaves
|
|
3098
|
+
that owner's value standing.
|
|
3099
|
+
|
|
3100
|
+
* @summary Delete a variable
|
|
3101
|
+
*/
|
|
3102
|
+
const deleteVariable = async (variableName, params, options) => {
|
|
3103
|
+
return customFetch(getDeleteVariableUrl(variableName, params), {
|
|
3104
|
+
...options,
|
|
3105
|
+
method: "DELETE"
|
|
3106
|
+
});
|
|
3107
|
+
};
|
|
2726
3108
|
//#endregion
|
|
2727
3109
|
//#region ../api/dist/runtime/api-factory.mjs
|
|
2728
3110
|
/**
|
|
@@ -3038,9 +3420,10 @@ function createSanitiser() {
|
|
|
3038
3420
|
* the `Branding` JSON into a CSSStyleSheet of `:host { --zl-* }` declarations
|
|
3039
3421
|
* and applies it via `shadowRoot.adoptedStyleSheets`.
|
|
3040
3422
|
*
|
|
3041
|
-
*
|
|
3042
|
-
*
|
|
3043
|
-
*
|
|
3423
|
+
* Light and dark are independent surfaces: each side's palette is emitted under
|
|
3424
|
+
* its own `data-theme` selector only, so a key the revision left unset on one
|
|
3425
|
+
* side takes the maintained default for that side rather than the other side's
|
|
3426
|
+
* colour. Resolution between `light | dark | auto` happens in `<zitadel-login>`.
|
|
3044
3427
|
*
|
|
3045
3428
|
* Base layer: the design-tokens package ships the full `--zl-*` set as both a
|
|
3046
3429
|
* `.css` file (for host pages) and a `tokensCss` string (for shadow roots and
|
|
@@ -3048,13 +3431,32 @@ function createSanitiser() {
|
|
|
3048
3431
|
* paint correctly even when the host page didn't `@import` tokens.css — the
|
|
3049
3432
|
* orchestrator is meant to drop into any page.
|
|
3050
3433
|
*/
|
|
3051
|
-
const
|
|
3052
|
-
|
|
3053
|
-
sm
|
|
3054
|
-
md
|
|
3055
|
-
lg
|
|
3056
|
-
|
|
3057
|
-
|
|
3434
|
+
const RADIUS_STEPS = [
|
|
3435
|
+
"xs",
|
|
3436
|
+
"sm",
|
|
3437
|
+
"md",
|
|
3438
|
+
"lg",
|
|
3439
|
+
"xl"
|
|
3440
|
+
];
|
|
3441
|
+
const RADIUS_RATIOS = (() => {
|
|
3442
|
+
const base = remToNumber(tokens.radius.md);
|
|
3443
|
+
const ratios = {};
|
|
3444
|
+
for (const step of RADIUS_STEPS) ratios[step] = remToNumber(tokens.radius[step]) / base;
|
|
3445
|
+
return ratios;
|
|
3446
|
+
})();
|
|
3447
|
+
const RADIUS_PRESETS = {
|
|
3448
|
+
none: 0,
|
|
3449
|
+
sm: .25,
|
|
3450
|
+
md: .5,
|
|
3451
|
+
lg: .75
|
|
3452
|
+
};
|
|
3453
|
+
const TEXT_STEPS = [
|
|
3454
|
+
"xs",
|
|
3455
|
+
"sm",
|
|
3456
|
+
"base",
|
|
3457
|
+
"lg",
|
|
3458
|
+
"xl"
|
|
3459
|
+
];
|
|
3058
3460
|
const DENSITY_MAP = {
|
|
3059
3461
|
compact: {
|
|
3060
3462
|
"--zl-spacing-4": "0.75rem",
|
|
@@ -3106,34 +3508,35 @@ const PALETTE_MAP = {
|
|
|
3106
3508
|
* the moment before a theme resolves.
|
|
3107
3509
|
*/
|
|
3108
3510
|
const BRANDING_SELECTOR = ":host, :host([data-theme=\"light\"]), :host([data-theme=\"dark\"])";
|
|
3109
|
-
/**
|
|
3511
|
+
/** Per-side palettes. Emitted after {@link BRANDING_SELECTOR}, so they win on order. */
|
|
3512
|
+
const LIGHT_SELECTOR = ":host([data-theme=\"light\"])";
|
|
3110
3513
|
const DARK_SELECTOR = ":host([data-theme=\"dark\"])";
|
|
3111
3514
|
/**
|
|
3112
3515
|
* Build a CSS string of `:host { --zl-* }` declarations from a Branding
|
|
3113
|
-
* payload.
|
|
3114
|
-
*
|
|
3516
|
+
* payload. Shape and typography are shared across the sides and land on the
|
|
3517
|
+
* shared selector; each side's palette lands only under its own `data-theme`
|
|
3518
|
+
* selector, and nowhere else.
|
|
3519
|
+
*
|
|
3520
|
+
* No copy of the resolved side goes on the shared selector. That copy would
|
|
3521
|
+
* reach `[data-theme="light"]` as well, so a key set on the dark side and not
|
|
3522
|
+
* the light one would paint on both, with nothing in the light block to
|
|
3523
|
+
* override it. Callers stamp `data-theme` on the host — `applySurfaceTheme`
|
|
3524
|
+
* does it in the same update that adopts this sheet — so the per-side block is
|
|
3525
|
+
* already matching by the time anything paints.
|
|
3115
3526
|
*/
|
|
3116
|
-
function buildBrandingStylesheet(branding
|
|
3117
|
-
const
|
|
3118
|
-
const
|
|
3119
|
-
const
|
|
3527
|
+
function buildBrandingStylesheet(branding) {
|
|
3528
|
+
const shared = collectDeclarations(branding);
|
|
3529
|
+
const light = mapPalette(branding?.theme?.light?.palette);
|
|
3530
|
+
const dark = mapPalette(branding?.theme?.dark?.palette);
|
|
3120
3531
|
const blocks = [];
|
|
3121
|
-
if (Object.keys(
|
|
3122
|
-
if (Object.keys(
|
|
3123
|
-
if (
|
|
3124
|
-
const merged = {
|
|
3125
|
-
...lightDecls,
|
|
3126
|
-
...darkDecls
|
|
3127
|
-
};
|
|
3128
|
-
blocks.length = 0;
|
|
3129
|
-
blocks.push(formatBlock(BRANDING_SELECTOR, merged));
|
|
3130
|
-
}
|
|
3532
|
+
if (Object.keys(shared).length > 0) blocks.push(formatBlock(BRANDING_SELECTOR, shared));
|
|
3533
|
+
if (Object.keys(light).length > 0) blocks.push(formatBlock(LIGHT_SELECTOR, light));
|
|
3534
|
+
if (Object.keys(dark).length > 0) blocks.push(formatBlock(DARK_SELECTOR, dark));
|
|
3131
3535
|
return blocks.join("\n");
|
|
3132
3536
|
}
|
|
3133
3537
|
function collectDeclarations(branding) {
|
|
3134
3538
|
if (!branding) return {};
|
|
3135
3539
|
const decls = {};
|
|
3136
|
-
Object.assign(decls, mapPalette(branding.palette));
|
|
3137
3540
|
Object.assign(decls, mapTypography(branding.typography));
|
|
3138
3541
|
Object.assign(decls, mapShape(branding.shape));
|
|
3139
3542
|
return decls;
|
|
@@ -3154,24 +3557,52 @@ function mapTypography(typography) {
|
|
|
3154
3557
|
out["--zl-font-family-sans"] = typography.font_family;
|
|
3155
3558
|
out["--zl-font-family-heading"] = typography.font_family;
|
|
3156
3559
|
}
|
|
3157
|
-
if (typography.font_family_heading) out["--zl-font-family-heading"] = typography.font_family_heading;
|
|
3158
|
-
if (typography.font_family_mono) out["--zl-font-family-mono"] = typography.font_family_mono;
|
|
3159
3560
|
const scale = clamp(typography.scale ?? 1, .75, 1.25);
|
|
3160
|
-
if (scale !== 1)
|
|
3561
|
+
if (scale !== 1) for (const step of TEXT_STEPS) {
|
|
3562
|
+
out[`--zl-text-${step}-size`] = scaleRem(tokens.text[step].size, scale);
|
|
3563
|
+
out[`--zl-text-${step}-leading`] = scaleRem(tokens.text[step].leading, scale);
|
|
3564
|
+
}
|
|
3161
3565
|
return out;
|
|
3162
3566
|
}
|
|
3163
3567
|
function mapShape(shape) {
|
|
3164
3568
|
if (!shape) return {};
|
|
3165
3569
|
const out = {};
|
|
3166
|
-
|
|
3167
|
-
const radius = RADIUS_MAP[shape.radius];
|
|
3168
|
-
out["--zl-radius-md"] = radius;
|
|
3169
|
-
out["--zl-radius-lg"] = radius === "0" ? "0" : `calc(${radius} * 1.25)`;
|
|
3170
|
-
out["--zl-radius-xl"] = radius === "0" ? "0" : `calc(${radius} * 1.75)`;
|
|
3171
|
-
}
|
|
3570
|
+
Object.assign(out, mapRadius(shape.radius));
|
|
3172
3571
|
if (shape.density) Object.assign(out, DENSITY_MAP[shape.density]);
|
|
3572
|
+
const logoScale = shape.logo_scale;
|
|
3573
|
+
if (typeof logoScale === "number" && Number.isFinite(logoScale)) out["--zl-logo-scale"] = `${clamp(logoScale, .5, 2)}`;
|
|
3574
|
+
return out;
|
|
3575
|
+
}
|
|
3576
|
+
/**
|
|
3577
|
+
* A brand picks one corner value and the whole ramp follows it in proportion,
|
|
3578
|
+
* which is what keeps the card rounder than the controls inside it. Both forms
|
|
3579
|
+
* the revision accepts land here: a preset name, or an integer number of pixels
|
|
3580
|
+
* for the brand that has a specific value.
|
|
3581
|
+
*/
|
|
3582
|
+
function mapRadius(radius) {
|
|
3583
|
+
if (radius == null) return {};
|
|
3584
|
+
const out = {};
|
|
3585
|
+
if (radius === "full") {
|
|
3586
|
+
for (const step of RADIUS_STEPS) out[`--zl-radius-${step}`] = tokens.radius.full;
|
|
3587
|
+
return out;
|
|
3588
|
+
}
|
|
3589
|
+
const [base, unit] = typeof radius === "number" ? [radius, "px"] : radius in RADIUS_PRESETS ? [RADIUS_PRESETS[radius], "rem"] : [NaN, ""];
|
|
3590
|
+
if (Number.isNaN(base)) return {};
|
|
3591
|
+
for (const step of RADIUS_STEPS) {
|
|
3592
|
+
const value = base * RADIUS_RATIOS[step];
|
|
3593
|
+
out[`--zl-radius-${step}`] = value === 0 ? "0" : `${round(value)}${unit}`;
|
|
3594
|
+
}
|
|
3173
3595
|
return out;
|
|
3174
3596
|
}
|
|
3597
|
+
function scaleRem(value, scale) {
|
|
3598
|
+
return `${round(remToNumber(value) * scale)}rem`;
|
|
3599
|
+
}
|
|
3600
|
+
function remToNumber(value) {
|
|
3601
|
+
return Number.parseFloat(value);
|
|
3602
|
+
}
|
|
3603
|
+
function round(value) {
|
|
3604
|
+
return Math.round(value * 1e4) / 1e4;
|
|
3605
|
+
}
|
|
3175
3606
|
function formatBlock(selector, decls) {
|
|
3176
3607
|
return `${selector} {\n${Object.entries(decls).map(([prop, value]) => ` ${prop}: ${value};`).join("\n")}\n}`;
|
|
3177
3608
|
}
|
|
@@ -3211,8 +3642,8 @@ function applyBaseTokens(shadowRoot) {
|
|
|
3211
3642
|
* Callers should run `applyBaseTokens(shadowRoot)` first (once per shadow
|
|
3212
3643
|
* root) so the base values exist before branding patches them.
|
|
3213
3644
|
*/
|
|
3214
|
-
function applyBrandingTokens(shadowRoot, branding
|
|
3215
|
-
const css = buildBrandingStylesheet(branding
|
|
3645
|
+
function applyBrandingTokens(shadowRoot, branding) {
|
|
3646
|
+
const css = buildBrandingStylesheet(branding);
|
|
3216
3647
|
if (typeof CSSStyleSheet === "undefined") return;
|
|
3217
3648
|
const sheet = new CSSStyleSheet();
|
|
3218
3649
|
sheet.replaceSync(css);
|
|
@@ -3227,9 +3658,11 @@ function applyBrandingTokens(shadowRoot, branding, resolvedTheme) {
|
|
|
3227
3658
|
* and a variant-derived fallback on top of the same branding input.
|
|
3228
3659
|
*
|
|
3229
3660
|
* Defaults to dark: the design system's primary surface, and the mode a
|
|
3230
|
-
* hosted login page renders when a
|
|
3661
|
+
* hosted login page renders when a revision states no preference.
|
|
3231
3662
|
*/
|
|
3232
3663
|
function resolveTheme(branding) {
|
|
3664
|
+
const [only, second] = publishedSides(branding);
|
|
3665
|
+
if (only && !second) return only;
|
|
3233
3666
|
const mode = branding?.theme?.mode ?? "dark";
|
|
3234
3667
|
if (mode === "light") return "light";
|
|
3235
3668
|
if (mode === "dark") return "dark";
|
|
@@ -3247,7 +3680,7 @@ function resolveTheme(branding) {
|
|
|
3247
3680
|
* (Arimo, named first in `--zl-font-family-sans`). The component ships this
|
|
3248
3681
|
* so the auth screens render in the brand font out of the box, even when the
|
|
3249
3682
|
* server returns no branding. This is the "default users can override" layer.
|
|
3250
|
-
* - The **tenant override** (`applyFontUrl`) — `branding.font_url`, resolved
|
|
3683
|
+
* - The **tenant override** (`applyFontUrl`) — `branding.typography.font_url`, resolved
|
|
3251
3684
|
* server-side from the app → team → project branding hierarchy.
|
|
3252
3685
|
*
|
|
3253
3686
|
* Both must live at document level, not inside the shadow root: browsers ignore
|
|
@@ -3276,7 +3709,7 @@ const DEFAULT_LINK_ID = "zl-default-font-link";
|
|
|
3276
3709
|
* Design-system default brand font. Arimo is the Figma body face and leads the
|
|
3277
3710
|
* `--zl-font-family-sans` stack; loading it here makes the unbranded auth UI
|
|
3278
3711
|
* paint in the brand font instead of the system fallback. Tenants override it
|
|
3279
|
-
* with `branding.font_url`. Exported so a privacy- or offline-sensitive
|
|
3712
|
+
* with `branding.typography.font_url`. Exported so a privacy- or offline-sensitive
|
|
3280
3713
|
* deployment can self-host the same face and swap this single URL.
|
|
3281
3714
|
*/
|
|
3282
3715
|
const DEFAULT_BRAND_FONT_HREF = "https://fonts.googleapis.com/css2?family=Arimo:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap";
|
|
@@ -3296,7 +3729,7 @@ const DEFAULT_BRAND_FONT_HREF = "https://fonts.googleapis.com/css2?family=Arimo:
|
|
|
3296
3729
|
/** Per-document, per-link-id map of each owner's desired href. */
|
|
3297
3730
|
const registries = /* @__PURE__ */ new WeakMap();
|
|
3298
3731
|
/**
|
|
3299
|
-
* Inject the tenant's `branding.font_url` stylesheet. Pass `null`/`undefined`
|
|
3732
|
+
* Inject the tenant's `branding.typography.font_url` stylesheet. Pass `null`/`undefined`
|
|
3300
3733
|
* to withdraw this surface's registration (e.g. when a flow resolves with no
|
|
3301
3734
|
* tenant font); the link disappears once no surface registers a URL.
|
|
3302
3735
|
*/
|
|
@@ -3306,7 +3739,7 @@ function applyFontUrl(shadowRoot, fontUrl) {
|
|
|
3306
3739
|
/**
|
|
3307
3740
|
* Inject the design-system default font stylesheet. Defaults to
|
|
3308
3741
|
* {@link DEFAULT_BRAND_FONT_HREF}; pass `null` to withdraw this surface's
|
|
3309
|
-
* registration (the orchestrator does this when a tenant
|
|
3742
|
+
* registration (the orchestrator does this when a tenant font stylesheet takes
|
|
3310
3743
|
* over, to avoid a redundant request).
|
|
3311
3744
|
*/
|
|
3312
3745
|
function applyDefaultFont(shadowRoot, href = DEFAULT_BRAND_FONT_HREF) {
|
|
@@ -3373,7 +3806,10 @@ var ThemeController = class {
|
|
|
3373
3806
|
* element nor the branding payload names a mode. Precedence, strongest
|
|
3374
3807
|
* first: element `theme` property → `branding.theme.mode` → fallback. The
|
|
3375
3808
|
* element wins because the page embedding the widget knows its own surface
|
|
3376
|
-
* better than the tenant's stored branding does
|
|
3809
|
+
* better than the tenant's stored branding does — but it selects among the
|
|
3810
|
+
* sides the revision published, and cannot reach one it did not. A revision
|
|
3811
|
+
* with a single published side therefore ignores this property: an embedder
|
|
3812
|
+
* pinning `theme="light"` against a dark-only revision gets dark.
|
|
3377
3813
|
*/
|
|
3378
3814
|
setModePreference(explicit, fallback) {
|
|
3379
3815
|
if (this.explicitMode === explicit && this.fallbackMode === fallback) return;
|
|
@@ -3388,6 +3824,12 @@ var ThemeController = class {
|
|
|
3388
3824
|
this.detach();
|
|
3389
3825
|
}
|
|
3390
3826
|
refresh() {
|
|
3827
|
+
const [only, second] = publishedSides(this.branding);
|
|
3828
|
+
if (only && !second) {
|
|
3829
|
+
this.detach();
|
|
3830
|
+
this.update(only);
|
|
3831
|
+
return;
|
|
3832
|
+
}
|
|
3391
3833
|
const mode = this.explicitMode ?? this.branding?.theme?.mode ?? this.fallbackMode;
|
|
3392
3834
|
if (mode === "auto") {
|
|
3393
3835
|
this.attach();
|
|
@@ -3466,9 +3908,10 @@ var ZitadelSurface = class extends LitElement {
|
|
|
3466
3908
|
const root = this.shadowRoot;
|
|
3467
3909
|
if (root) {
|
|
3468
3910
|
applyBaseTokens(root);
|
|
3469
|
-
applyBrandingTokens(root, branding
|
|
3470
|
-
const
|
|
3471
|
-
|
|
3911
|
+
applyBrandingTokens(root, branding);
|
|
3912
|
+
const page = this.variant === "page";
|
|
3913
|
+
const tenantFontUrl = page ? branding?.typography?.font_url ?? null : null;
|
|
3914
|
+
applyDefaultFont(root, page && !tenantFontUrl ? void 0 : null);
|
|
3472
3915
|
applyFontUrl(root, tenantFontUrl);
|
|
3473
3916
|
}
|
|
3474
3917
|
this.dataset.theme = this.themeController.theme;
|
|
@@ -3504,7 +3947,7 @@ const TEMPLATE_NAMES = {
|
|
|
3504
3947
|
};
|
|
3505
3948
|
//#endregion
|
|
3506
3949
|
//#region src/orchestrator/templates/layout-chrome.css?inline
|
|
3507
|
-
var layout_chrome_default = ":host {\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n background: none;\n display: block;\n}\n\n:host([variant=\"page\"]) {\n background: var(--zl-background);\n min-height: 100%;\n}\n\nimg[data-zl-asset-broken] {\n display: none;\n}\n\n.zl-mount {\n min-height: var(--zl-page-min-height, auto);\n background: inherit;\n color: inherit;\n flex-direction: column;\n display: flex;\n container-type: inline-size;\n}\n\n:host([variant=\"page\"]) .zl-mount {\n min-height: var(--zl-page-min-height, 100vh);\n}\n\n.zl-mount > zl-page-shell, .zl-mount > [data-zl-template-root] {\n flex: auto;\n}\n\n.zl-attribution {\n background: none;\n justify-content: center;\n align-items: center;\n display: flex;\n}\n\n.zl-attribution[hidden] {\n display: none;\n}\n\n.zl-trustmark {\n gap: var(--zl-spacing-2-5);\n flex-wrap: wrap;\n}\n\n.zl-trustmark__mark {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n color: var(--zl-foreground);\n text-decoration: none;\n display: inline-flex;\n}\n\n.zl-trustmark__mark:hover {\n text-underline-offset: 4px;\n text-decoration: underline;\n}\n\n.zl-trustmark__mark:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n border-radius: var(--zl-radius-sm);\n}\n\n.zl-trustmark__logotype {\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n line-height: 0;\n display: block;\n}\n\n.zl-trustmark__logotype-svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.zl-card-logo {\n width: auto;\n max-width: min(12rem, 60%);\n max-height: var(--zl-card-logo-max-height, 2.5rem);\n object-fit: contain;\n}\n\n.zl-card-title {\n font-family: var(--zl-font-family-heading);\n font-size: var(--zl-text-xl-size);\n font-weight: var(--zl-font-weight-medium);\n color: var(--zl-card-foreground);\n text-align: left;\n margin: 0;\n line-height: 1;\n}\n\n.zl-card-subtitle {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n margin: 0;\n}\n\n.zl-field-group {\n gap: var(--zl-spacing-7);\n flex-direction: column;\n display: flex;\n}\n\n.zl-field-group:not(:has(*)) {\n display: none;\n}\n\n.zl-card-actions {\n gap: var(--zl-spacing-3);\n flex-direction: column;\n display: flex;\n}\n\n[data-suppress-header] .zl-card-title, [data-suppress-header] .zl-card-subtitle {\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n position: absolute;\n overflow: hidden;\n}\n\n.zl-card-nav {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n text-align: center;\n margin: 0;\n}\n\n.zl-card-nav__link {\n font: inherit;\n line-height: inherit;\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: underline;\n display: inline;\n}\n\n.zl-card-nav__link:hover {\n color: var(--zl-foreground);\n}\n\n.zl-card-nav__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-card-forgot {\n text-align: right;\n margin: 0;\n}\n\n.zl-card-forgot__link {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: none;\n display: inline;\n}\n\n.zl-card-forgot__link:hover {\n text-decoration: underline;\n}\n\n.zl-card-forgot__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-split {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n align-items: var(--zl-split-align, center);\n gap: var(--zl-spacing-8);\n width: 100%;\n min-height: 100%;\n display: grid;\n}\n\n.zl-split__brand {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n padding: var(--zl-spacing-8) var(--zl-spacing-4);\n flex-direction: column;\n display: flex;\n}\n\n.zl-split__logo {\n max-width: min(16rem, 60%);\n max-height: var(--zl-split-logo-max-height, 16rem);\n}\n\n.zl-split__logo:has( + .zl-split__hero) {\n max-height: var(--zl-split-logo-max-height, 8rem);\n}\n\n.zl-split__logo:has( + .zl-split__hero) + .zl-split__hero {\n max-height: min(var(--zl-split-hero-max-height, 22.5rem),\n max(6rem,\n calc(100vh - 104px - var(--zl-spacing-8) - var(--zl-spacing-8) -\n 2.5rem - var(--zl-spacing-6) - var(--zl-spacing-6) -\n var(--zl-split-logo-max-height, 8rem))));\n}\n\n.zl-split__hero {\n width: 100%;\n max-height: var(--zl-split-hero-max-height, min(22.5rem, 60vh));\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n}\n\n.zl-split__placeholder {\n aspect-ratio: 4 / 5;\n border-radius: var(--zl-radius-lg);\n background: radial-gradient(120% 120% at 18% 12%,\n var(--zl-gradient-lavender-start) 0%,\n transparent 60%),\n radial-gradient(130% 130% at 85% 92%,\n var(--zl-gradient-rose-start) 0%,\n transparent 60%),\n var(--zl-card);\n width: min(18rem, 85%);\n}\n\n.zl-split__form {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n flex-direction: column;\n padding: 16px;\n display: flex;\n}\n\n.zl-split__compact {\n max-width: min(12rem, 60%);\n display: none;\n}\n\nimg.zl-split__compact {\n max-height: 2.5rem;\n}\n\nimg.zl-split__compact--hero {\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n width: 100%;\n max-width: 100%;\n max-height: 6rem;\n}\n\n.zl-split--right .zl-split__brand {\n order: 2;\n}\n\n.zl-split--right .zl-split__form {\n order: 1;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n gap: var(--zl-spacing-8);\n width: 100%;\n display: grid;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution > * {\n grid-column: 2;\n justify-self: center;\n}\n\nzl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution ::slotted(*) {\n grid-column: 2;\n justify-self: center;\n}\n\nzl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution ::slotted(*) {\n grid-column: 1;\n}\n\n@container (width <= 48rem) {\n .zl-split {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .zl-split__brand {\n display: var(--zl-split-brand-mobile, none);\n }\n\n .zl-split__compact {\n display: block;\n }\n\n zl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: minmax(0, 1fr);\n }\n\n zl-page-shell:has(.zl-split) .zl-attribution > *, zl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n }\n}\n\n.zl-hero {\n text-align: left;\n width: 100%;\n max-width: 34rem;\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n flex-direction: column;\n display: flex;\n}\n\n.zl-hero__nav {\n margin-bottom: var(--zl-spacing-8);\n justify-content: space-between;\n align-items: center;\n display: flex;\n}\n\n.zl-hero__brand {\n align-items: center;\n gap: var(--zl-spacing-2);\n letter-spacing: -.01em;\n font-size: 1.125rem;\n font-weight: 700;\n display: inline-flex;\n}\n\n.zl-hero__brand-logo {\n max-height: 1.75rem;\n}\n\n.zl-hero__brand-mark {\n border-radius: var(--zl-radius-md);\n background: linear-gradient(135deg,\n var(--zl-gradient-lavender-start),\n var(--zl-gradient-rose-start));\n width: 1.75rem;\n height: 1.75rem;\n display: inline-flex;\n}\n\n.zl-hero__compact-brand {\n overflow-wrap: anywhere;\n letter-spacing: -.01em;\n max-width: 100%;\n color: var(--zl-foreground);\n margin: 0;\n font-size: 1.125rem;\n font-weight: 700;\n}\n\n.zl-hero__nav-links {\n gap: var(--zl-spacing-6);\n color: var(--zl-muted-foreground);\n font-size: .9375rem;\n display: flex;\n}\n\n.zl-hero__nav-links a {\n color: inherit;\n text-decoration: none;\n}\n\n.zl-hero__nav-links a:hover {\n text-decoration: underline;\n}\n\n.zl-hero__eyebrow {\n margin: 0 0 var(--zl-spacing-4);\n letter-spacing: .08em;\n text-transform: uppercase;\n color: var(--zl-muted-foreground);\n font-size: .8125rem;\n font-weight: 600;\n}\n\n.zl-hero__headline {\n margin: 0 0 var(--zl-spacing-4);\n font-family: var(--zl-font-family-heading);\n letter-spacing: -.02em;\n font-size: 2.75rem;\n font-weight: 700;\n line-height: 1.1;\n}\n\n.zl-hero__sub {\n margin: 0 0 var(--zl-spacing-8);\n max-width: 30rem;\n color: var(--zl-muted-foreground);\n font-size: 1.0625rem;\n line-height: 1.6;\n}\n\n.zl-hero__bullets {\n gap: var(--zl-spacing-2);\n margin: 0 0 var(--zl-spacing-8);\n flex-direction: column;\n padding: 0;\n list-style: none;\n display: flex;\n}\n\n.zl-hero__bullets li {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-size: 1rem;\n display: flex;\n}\n\n.zl-hero__bullets li:before {\n content: \"✓\";\n color: var(--zl-success);\n font-weight: 700;\n}\n\n.zl-hero__footnote {\n padding-top: var(--zl-spacing-6);\n border-top: 1px solid var(--zl-border);\n color: var(--zl-muted-foreground);\n margin: 0;\n font-size: .8125rem;\n}\n\n.zl-hero__footnote strong {\n color: var(--zl-muted-foreground);\n font-weight: 600;\n}\n\n.zl-minimal {\n gap: var(--zl-spacing-6);\n flex-direction: column;\n width: min(24rem, 100%);\n margin-inline: auto;\n display: flex;\n}\n\n:host([variant=\"page\"]) .zl-minimal {\n padding: 52px 16px;\n}\n";
|
|
3950
|
+
var layout_chrome_default = ":host {\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n background: none;\n display: block;\n}\n\n:host([variant=\"page\"]) {\n background: var(--zl-background);\n min-height: 100%;\n}\n\nimg[data-zl-asset-broken] {\n display: none;\n}\n\n.zl-mount {\n min-height: var(--zl-page-min-height, auto);\n background: inherit;\n color: inherit;\n flex-direction: column;\n display: flex;\n container-type: inline-size;\n}\n\n:host([variant=\"page\"]) .zl-mount {\n min-height: var(--zl-page-min-height, 100vh);\n}\n\n.zl-mount > zl-page-shell, .zl-mount > [data-zl-template-root] {\n flex: auto;\n}\n\n.zl-attribution {\n background: none;\n justify-content: center;\n align-items: center;\n display: flex;\n}\n\n.zl-attribution[hidden] {\n display: none;\n}\n\n.zl-trustmark {\n gap: var(--zl-spacing-2-5);\n flex-wrap: wrap;\n}\n\n.zl-trustmark__mark {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n color: var(--zl-foreground);\n text-decoration: none;\n display: inline-flex;\n}\n\n.zl-trustmark__mark:hover {\n text-underline-offset: 4px;\n text-decoration: underline;\n}\n\n.zl-trustmark__mark:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n border-radius: var(--zl-radius-sm);\n}\n\n.zl-trustmark__logotype {\n flex-shrink: 0;\n width: 65px;\n height: 16px;\n line-height: 0;\n display: block;\n}\n\n.zl-trustmark__logotype-svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n\n.zl-card-logo {\n width: auto;\n max-width: min(12rem, 60%);\n max-height: calc(var(--zl-card-logo-max-height, 2.5rem) * var(--zl-logo-scale, 1));\n object-fit: contain;\n}\n\n.zl-card-title {\n font-family: var(--zl-font-family-heading);\n font-size: var(--zl-text-xl-size);\n font-weight: var(--zl-font-weight-medium);\n color: var(--zl-card-foreground);\n text-align: left;\n margin: 0;\n line-height: 1;\n}\n\n.zl-card-subtitle {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n margin: 0;\n}\n\n.zl-field-group {\n gap: var(--zl-spacing-7);\n flex-direction: column;\n display: flex;\n}\n\n.zl-field-group:not(:has(*)) {\n display: none;\n}\n\n.zl-card-actions {\n gap: var(--zl-spacing-3);\n flex-direction: column;\n display: flex;\n}\n\n[data-suppress-header] .zl-card-title, [data-suppress-header] .zl-card-subtitle {\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n position: absolute;\n overflow: hidden;\n}\n\n.zl-card-nav {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-muted-foreground);\n text-align: center;\n margin: 0;\n}\n\n.zl-card-nav__link {\n font: inherit;\n line-height: inherit;\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: underline;\n display: inline;\n}\n\n.zl-card-nav__link:hover {\n color: var(--zl-foreground);\n}\n\n.zl-card-nav__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-card-forgot {\n text-align: right;\n margin: 0;\n}\n\n.zl-card-forgot__link {\n font-family: var(--zl-font-family-sans);\n font-size: var(--zl-text-sm-size);\n line-height: var(--zl-text-sm-leading);\n font-weight: var(--zl-font-weight-normal);\n color: var(--zl-link);\n text-underline-offset: 4px;\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: none;\n display: inline;\n}\n\n.zl-card-forgot__link:hover {\n text-decoration: underline;\n}\n\n.zl-card-forgot__link:focus-visible {\n outline: var(--zl-focus-width) solid var(--zl-ring);\n outline-offset: var(--zl-focus-offset);\n}\n\n.zl-split {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n align-items: var(--zl-split-align, center);\n gap: var(--zl-spacing-8);\n width: 100%;\n min-height: 100%;\n display: grid;\n}\n\n.zl-split__brand {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n padding: var(--zl-spacing-8) var(--zl-spacing-4);\n flex-direction: column;\n display: flex;\n}\n\n.zl-split__logo {\n max-width: min(16rem, 60%);\n max-height: calc(var(--zl-split-logo-max-height, 16rem) * var(--zl-logo-scale, 1));\n}\n\n.zl-split__logo:has( + .zl-split__hero) {\n max-height: calc(var(--zl-split-logo-max-height, 8rem) * var(--zl-logo-scale, 1));\n}\n\n.zl-split__logo:has( + .zl-split__hero) + .zl-split__hero {\n max-height: min(var(--zl-split-hero-max-height, 22.5rem),\n max(6rem,\n calc(100vh - 104px - var(--zl-spacing-8) - var(--zl-spacing-8) -\n 2.5rem - var(--zl-spacing-6) - var(--zl-spacing-6) -\n calc(var(--zl-split-logo-max-height, 8rem) * var(--zl-logo-scale, 1)))));\n}\n\n.zl-split__hero {\n width: 100%;\n max-height: var(--zl-split-hero-max-height, min(22.5rem, 60vh));\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n}\n\n.zl-split__placeholder {\n aspect-ratio: 4 / 5;\n border-radius: var(--zl-radius-lg);\n background: radial-gradient(120% 120% at 18% 12%,\n var(--zl-gradient-lavender-start) 0%,\n transparent 60%),\n radial-gradient(130% 130% at 85% 92%,\n var(--zl-gradient-rose-start) 0%,\n transparent 60%),\n var(--zl-card);\n width: min(18rem, 85%);\n}\n\n.zl-split__form {\n justify-content: center;\n align-items: center;\n gap: var(--zl-spacing-6);\n flex-direction: column;\n padding: 16px;\n display: flex;\n}\n\n.zl-split__compact {\n max-width: min(12rem, 60%);\n display: none;\n}\n\nimg.zl-split__compact {\n max-height: calc(2.5rem * var(--zl-logo-scale, 1));\n}\n\nimg.zl-split__compact--hero {\n border-radius: var(--zl-radius-lg);\n object-fit: cover;\n width: 100%;\n max-width: 100%;\n max-height: 6rem;\n}\n\n.zl-split--right .zl-split__brand {\n order: 2;\n}\n\n.zl-split--right .zl-split__form {\n order: 1;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: var(--zl-split-columns, minmax(0, 1fr) minmax(0, 1fr));\n gap: var(--zl-spacing-8);\n width: 100%;\n display: grid;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution > * {\n grid-column: 2;\n justify-self: center;\n}\n\nzl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n}\n\nzl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution ::slotted(*) {\n grid-column: 2;\n justify-self: center;\n}\n\nzl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution ::slotted(*) {\n grid-column: 1;\n}\n\n@container (width <= 48rem) {\n .zl-split {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .zl-split__brand {\n display: var(--zl-split-brand-mobile, none);\n }\n\n .zl-split__compact {\n display: block;\n }\n\n zl-page-shell:has(.zl-split) [slot=\"footer\"].zl-attribution {\n grid-template-columns: minmax(0, 1fr);\n }\n\n zl-page-shell:has(.zl-split) .zl-attribution > *, zl-page-shell:has(.zl-split--right) [slot=\"footer\"].zl-attribution > * {\n grid-column: 1;\n }\n}\n\n.zl-hero {\n text-align: left;\n width: 100%;\n max-width: 34rem;\n color: var(--zl-foreground);\n font-family: var(--zl-font-family-sans);\n flex-direction: column;\n display: flex;\n}\n\n.zl-hero__nav {\n margin-bottom: var(--zl-spacing-8);\n justify-content: space-between;\n align-items: center;\n display: flex;\n}\n\n.zl-hero__brand {\n align-items: center;\n gap: var(--zl-spacing-2);\n letter-spacing: -.01em;\n font-size: 1.125rem;\n font-weight: 700;\n display: inline-flex;\n}\n\n.zl-hero__brand-logo {\n max-height: calc(1.75rem * var(--zl-logo-scale, 1));\n}\n\n.zl-hero__brand-mark {\n border-radius: var(--zl-radius-md);\n background: linear-gradient(135deg,\n var(--zl-gradient-lavender-start),\n var(--zl-gradient-rose-start));\n width: 1.75rem;\n height: 1.75rem;\n display: inline-flex;\n}\n\n.zl-hero__compact-brand {\n overflow-wrap: anywhere;\n letter-spacing: -.01em;\n max-width: 100%;\n color: var(--zl-foreground);\n margin: 0;\n font-size: 1.125rem;\n font-weight: 700;\n}\n\n.zl-hero__nav-links {\n gap: var(--zl-spacing-6);\n color: var(--zl-muted-foreground);\n font-size: .9375rem;\n display: flex;\n}\n\n.zl-hero__nav-links a {\n color: inherit;\n text-decoration: none;\n}\n\n.zl-hero__nav-links a:hover {\n text-decoration: underline;\n}\n\n.zl-hero__eyebrow {\n margin: 0 0 var(--zl-spacing-4);\n letter-spacing: .08em;\n text-transform: uppercase;\n color: var(--zl-muted-foreground);\n font-size: .8125rem;\n font-weight: 600;\n}\n\n.zl-hero__headline {\n margin: 0 0 var(--zl-spacing-4);\n font-family: var(--zl-font-family-heading);\n letter-spacing: -.02em;\n font-size: 2.75rem;\n font-weight: 700;\n line-height: 1.1;\n}\n\n.zl-hero__sub {\n margin: 0 0 var(--zl-spacing-8);\n max-width: 30rem;\n color: var(--zl-muted-foreground);\n font-size: 1.0625rem;\n line-height: 1.6;\n}\n\n.zl-hero__bullets {\n gap: var(--zl-spacing-2);\n margin: 0 0 var(--zl-spacing-8);\n flex-direction: column;\n padding: 0;\n list-style: none;\n display: flex;\n}\n\n.zl-hero__bullets li {\n align-items: center;\n gap: var(--zl-spacing-2);\n font-size: 1rem;\n display: flex;\n}\n\n.zl-hero__bullets li:before {\n content: \"✓\";\n color: var(--zl-success);\n font-weight: 700;\n}\n\n.zl-hero__footnote {\n padding-top: var(--zl-spacing-6);\n border-top: 1px solid var(--zl-border);\n color: var(--zl-muted-foreground);\n margin: 0;\n font-size: .8125rem;\n}\n\n.zl-hero__footnote strong {\n color: var(--zl-muted-foreground);\n font-weight: 600;\n}\n\n.zl-minimal {\n gap: var(--zl-spacing-6);\n flex-direction: column;\n width: min(24rem, 100%);\n margin-inline: auto;\n display: flex;\n}\n\n:host([variant=\"page\"]) .zl-minimal {\n padding: 52px 16px;\n}\n";
|
|
3508
3951
|
//#endregion
|
|
3509
3952
|
//#region src/orchestrator/zitadel-login.ts
|
|
3510
3953
|
/** Narrow a rendered named element to the `formValue` field-atom contract. */
|
|
@@ -3635,6 +4078,13 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
|
|
|
3635
4078
|
this.#_formValues_accessor_storage = value;
|
|
3636
4079
|
}
|
|
3637
4080
|
engine = null;
|
|
4081
|
+
/**
|
|
4082
|
+
* The theme the last commit rendered with. The template output carries the
|
|
4083
|
+
* resolved side's mark, so a theme change rewrites the string and
|
|
4084
|
+
* `unsafeHTML` rebuilds the form — which drops what the visitor had typed
|
|
4085
|
+
* unless it is put back.
|
|
4086
|
+
*/
|
|
4087
|
+
lastRenderedTheme = null;
|
|
3638
4088
|
sanitise = createSanitiser();
|
|
3639
4089
|
/**
|
|
3640
4090
|
* Cached compiled tenant template, keyed by source string. Re-rendering on
|
|
@@ -3733,9 +4183,14 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
|
|
|
3733
4183
|
}
|
|
3734
4184
|
for (const card of this.shadowRoot.querySelectorAll("zl-card")) card.toggleAttribute("data-suppress-header", this.suppressHeader);
|
|
3735
4185
|
}
|
|
4186
|
+
const previousTheme = this.lastRenderedTheme;
|
|
4187
|
+
this.lastRenderedTheme = this.themeController.theme;
|
|
3736
4188
|
const props = changed;
|
|
3737
|
-
if (
|
|
3738
|
-
|
|
4189
|
+
if (props.has("response")) {
|
|
4190
|
+
this.hydrateStepAfterRender(props.get("response") == null);
|
|
4191
|
+
return;
|
|
4192
|
+
}
|
|
4193
|
+
if (previousTheme !== null && previousTheme !== this.lastRenderedTheme) this.restoreValuesAfterRender();
|
|
3739
4194
|
}
|
|
3740
4195
|
/**
|
|
3741
4196
|
* Apply captured values and move focus once the new step has fully
|
|
@@ -3750,11 +4205,19 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
|
|
|
3750
4205
|
* swaps are user-initiated, so focus moves in both modes.
|
|
3751
4206
|
*/
|
|
3752
4207
|
async hydrateStepAfterRender(initial = false) {
|
|
4208
|
+
await this.restoreValuesAfterRender();
|
|
4209
|
+
if (!initial || this.variant === "page") this.moveFocusToFirstField(initial && this.variant === "page");
|
|
4210
|
+
}
|
|
4211
|
+
/**
|
|
4212
|
+
* Put captured values back once the rebuilt subtree has rendered. Awaits the
|
|
4213
|
+
* child atoms' own first render before touching them, rather than guessing a
|
|
4214
|
+
* frame with `requestAnimationFrame`.
|
|
4215
|
+
*/
|
|
4216
|
+
async restoreValuesAfterRender() {
|
|
3753
4217
|
await this.updateComplete;
|
|
3754
4218
|
const atoms = this.shadowRoot?.querySelectorAll("zl-field, zl-select, zl-checkbox, zl-button");
|
|
3755
4219
|
if (atoms) await Promise.all(Array.from(atoms).map((atom) => atom.updateComplete));
|
|
3756
4220
|
this.applyValuesToFields();
|
|
3757
|
-
if (!initial || this.variant === "page") this.moveFocusToFirstField(initial && this.variant === "page");
|
|
3758
4221
|
}
|
|
3759
4222
|
render() {
|
|
3760
4223
|
if (this.startupError) return html`<form class="zl-mount" novalidate>
|
|
@@ -3796,6 +4259,20 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
|
|
|
3796
4259
|
return rendered + html;
|
|
3797
4260
|
}
|
|
3798
4261
|
/**
|
|
4262
|
+
* The branding a template renders against, with `logo_url` already resolved
|
|
4263
|
+
* to the mark for the active side. Templates read one logo field and get the
|
|
4264
|
+
* right file per surface; the per-side URLs stay on `theme` for a template
|
|
4265
|
+
* that wants to reach them itself.
|
|
4266
|
+
*/
|
|
4267
|
+
brandingForTemplate() {
|
|
4268
|
+
if (!this.branding) return {};
|
|
4269
|
+
const logoUrl = resolveLogoUrl(this.branding, this.themeController.theme);
|
|
4270
|
+
return {
|
|
4271
|
+
...this.branding,
|
|
4272
|
+
logo_url: logoUrl
|
|
4273
|
+
};
|
|
4274
|
+
}
|
|
4275
|
+
/**
|
|
3799
4276
|
* "Secured with Zitadel" attribution chrome injected into every
|
|
3800
4277
|
* template's page-shell footer slot. Controlled by
|
|
3801
4278
|
* `branding.attribution.show_zitadel` — defaults to `true` for
|
|
@@ -3876,7 +4353,11 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
|
|
|
3876
4353
|
this.armed = true;
|
|
3877
4354
|
} else if (!hasBack && this.armed) {
|
|
3878
4355
|
this.armed = false;
|
|
3879
|
-
if (history.state?.zl === true) {
|
|
4356
|
+
if (history.state?.zl === true) if (this.completing) history.replaceState({
|
|
4357
|
+
...history.state,
|
|
4358
|
+
zl: false
|
|
4359
|
+
}, "");
|
|
4360
|
+
else {
|
|
3880
4361
|
this.ignoreNextPop = true;
|
|
3881
4362
|
history.back();
|
|
3882
4363
|
}
|
|
@@ -3948,7 +4429,7 @@ let ZitadelLogin = class ZitadelLogin extends ZitadelSurface {
|
|
|
3948
4429
|
messages: [],
|
|
3949
4430
|
identity: this.deriveIdentity(),
|
|
3950
4431
|
errors,
|
|
3951
|
-
branding: this.
|
|
4432
|
+
branding: this.brandingForTemplate(),
|
|
3952
4433
|
loading: this.loading
|
|
3953
4434
|
};
|
|
3954
4435
|
let raw;
|
|
@@ -4612,7 +5093,7 @@ let ZitadelLogout = class ZitadelLogout extends LitElement {
|
|
|
4612
5093
|
const root = this.shadowRoot;
|
|
4613
5094
|
if (root && !this.templateMode) {
|
|
4614
5095
|
applyBaseTokens(root);
|
|
4615
|
-
applyBrandingTokens(root, void 0
|
|
5096
|
+
applyBrandingTokens(root, void 0);
|
|
4616
5097
|
}
|
|
4617
5098
|
this.dataset.theme = this.themeController.theme;
|
|
4618
5099
|
this.toggleAttribute("data-theme-dark", this.themeController.theme === "dark");
|
|
@@ -5096,6 +5577,6 @@ __decorate([state()], ZitadelSession.prototype, "loading", null);
|
|
|
5096
5577
|
__decorate([state()], ZitadelSession.prototype, "errorMessage", null);
|
|
5097
5578
|
ZitadelSession = __decorate([customElement("zitadel-session")], ZitadelSession);
|
|
5098
5579
|
//#endregion
|
|
5099
|
-
export {
|
|
5580
|
+
export { getCurrentStep as C, zitadelTrustmarkInnerHtml as D, ZITADEL_ATTRIBUTION_LOGOTYPE_SVG as E, validateBranding as S, submitStep as T, MANDATORY_GATES_MARKER as _, TEMPLATE_NAMES as a, publishedSides as b, applyBrandingTokens as c, createSanitiser as d, builtinLocales as f, en as g, de as h, layout_chrome_default as i, buildBrandingStylesheet as l, it as m, ZitadelLogout as n, ThemeController as o, businessLocales as p, ZitadelLogin as r, applyFontUrl as s, ZitadelSession as t, resolveTheme as u, mandatoryGatesMarkerComment as v, startFlow as w, resolveLogoUrl as x, patchMandatoryGates as y };
|
|
5100
5581
|
|
|
5101
|
-
//# sourceMappingURL=orchestrator-
|
|
5582
|
+
//# sourceMappingURL=orchestrator-BVmKaCqz.mjs.map
|