mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-04 13:22:16 +00:00
feat: label policy (#1708)
* feat: label policy proto extension * feat: label policy and activate event * feat: label policy asset events * feat: label policy asset commands * feat: add storage key * feat: storage key validation * feat: label policy asset tests * feat: label policy query side * feat: avatar * feat: avatar event * feat: human avatar * feat: avatar read side * feat: font on iam label policy * feat: label policy font * feat: possiblity to create bucket on put file * uplaoder * login policy logo * set bucket prefix * feat: avatar upload * feat: avatar upload * feat: use assets on command side * feat: fix human avatar removed event * feat: remove human avatar * feat: mock asset storage * feat: remove human avatar * fix(operator): add configuration of asset storage to zitadel operator * feat(console): private labeling policy (#1697) * private labeling component, routing, preview * font, colors, upload, i18n * show logo * fix: uniqueness (#1710) * fix: uniqueconstraint to lower * feat: change org * feat: org change test * feat: change org * fix: tests * fix: handle domain claims correctly * feat: update org Co-authored-by: fabi <[email protected]> * fix: handle domain claimed event correctly for service users (#1711) * fix: handle domain claimed event correctly on user view * fix: ignore domain claimed events for email notifications * fix: change org * handle org changed in read models correctly * fix: change org in user grant handler Co-authored-by: fabi <[email protected]> * fix: correct value (#1695) * docs(api): correct link (#1712) * upload service Co-authored-by: Livio Amstutz <[email protected]> Co-authored-by: fabi <[email protected]> Co-authored-by: Florian Forster <[email protected]> * feat: fix tests, * feat: remove assets from label policy * fix npm, set environment * lint ts * remove stylelinting * fix(operator): add mapping for console with changed unit tests * fix(operator): add secrets as env variables to pod * feat: remove human avatar * fix(operator): add secrets as env variables to pod * feat: map label policy * feat: labelpolicy, admin, mgmt, adv settings (#1715) * fetch label policy, mgmt, admin service * feat: advanced beh, links, add, update * lint ts * feat: watermark * feat: remove human avatar * feat: remove human avatar * feat: remove human avatar * feat: remove human avatar * feat: remove human avatar * feat: remove human avatar * feat: remove human avatar * feat: custom css * css * css * css * css * css * getobject * feat: dynamic handler * feat: varibale css * content info * css overwrite * feat: variablen css * feat: generate css file * feat: dark mode * feat: dark mode * fix logo css * feat: upload logos * dark mode with cookie * feat: handle images in login * avatar css and begin font * feat: avatar * feat: user avatar * caching of static assets in login * add avatar.js to main.html * feat: header dont show logo if no url * feat: label policy colors * feat: mock asset storage * feat: mock asset storage * feat: fix tests * feat: user avatar * feat: header logo * avatar * avatar * make it compatible with go 1.15 * feat: remove unused logos * fix handler * fix: styling error handling * fonts * fix: download func * switch to mux * fix: change upload api to assets * fix build * fix: download avatar * fix: download logos * fix: my avatar * font * fix: remove error msg popup possibility * fix: docs * fix: svalidate colors * rem msg popup from frontend * fix: email with private labeling * fix: tests * fix: email templates * fix: change migration version * fix: fix duplicate imports * fix(console): assets, service url, upload, policy current and preview (#1781) * upload endpoint, layout * fetch current, preview, fix upload * cleanup private labeling * fix linting * begin generated asset handler * generate asset api in dockerfile * features for label policy * features for label policy * features * flag for asset generator * change asset generator flag * fix label policy view in grpc * fix: layout, activate policy (#1786) * theme switcher up on top * change layout * activate policy * feat(console): label policy back color, layout (#1788) * theme switcher up on top * change layout * activate policy * fix overwrite value fc * reset policy, reset service * autosave policy, preview desc, layout impv * layout, i18n * background colors, inject material styles * load images * clean, lint * fix layout * set custom hex * fix content size conversion * remove font format in generated css * fix features for assets * fix(console): label policy colors, image downloads, preview (#1804) * load images * colors, images binding * lint * refresh emitter * lint * propagate font colors * upload error handling * label policy feature check * add blob in csp for console * log * fix: feature edits for label policy, refresh state on upload (#1807) * show error on load image, stop spinner * fix merge * fix migration versions * fix assets * fix csp * fix background color * scss * fix build * lint scss * fix statik for console * fix features check for label policy * cleanup * lint * public links * fix notifications * public links * feat: merge main * feat: fix translation files * fix migration * set api domain * fix logo in email * font face in email * font face in email * validate assets on upload * cleanup * add missing translations * add missing translations Co-authored-by: Livio Amstutz <[email protected]> Co-authored-by: Stefan Benz <[email protected]> Co-authored-by: Max Peintner <[email protected]> Co-authored-by: Florian Forster <[email protected]>
This commit is contained in:
co-authored by
fabi
Livio Amstutz
Florian Forster
Stefan Benz
Max Peintner
parent
c0d9d86b09
commit
73d37459bb
@@ -86,6 +86,7 @@ func csp(zitadelDomain string) *middleware.CSP {
|
||||
AddHost("fonts.googleapis.com").
|
||||
AddHost("fonts.gstatic.com").
|
||||
AddHost("maxst.icons8.com") //TODO: host it
|
||||
csp.ImgSrc = csp.ImgSrc.AddScheme("blob")
|
||||
return &csp
|
||||
}
|
||||
|
||||
|
||||
@@ -11,12 +11,15 @@ import (
|
||||
"github.com/caos/zitadel/internal/api/http/middleware"
|
||||
auth_repository "github.com/caos/zitadel/internal/auth/repository"
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/cache"
|
||||
cache_config "github.com/caos/zitadel/internal/cache/config"
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/form"
|
||||
"github.com/caos/zitadel/internal/id"
|
||||
"github.com/caos/zitadel/internal/static"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
_ "github.com/caos/zitadel/internal/ui/login/statik"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
@@ -32,6 +35,8 @@ type Login struct {
|
||||
parser *form.Parser
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
staticStorage static.Storage
|
||||
staticCache cache.Cache
|
||||
authRepo auth_repository.Repository
|
||||
baseURL string
|
||||
zitadelURL string
|
||||
@@ -49,6 +54,7 @@ type Config struct {
|
||||
CSRF CSRF
|
||||
UserAgentCookieConfig *middleware.UserAgentCookieConfig
|
||||
Cache middleware.CacheConfig
|
||||
StaticCache cache_config.CacheConfig
|
||||
}
|
||||
|
||||
type CSRF struct {
|
||||
@@ -62,7 +68,7 @@ const (
|
||||
handlerPrefix = "/login"
|
||||
)
|
||||
|
||||
func CreateLogin(config Config, command *command.Commands, query *query.Queries, authRepo *eventsourcing.EsRepository, systemDefaults systemdefaults.SystemDefaults, localDevMode bool) (*Login, string) {
|
||||
func CreateLogin(config Config, command *command.Commands, query *query.Queries, authRepo *eventsourcing.EsRepository, staticStorage static.Storage, systemDefaults systemdefaults.SystemDefaults, localDevMode bool) (*Login, string) {
|
||||
aesCrypto, err := crypto.NewAESCrypto(systemDefaults.IDPConfigVerificationKey)
|
||||
if err != nil {
|
||||
logging.Log("HANDL-s90ew").WithError(err).Debug("error create new aes crypto")
|
||||
@@ -73,6 +79,7 @@ func CreateLogin(config Config, command *command.Commands, query *query.Queries,
|
||||
zitadelURL: config.ZitadelURL,
|
||||
command: command,
|
||||
query: query,
|
||||
staticStorage: staticStorage,
|
||||
authRepo: authRepo,
|
||||
IDPConfigAesCrypto: aesCrypto,
|
||||
iamDomain: systemDefaults.Domain,
|
||||
@@ -81,6 +88,9 @@ func CreateLogin(config Config, command *command.Commands, query *query.Queries,
|
||||
if localDevMode {
|
||||
prefix = handlerPrefix
|
||||
}
|
||||
login.staticCache, err = config.StaticCache.Config.NewCache()
|
||||
logging.Log("CONFI-dgg31").OnError(err).Panic("unable to create storage cache")
|
||||
|
||||
statikFS, err := fs.NewWithNamespace("login")
|
||||
logging.Log("CONFI-Ga21f").OnError(err).Panic("unable to create filesystem")
|
||||
|
||||
@@ -92,7 +102,7 @@ func CreateLogin(config Config, command *command.Commands, query *query.Queries,
|
||||
userAgentCookie, err := middleware.NewUserAgentHandler(config.UserAgentCookieConfig, id.SonyFlakeGenerator, localDevMode)
|
||||
logging.Log("CONFI-Dvwf2").OnError(err).Panic("unable to create userAgentInterceptor")
|
||||
login.router = CreateRouter(login, statikFS, csrf, cache, security, userAgentCookie, middleware.TelemetryHandler(EndpointResources))
|
||||
login.renderer = CreateRenderer(prefix, statikFS, config.LanguageCookieName, config.DefaultLanguage)
|
||||
login.renderer = CreateRenderer(prefix, statikFS, staticStorage, config.LanguageCookieName, config.DefaultLanguage)
|
||||
login.parser = form.NewParser()
|
||||
return login, handlerPrefix
|
||||
}
|
||||
|
||||
@@ -3,10 +3,13 @@ package handler
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/static"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/gorilla/csrf"
|
||||
@@ -25,12 +28,14 @@ const (
|
||||
|
||||
type Renderer struct {
|
||||
*renderer.Renderer
|
||||
pathPrefix string
|
||||
pathPrefix string
|
||||
staticStorage static.Storage
|
||||
}
|
||||
|
||||
func CreateRenderer(pathPrefix string, staticDir http.FileSystem, cookieName string, defaultLanguage language.Tag) *Renderer {
|
||||
func CreateRenderer(pathPrefix string, staticDir http.FileSystem, staticStorage static.Storage, cookieName string, defaultLanguage language.Tag) *Renderer {
|
||||
r := &Renderer{
|
||||
pathPrefix: pathPrefix,
|
||||
pathPrefix: pathPrefix,
|
||||
staticStorage: staticStorage,
|
||||
}
|
||||
tmplMapping := map[string]string{
|
||||
tmplError: "error.html",
|
||||
@@ -69,6 +74,35 @@ func CreateRenderer(pathPrefix string, staticDir http.FileSystem, cookieName str
|
||||
"resourceThemeUrl": func(file, theme string) string {
|
||||
return path.Join(r.pathPrefix, EndpointResources, "themes", theme, file)
|
||||
},
|
||||
"hasCustomPolicy": func(policy *domain.LabelPolicy) bool {
|
||||
if policy != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
"hasWatermark": func(policy *domain.LabelPolicy) bool {
|
||||
if policy != nil && policy.DisableWatermark {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
"variablesCssFileUrl": func(orgID string, policy *domain.LabelPolicy) string {
|
||||
cssFile := domain.CssPath + "/" + domain.CssVariablesFileName
|
||||
return path.Join(r.pathPrefix, fmt.Sprintf("%s?%s=%s&%s=%v&%s=%s", EndpointDynamicResources, "orgId", orgID, "default-policy", policy.Default, "filename", cssFile))
|
||||
},
|
||||
"customLogoResource": func(orgID string, policy *domain.LabelPolicy, darkMode bool) string {
|
||||
fileName := policy.LogoURL
|
||||
if darkMode && policy.LogoDarkURL != "" {
|
||||
fileName = policy.LogoDarkURL
|
||||
}
|
||||
if fileName == "" {
|
||||
return ""
|
||||
}
|
||||
return path.Join(r.pathPrefix, fmt.Sprintf("%s?%s=%s&%s=%v&%s=%s", EndpointDynamicResources, "orgId", orgID, "default-policy", policy.Default, "filename", fileName))
|
||||
},
|
||||
"avatarResource": func(orgID, avatar string) string {
|
||||
return path.Join(r.pathPrefix, fmt.Sprintf("%s?%s=%s&%s=%v&%s=%s", EndpointDynamicResources, "orgId", orgID, "default-policy", false, "filename", avatar))
|
||||
},
|
||||
"loginUrl": func() string {
|
||||
return path.Join(r.pathPrefix, EndpointLogin)
|
||||
},
|
||||
@@ -272,6 +306,7 @@ func (l *Login) getBaseData(r *http.Request, authReq *domain.AuthRequest, title
|
||||
Title: title,
|
||||
Theme: l.getTheme(r),
|
||||
ThemeMode: l.getThemeMode(r),
|
||||
DarkMode: l.isDarkMode(r),
|
||||
OrgID: l.getOrgID(authReq),
|
||||
OrgName: l.getOrgName(authReq),
|
||||
PrimaryDomain: l.getOrgPrimaryDomain(authReq),
|
||||
@@ -282,22 +317,27 @@ func (l *Login) getBaseData(r *http.Request, authReq *domain.AuthRequest, title
|
||||
}
|
||||
if authReq != nil {
|
||||
baseData.LoginPolicy = authReq.LoginPolicy
|
||||
baseData.LabelPolicy = authReq.LabelPolicy
|
||||
baseData.IDPProviders = authReq.AllowedExternalIDPs
|
||||
} else {
|
||||
//TODO: How to handle LabelPolicy if no auth req (eg Register)
|
||||
}
|
||||
return baseData
|
||||
}
|
||||
|
||||
func (l *Login) getProfileData(authReq *domain.AuthRequest) profileData {
|
||||
var userName, loginName, displayName string
|
||||
var userName, loginName, displayName, avatar string
|
||||
if authReq != nil {
|
||||
userName = authReq.UserName
|
||||
loginName = authReq.LoginName
|
||||
displayName = authReq.DisplayName
|
||||
avatar = authReq.AvatarKey
|
||||
}
|
||||
return profileData{
|
||||
UserName: userName,
|
||||
LoginName: loginName,
|
||||
DisplayName: displayName,
|
||||
AvatarKey: avatar,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +356,18 @@ func (l *Login) getTheme(r *http.Request) string {
|
||||
}
|
||||
|
||||
func (l *Login) getThemeMode(r *http.Request) string {
|
||||
return "lgn-dark-theme" //TODO: impl
|
||||
if l.isDarkMode(r) {
|
||||
return "lgn-dark-theme"
|
||||
}
|
||||
return "lgn-light-theme"
|
||||
}
|
||||
|
||||
func (l *Login) isDarkMode(r *http.Request) bool {
|
||||
cookie, err := r.Cookie("mode")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return strings.HasSuffix(cookie.Value, "dark")
|
||||
}
|
||||
|
||||
func (l *Login) getOrgID(authReq *domain.AuthRequest) string {
|
||||
@@ -379,6 +430,7 @@ type baseData struct {
|
||||
Title string
|
||||
Theme string
|
||||
ThemeMode string
|
||||
DarkMode bool
|
||||
OrgID string
|
||||
OrgName string
|
||||
PrimaryDomain string
|
||||
@@ -388,6 +440,7 @@ type baseData struct {
|
||||
Nonce string
|
||||
LoginPolicy *domain.LoginPolicy
|
||||
IDPProviders []*domain.IDPProvider
|
||||
LabelPolicy *domain.LabelPolicy
|
||||
}
|
||||
|
||||
type errorData struct {
|
||||
@@ -408,6 +461,7 @@ type profileData struct {
|
||||
LoginName string
|
||||
UserName string
|
||||
DisplayName string
|
||||
AvatarKey string
|
||||
}
|
||||
|
||||
type passwordData struct {
|
||||
|
||||
@@ -1,9 +1,99 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
)
|
||||
|
||||
type dynamicResourceData struct {
|
||||
OrgID string `schema:"orgId"`
|
||||
DefaultPolicy bool `schema:"default-policy"`
|
||||
FileName string `schema:"filename"`
|
||||
}
|
||||
|
||||
func (l *Login) handleResources(staticDir http.FileSystem) http.Handler {
|
||||
return http.FileServer(staticDir)
|
||||
}
|
||||
|
||||
func (l *Login) handleDynamicResources(w http.ResponseWriter, r *http.Request) {
|
||||
data := new(dynamicResourceData)
|
||||
err := l.getParseData(r, data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
bucketName := domain.IAMID
|
||||
if data.OrgID != "" && !data.DefaultPolicy {
|
||||
bucketName = data.OrgID
|
||||
}
|
||||
|
||||
etag := r.Header.Get("If-None-Match")
|
||||
asset, info, err := l.getStatic(r.Context(), bucketName, data.FileName)
|
||||
if info != nil && info.ETag == etag {
|
||||
w.WriteHeader(304)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("content-length", strconv.FormatInt(info.Size, 10))
|
||||
w.Header().Set("content-type", info.ContentType)
|
||||
w.Header().Set("ETag", info.ETag)
|
||||
w.Write(asset)
|
||||
}
|
||||
|
||||
func (l *Login) getStatic(ctx context.Context, bucketName, fileName string) ([]byte, *domain.AssetInfo, error) {
|
||||
s := new(staticAsset)
|
||||
key := bucketName + "-" + fileName
|
||||
err := l.staticCache.Get(key, s)
|
||||
if err == nil && s.Info != nil && (s.Info.Expiration.After(time.Now().Add(-1 * time.Minute))) { //TODO: config?
|
||||
return s.Data, s.Info, nil
|
||||
}
|
||||
|
||||
info, err := l.staticStorage.GetObjectInfo(ctx, bucketName, fileName)
|
||||
if err != nil {
|
||||
if caos_errs.IsNotFound(err) {
|
||||
return nil, nil, err
|
||||
}
|
||||
return s.Data, s.Info, err
|
||||
}
|
||||
if s.Info != nil && s.Info.ETag == info.ETag {
|
||||
if info.Expiration.After(s.Info.Expiration) {
|
||||
s.Info = info
|
||||
l.cacheStatic(bucketName, fileName, s)
|
||||
}
|
||||
return s.Data, s.Info, nil
|
||||
}
|
||||
|
||||
reader, _, err := l.staticStorage.GetObject(ctx, bucketName, fileName)
|
||||
if err != nil {
|
||||
return s.Data, s.Info, err
|
||||
}
|
||||
s.Data, err = ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
s.Info = info
|
||||
l.cacheStatic(bucketName, fileName, s)
|
||||
return s.Data, s.Info, nil
|
||||
}
|
||||
|
||||
func (l *Login) cacheStatic(bucketName, fileName string, s *staticAsset) {
|
||||
key := bucketName + "-" + fileName
|
||||
err := l.staticCache.Set(key, &s)
|
||||
logging.Log("HANDLER-dfht2").OnError(err).Warnf("caching of asset %s: %s failed", bucketName, fileName)
|
||||
}
|
||||
|
||||
type staticAsset struct {
|
||||
Data []byte
|
||||
Info *domain.AssetInfo
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ const (
|
||||
EndpointLogoutDone = "/logout/done"
|
||||
EndpointExternalNotFoundOption = "/externaluser/option"
|
||||
|
||||
EndpointResources = "/resources"
|
||||
EndpointResources = "/resources"
|
||||
EndpointDynamicResources = "/resources/dynamic"
|
||||
)
|
||||
|
||||
func CreateRouter(login *Login, staticDir http.FileSystem, interceptors ...mux.MiddlewareFunc) *mux.Router {
|
||||
@@ -77,6 +78,7 @@ func CreateRouter(login *Login, staticDir http.FileSystem, interceptors ...mux.M
|
||||
router.HandleFunc(EndpointExternalRegister, login.handleExternalRegister).Methods(http.MethodGet)
|
||||
router.HandleFunc(EndpointExternalRegisterCallback, login.handleExternalRegisterCallback).Methods(http.MethodGet)
|
||||
router.HandleFunc(EndpointLogoutDone, login.handleLogoutDone).Methods(http.MethodGet)
|
||||
router.HandleFunc(EndpointDynamicResources, login.handleDynamicResources).Methods(http.MethodGet)
|
||||
router.PathPrefix(EndpointResources).Handler(login.handleResources(staticDir)).Methods(http.MethodGet)
|
||||
router.HandleFunc(EndpointRegisterOrg, login.handleRegisterOrg).Methods(http.MethodGet)
|
||||
router.HandleFunc(EndpointRegisterOrg, login.handleRegisterOrgCheck).Methods(http.MethodPost)
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
"github.com/caos/zitadel/internal/config/systemdefaults"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
"github.com/caos/zitadel/internal/static"
|
||||
"github.com/caos/zitadel/internal/ui/login/handler"
|
||||
)
|
||||
|
||||
@@ -12,6 +13,6 @@ type Config struct {
|
||||
Handler handler.Config
|
||||
}
|
||||
|
||||
func Start(config Config, command *command.Commands, query *query.Queries, authRepo *eventsourcing.EsRepository, systemdefaults systemdefaults.SystemDefaults, localDevMode bool) (*handler.Login, string) {
|
||||
return handler.CreateLogin(config.Handler, command, query, authRepo, systemdefaults, localDevMode)
|
||||
func Start(config Config, command *command.Commands, query *query.Queries, authRepo *eventsourcing.EsRepository, staticStorage static.Storage, systemdefaults systemdefaults.SystemDefaults, localDevMode bool) (*handler.Login, string) {
|
||||
return handler.CreateLogin(config.Handler, command, query, authRepo, staticStorage, systemdefaults, localDevMode)
|
||||
}
|
||||
|
||||
@@ -220,6 +220,7 @@ Actions:
|
||||
PasswordLogin: Mit Passwort anmelden
|
||||
|
||||
Footer:
|
||||
PoweredBy: Powered By
|
||||
Tos: AGB
|
||||
TosLink: https://zitadel.ch/pdf/agb.pdf
|
||||
Privacy: Datenschutzerklärung
|
||||
|
||||
@@ -220,6 +220,7 @@ Actions:
|
||||
PasswordLogin: Login with password
|
||||
|
||||
Footer:
|
||||
PoweredBy: Powered By
|
||||
Tos: TOS
|
||||
TosLink: https://zitadel.ch/pdf/tos.pdf
|
||||
Privacy: Privacy policy
|
||||
|
||||
@@ -3,6 +3,4 @@ package resources
|
||||
// TODO whitelabeling go:generate sass themes/scss/zitadel-alternative.scss themes/zitadel/css/zitadel.css
|
||||
// scss
|
||||
|
||||
//go:generate sass themes/scss/main.scss themes/zitadel/css/main.css
|
||||
//go:generate sass themes/scss/bundle.scss themes/zitadel/css/bundle.css
|
||||
//go:generate sass themes/scss/zitadel.scss themes/zitadel/css/zitadel.css
|
||||
|
||||
@@ -1,50 +1,36 @@
|
||||
const avatars = document.getElementsByClassName('lgn-avatar');
|
||||
for (let i = 0; i < avatars.length; i++) {
|
||||
const displayName = avatars[i].getAttribute('displayname');
|
||||
const displayName = avatars[i].getAttribute('loginname');
|
||||
if (displayName) {
|
||||
const split = displayName.split(' ');
|
||||
if (split) {
|
||||
const initials = split[0].charAt(0) + (split[1] ? split[1].charAt(0) : '');
|
||||
if (initials) {
|
||||
avatars[i].getElementsByClassName('initials')[0].innerHTML = initials;
|
||||
}
|
||||
const username = displayName.split('@')[0];
|
||||
let separator = '_';
|
||||
if (username.includes('-')) {
|
||||
separator = '-';
|
||||
}
|
||||
if (username.includes('.')) {
|
||||
separator = '.';
|
||||
}
|
||||
const split = username.split(separator);
|
||||
const initials = split[0].charAt(0) + (split[1] ? split[1].charAt(0) : '');
|
||||
avatars[i].getElementsByClassName('initials')[0].innerHTML = initials;
|
||||
|
||||
const color = this.getColor(displayName);
|
||||
avatars[i].style.background = color;
|
||||
avatars[i].style.background = this.getColor(displayName);
|
||||
// set default white text instead of contrast text mode
|
||||
avatars[i].style.color = '#ffffff';
|
||||
}
|
||||
}
|
||||
|
||||
function getColor(userName) {
|
||||
const colors = [
|
||||
'linear-gradient(40deg, #B44D51 30%, rgb(241,138,138))',
|
||||
'linear-gradient(40deg, #B75073 30%, rgb(234,96,143))',
|
||||
'linear-gradient(40deg, #84498E 30%, rgb(214,116,230))',
|
||||
'linear-gradient(40deg, #705998 30%, rgb(163,131,220))',
|
||||
'linear-gradient(40deg, #5C6598 30%, rgb(135,148,222))',
|
||||
'linear-gradient(40deg, #7F90D3 30%, rgb(181,196,247))',
|
||||
'linear-gradient(40deg, #3E93B9 30%, rgb(150,215,245))',
|
||||
'linear-gradient(40deg, #3494A0 30%, rgb(71,205,222))',
|
||||
'linear-gradient(40deg, #25716A 30%, rgb(58,185,173))',
|
||||
'linear-gradient(40deg, #427E41 30%, rgb(97,185,96))',
|
||||
'linear-gradient(40deg, #89A568 30%, rgb(176,212,133))',
|
||||
'linear-gradient(40deg, #90924D 30%, rgb(187,189,98))',
|
||||
'linear-gradient(40deg, #E2B032 30%, rgb(245,203,99))',
|
||||
'linear-gradient(40deg, #C97358 30%, rgb(245,148,118))',
|
||||
'linear-gradient(40deg, #6D5B54 30%, rgb(152,121,108))',
|
||||
'linear-gradient(40deg, #6B7980 30%, rgb(134,163,177))',
|
||||
];
|
||||
|
||||
function getColor(username) {
|
||||
const s = 40;
|
||||
const l = 50;
|
||||
const l2 = 62.5;
|
||||
let hash = 0;
|
||||
if (userName.length === 0) {
|
||||
return colors[hash];
|
||||
for (let i = 0; i < username.length; i++) {
|
||||
hash = username.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
for (let i = 0; i < userName.length; i++) {
|
||||
hash = userName.charCodeAt(i) + ((hash << 5) - hash);
|
||||
hash = hash & hash;
|
||||
}
|
||||
hash = ((hash % colors.length) + colors.length) % colors.length;
|
||||
return colors[hash];
|
||||
|
||||
const h = hash % 360;
|
||||
const col1 = 'hsl(' + h + ', ' + s + '%, ' + l + '%)';
|
||||
const col2 = 'hsl(' + h + ', ' + s + '%, ' + l2 + '%)';
|
||||
return 'linear-gradient(40deg, ' + col1 + ' 30%, ' + col2 + ')';
|
||||
}
|
||||
@@ -1,6 +1,46 @@
|
||||
const usesDarkTheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const usesDarkTheme = hasDarkModeOverwriteCookie() || (!hasLightModeOverwriteCookie() && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||
if (usesDarkTheme) {
|
||||
document.documentElement.classList.replace('lgn-light-theme', 'lgn-dark-theme');
|
||||
writeModeCookie('dark');
|
||||
} else {
|
||||
document.documentElement.classList.replace('lgn-dark-theme', 'lgn-light-theme');
|
||||
writeModeCookie('light');
|
||||
}
|
||||
|
||||
function hasDarkModeOverwriteCookie() {
|
||||
return getCookie('mode') === 'dark';
|
||||
}
|
||||
|
||||
function hasLightModeOverwriteCookie() {
|
||||
return getCookie('mode') === 'light';
|
||||
}
|
||||
|
||||
function writeModeCookie(mode) {
|
||||
let cookieMode = getCookie('mode')
|
||||
if (cookieMode === '' || cookieMode.startsWith('auto')) {
|
||||
setCookie('mode', 'auto-' + mode, 365);
|
||||
}
|
||||
}
|
||||
|
||||
function getCookie(cname) {
|
||||
let name = cname + '=';
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) === 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function setCookie(name, value, exdays) {
|
||||
let d = new Date();
|
||||
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
|
||||
let expires = "expires=" + d.toUTCString();
|
||||
document.cookie = name + "=" + value + ";" + expires + ";path=/";
|
||||
}
|
||||
@@ -1,24 +1,18 @@
|
||||
@import './a.scss';
|
||||
|
||||
@mixin lgn-a-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
@mixin lgn-a-theme() {
|
||||
|
||||
@include lgn-a-color();
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-a-color($color);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin lgn-a-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
|
||||
@mixin lgn-a-color() {
|
||||
a {
|
||||
color: lgn-color($primary, default);
|
||||
|
||||
color: var(--zitadel-color-primary);
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
color: lgn-color($primary, 400);
|
||||
color: var(--zitadel-color-primary-400);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
-21
@@ -1,20 +1,12 @@
|
||||
@import './account_selection.scss';
|
||||
|
||||
@mixin lgn-account-selection-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
@mixin lgn-account-selection-theme() {
|
||||
|
||||
@include lgn-account-selection-color();
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-account-selection-color($color);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin lgn-account-selection-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$warn: map-get($config, warn);
|
||||
$primary: map-get($config, primary);
|
||||
$foreground: map-get($config, foreground);
|
||||
$background: map-get($config, background);
|
||||
@mixin lgn-account-selection-color() {
|
||||
|
||||
.lgn-account-selection{
|
||||
display: flex;
|
||||
@@ -24,36 +16,34 @@
|
||||
.lgn-account {
|
||||
color: inherit;
|
||||
background: transparent;
|
||||
box-shadow: inset 0 -1px lgn-color($foreground, footer-line);
|
||||
box-shadow: inset 0 -1px var(--zitadel-color-footer-line);
|
||||
|
||||
&:hover {
|
||||
$primary: map-get($config, primary);
|
||||
background-color: lgn-color($background, account-selector-hover);
|
||||
background-color: var(--zitadel-color-account-selector-hover);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: lgn-color($background, account-selector-active);
|
||||
background-color: var(--zitadel-color-account-selector-active);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: lgn-color($background, account-selector-active);
|
||||
background-color: var(--zitadel-color-account-selector-active);
|
||||
}
|
||||
|
||||
.lgn-loginname{
|
||||
font-size: 14px;
|
||||
color: lgn-color($foreground, label);
|
||||
color: var(--zitadel-color-label);
|
||||
}
|
||||
|
||||
.lgn-session-state {
|
||||
color: lgn-color($foreground, label);
|
||||
color: var(--zitadel-color-label);
|
||||
|
||||
&.i0 {
|
||||
color: #85d996;
|
||||
}
|
||||
|
||||
&.i1 {
|
||||
$warn: map-get($config, warn);
|
||||
color: lgn-color($warn, default);
|
||||
color: var(--zitadel-color-warn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,11 @@ $lgn-avatar-size: 32px;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.lgn-avatar .avatar-img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
@@ -1,45 +1,32 @@
|
||||
@import './avatar.scss';
|
||||
@import "../elevation/elevation.scss";
|
||||
|
||||
@mixin lgn-avatar-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-avatar-color($color);
|
||||
}
|
||||
@mixin lgn-avatar-theme() {
|
||||
@include lgn-avatar-color();
|
||||
}
|
||||
|
||||
@mixin lgn-avatar-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$warn: map-get($config, warn);
|
||||
$primary: map-get($config, primary);
|
||||
|
||||
@mixin lgn-avatar-color() {
|
||||
.lgn-avatar:not(.transparent) {
|
||||
@include _lgn-avatar-theme-property($config, "background-color", default);
|
||||
@include lgn-button-elevation(2, $config);
|
||||
@include _lgn-avatar-theme-property("background-color", false);
|
||||
@include lgn-avatar-elevation(2);
|
||||
}
|
||||
|
||||
.lgn-avatar .initials{
|
||||
@include _lgn-avatar-theme-property($config, "color", default-contrast);
|
||||
@include _lgn-avatar-theme-property("color", true);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _lgn-avatar-theme-property($theme, $property, $hue) {
|
||||
$primary: map-get($theme, primary);
|
||||
$accent: map-get($theme, accent);
|
||||
$warn: map-get($theme, warn);
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
@mixin _lgn-avatar-theme-property($property, $contrast) {
|
||||
$color: if($contrast, var(--zitadel-color-primary-contrast), var(--zitadel-color-primary));
|
||||
|
||||
&.lgn-primary {
|
||||
#{$property}: lgn-color($primary, $hue);
|
||||
#{$property}: $color;
|
||||
}
|
||||
&.lgn-accent {
|
||||
#{$property}: lgn-color($accent, $hue);
|
||||
#{$property}: $color;
|
||||
}
|
||||
&.lgn-warn {
|
||||
#{$property}: lgn-color($warn, $hue);
|
||||
#{$property}: $color;
|
||||
}
|
||||
|
||||
&.lgn-primary,
|
||||
@@ -47,20 +34,12 @@
|
||||
&.lgn-warn,
|
||||
&[disabled] {
|
||||
&[disabled] {
|
||||
$palette: if($property == "color", $foreground, $background);
|
||||
#{$property}: lgn-color($palette, disabled-button);
|
||||
$btn-color: if($property == "color", var(--zitadel-color-button-disabled), var(--itadel-color-button-disabled-background));
|
||||
#{$property}: $btn-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin lgn-avatar-elevation($zValue, $config, $opacity: $lgn-elevation-opacity) {
|
||||
$foreground: map-get($config, foreground);
|
||||
$elevation-color: map-get($foreground, elevation);
|
||||
$elevation-color-or-default: if(
|
||||
$elevation-color == null,
|
||||
$lgn-elevation-color,
|
||||
$elevation-color
|
||||
);
|
||||
|
||||
@include lgn-elevation($zValue, $elevation-color-or-default, $opacity);
|
||||
@mixin lgn-avatar-elevation($zValue, $opacity: $lgn-elevation-opacity) {
|
||||
@include lgn-elevation($zValue, rgb(0, 0, 0), $opacity);
|
||||
}
|
||||
@@ -2,81 +2,68 @@
|
||||
@import "./button.scss";
|
||||
@import "../elevation/elevation.scss";
|
||||
|
||||
@mixin lgn-button-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-button-color($color);
|
||||
}
|
||||
@mixin lgn-button-theme() {
|
||||
@include lgn-button-color();
|
||||
}
|
||||
|
||||
@mixin lgn-button-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$accent: map-get($config, accent);
|
||||
$warn: map-get($config, warn);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
|
||||
@mixin lgn-button-color() {
|
||||
.lgn-button,
|
||||
.lgn-stroked-button,
|
||||
.lgn-icon-button {
|
||||
color: inherit;
|
||||
background: transparent;
|
||||
|
||||
@include _lgn-button-theme-property($config, "color", text);
|
||||
@include _lgn-button-theme-color(false);
|
||||
}
|
||||
|
||||
.lgn-button:focus,
|
||||
.lgn-stroked-button:focus,
|
||||
.lgn-raised-button:focus {
|
||||
@include lgn-button-elevation(8, $config);
|
||||
background: map-get($background, base);
|
||||
@include lgn-button-elevation(8);
|
||||
background: var(--zitadel-color-background);
|
||||
}
|
||||
|
||||
.lgn-stroked-button:not([disabled]) {
|
||||
border-color: lgn-color($foreground, divider);
|
||||
border-color: var(--zitadel-color-divider);
|
||||
}
|
||||
|
||||
.lgn-button {
|
||||
@include _lgn-button-theme-property($config, "color", text);
|
||||
@include _lgn-button-theme-color(false);
|
||||
&:hover {
|
||||
$primary: map-get($config, primary);
|
||||
background-color: rgba(lgn-color($primary, 500), 0.1);
|
||||
background-color: rgba(var(--zitadel-color-primary-rgb), 0.1);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background-color: rgba(lgn-color($primary, 500), 0.2);
|
||||
background-color: rgba(var(--zitadel-color-primary-rgb), 0.2);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: rgba(lgn-color($primary, 500), 0.25);
|
||||
background-color: rgba(var(--zitadel-color-primary-rgb), 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
.lgn-raised-button {
|
||||
color: lgn-color($foreground, text);
|
||||
background-color: lgn-color($background, raised-button);
|
||||
color: var(--zitadel-color-text);
|
||||
background-color: var(--zitadel-color-raised-button-background);
|
||||
|
||||
@include _lgn-button-theme-property($config, "color", default-contrast);
|
||||
@include _lgn-button-theme-property($config, "background-color", default);
|
||||
@include _lgn-button-theme-color(true);
|
||||
@include _lgn-button-theme-background-color();
|
||||
|
||||
&:active {
|
||||
background-color: rgba(lgn-color($primary, 500), 0.8);
|
||||
background-color: rgba(var(--zitadel-color-primary-rgb), 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.lgn-button,
|
||||
.lgn-stroked-button {
|
||||
@include lgn-button-elevation(0, $config);
|
||||
@include lgn-button-elevation(0);
|
||||
}
|
||||
|
||||
.lgn-raised-button {
|
||||
@include lgn-button-elevation(2, $config);
|
||||
@include lgn-button-elevation(2);
|
||||
|
||||
&:not([disabled]):active {
|
||||
@include lgn-button-elevation(8, $config);
|
||||
@include lgn-button-elevation(8);
|
||||
}
|
||||
|
||||
// &:focus {
|
||||
@@ -84,26 +71,20 @@
|
||||
// }
|
||||
|
||||
&[disabled] {
|
||||
@include lgn-button-elevation(0, $config);
|
||||
@include lgn-button-elevation(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _lgn-button-theme-property($theme, $property, $hue) {
|
||||
$primary: map-get($theme, primary);
|
||||
$accent: map-get($theme, accent);
|
||||
$warn: map-get($theme, warn);
|
||||
$background: map-get($theme, background);
|
||||
$foreground: map-get($theme, foreground);
|
||||
|
||||
@mixin _lgn-button-theme-color() {
|
||||
&.lgn-primary {
|
||||
#{$property}: lgn-color($primary, $hue);
|
||||
color: var(--zitadel-color-primary);
|
||||
}
|
||||
&.lgn-accent {
|
||||
#{$property}: lgn-color($accent, $hue);
|
||||
color: var(--zitadel-color-secondary);
|
||||
}
|
||||
&.lgn-warn {
|
||||
#{$property}: lgn-color($warn, $hue);
|
||||
color: var(--zitadel-color-warn);
|
||||
}
|
||||
|
||||
&.lgn-primary,
|
||||
@@ -111,50 +92,92 @@
|
||||
&.lgn-warn,
|
||||
&[disabled] {
|
||||
&[disabled] {
|
||||
$palette: if($property == "color", $foreground, $background);
|
||||
#{$property}: lgn-color($palette, disabled-button);
|
||||
color: var(--zitadel-color-button-disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _lgn-button-focus-overlay-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$accent: map-get($config, accent);
|
||||
$warn: map-get($config, warn);
|
||||
@mixin _lgn-button-theme-background-color() {
|
||||
&.lgn-primary {
|
||||
background-color: var(--zitadel-color-primary);
|
||||
}
|
||||
&.lgn-accent {
|
||||
background-color: var(--zitadel-color-secondary);
|
||||
}
|
||||
&.lgn-warn {
|
||||
background-color: var(--zitadel-color-warn);
|
||||
}
|
||||
|
||||
&.lgn-primary,
|
||||
&.lgn-accent,
|
||||
&.lgn-warn,
|
||||
&[disabled] {
|
||||
&[disabled] {
|
||||
background-color: var(--zitadel-color-button-disabled-background);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _lgn-button-theme-color($contrast) {
|
||||
$color: if($contrast, var(--zitadel-color-primary-contrast), var(--zitadel-color-primary));
|
||||
|
||||
&.lgn-primary {
|
||||
color: $color;
|
||||
}
|
||||
&.lgn-accent {
|
||||
color: $color;
|
||||
}
|
||||
&.lgn-warn {
|
||||
color: $color;
|
||||
}
|
||||
|
||||
&.lgn-primary,
|
||||
&.lgn-accent,
|
||||
&.lgn-warn,
|
||||
&[disabled] {
|
||||
&[disabled] {
|
||||
color: var(--zitadel-color-button-disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _lgn-button-theme-background-color() {
|
||||
|
||||
&.lgn-primary {
|
||||
background-color: var(--zitadel-color-primary);
|
||||
}
|
||||
&.lgn-accent {
|
||||
background-color: var(--zitadel-color-primary);
|
||||
}
|
||||
&.lgn-warn {
|
||||
background-color: var(--zitadel-color-primary);
|
||||
}
|
||||
|
||||
&.lgn-primary,
|
||||
&.lgn-accent,
|
||||
&.lgn-warn,
|
||||
&[disabled] {
|
||||
&[disabled] {
|
||||
background-color: var(--zitadel-color-button-disabled-background);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _lgn-button-focus-overlay-color() {
|
||||
|
||||
&.lgn-primary:focus {
|
||||
background-color: lgn-color($primary);
|
||||
background-color: var(--zitadel-color-primary);
|
||||
}
|
||||
|
||||
&.lgn-accent:focus {
|
||||
background-color: lgn-color($accent);
|
||||
background-color: var(--zitadel-color-secondary);
|
||||
}
|
||||
|
||||
&.lgn-warn:focus {
|
||||
background-color: lgn-color($warn);
|
||||
background-color: var(--zitadel-color-warn);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin lgn-button-elevation($zValue, $config, $opacity: $lgn-elevation-opacity) {
|
||||
$foreground: map-get($config, foreground);
|
||||
$elevation-color: map-get($foreground, elevation);
|
||||
$elevation-color-or-default: if(
|
||||
$elevation-color == null,
|
||||
$lgn-elevation-color,
|
||||
$elevation-color
|
||||
);
|
||||
|
||||
@include lgn-elevation($zValue, $elevation-color-or-default, $opacity);
|
||||
@mixin lgn-button-elevation($zValue, $opacity: $lgn-elevation-opacity) {
|
||||
@include lgn-elevation($zValue, rgb(0, 0, 0), $opacity);
|
||||
}
|
||||
|
||||
@mixin lgn-button-typography($config-or-theme) {
|
||||
$config: lgn-get-typography-config($config-or-theme);
|
||||
.lgn-button, .lgn-raised-button, .lgn-icon-button, .lgn-stroked-button {
|
||||
font: {
|
||||
family: lgn-font-family($config, button);
|
||||
size: lgn-font-size($config, button);
|
||||
weight: lgn-font-weight($config, button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './checkbox.scss';
|
||||
|
||||
@mixin lgn-checkbox-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-checkbox-color($color);
|
||||
}
|
||||
@mixin lgn-checkbox-theme() {
|
||||
@include lgn-checkbox-color();
|
||||
}
|
||||
|
||||
@mixin lgn-checkbox-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$warn: map-get($config, warn);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
@mixin lgn-checkbox-color() {
|
||||
|
||||
input[type='checkbox'] {
|
||||
position: absolute;
|
||||
@@ -31,7 +21,7 @@
|
||||
.lgn-checkbox label {
|
||||
&:before {
|
||||
background-color: transparent;
|
||||
border: 2px solid lgn-color($foreground, input-border);
|
||||
border: 2px solid var(--zitadel-color-input-border);
|
||||
}
|
||||
|
||||
&:after {
|
||||
@@ -44,8 +34,8 @@
|
||||
// Checked
|
||||
input[type='checkbox']:checked + label {
|
||||
&:before {
|
||||
background-color: lgn-color($primary, default);
|
||||
border-color: lgn-color($primary, default);
|
||||
background-color: var(--zitadel-color-primary);
|
||||
border-color: var(--zitadel-color-primary);
|
||||
}
|
||||
|
||||
&:after {
|
||||
|
||||
+5
-14
@@ -1,29 +1,20 @@
|
||||
@import './container.scss';
|
||||
|
||||
@mixin lgn-container-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-container-color($color);
|
||||
}
|
||||
@mixin lgn-container-theme() {
|
||||
@include lgn-container-color();
|
||||
}
|
||||
|
||||
@mixin lgn-container-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$warn: map-get($config, warn);
|
||||
$primary: map-get($config, primary);
|
||||
@mixin lgn-container-color() {
|
||||
|
||||
.lgn-error {
|
||||
.lgn-error-message {
|
||||
color: lgn-color($warn, default);
|
||||
color: var(--zitadel-color-warn);
|
||||
}
|
||||
}
|
||||
|
||||
.lgn-login-profile {
|
||||
.lgn-names {
|
||||
$foreground: map-get($config, foreground);
|
||||
border-color: lgn-color($foreground, divider);
|
||||
border-color: var(--zitadel-color-divider);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,12 @@
|
||||
@include zitadel-lgn-typography($typography-config);
|
||||
}
|
||||
|
||||
@mixin lgn-core-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
@mixin lgn-core-color() {
|
||||
|
||||
// Wrapper element that provides the theme background
|
||||
.lgn-app-background#{if(&, ', &.lgn-app-background', '')} {
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
|
||||
background-color: lgn-color($background, background);
|
||||
color: lgn-color($foreground, text);
|
||||
background-color: var(--zitadel-color-background);
|
||||
color: var(--zitadel-color-text);
|
||||
}
|
||||
|
||||
// Marker that is used to determine whether the user has added a theme to their page.
|
||||
@@ -24,10 +20,6 @@
|
||||
}
|
||||
|
||||
// Mixin that renders all of the core styles that depend on the theme.
|
||||
@mixin lgn-core-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
@if $color != null {
|
||||
@include lgn-core-color($color);
|
||||
}
|
||||
@mixin lgn-core-theme() {
|
||||
@include lgn-core-color();
|
||||
}
|
||||
@@ -1,19 +1,12 @@
|
||||
@import './error.scss';
|
||||
|
||||
@mixin lgn-error-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-error-color($color);
|
||||
}
|
||||
@mixin lgn-error-theme() {
|
||||
@include lgn-error-color();
|
||||
}
|
||||
|
||||
@mixin lgn-error-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$warn: map-get($config, warn);
|
||||
@mixin lgn-error-color() {
|
||||
|
||||
.lgn-error {
|
||||
color: lgn-color($warn, default);
|
||||
color: var(--zitadel-color-warn);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ footer {
|
||||
a {
|
||||
font-size: 12px;
|
||||
margin-left: 1rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 600px) {
|
||||
@@ -26,4 +27,22 @@ footer {
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.watermark {
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.powered {
|
||||
font-size: 12px;
|
||||
margin: auto 2px;
|
||||
}
|
||||
|
||||
.lgn-logo-watermark {
|
||||
height: 34px;
|
||||
width: 125px;
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +1,26 @@
|
||||
@import './footer.scss';
|
||||
|
||||
@mixin lgn-footer-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
@mixin lgn-footer-theme() {
|
||||
// @include lgn-private-check-duplicate-theme-styles($theme, 'mat-button') {
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-footer-color($color);
|
||||
}
|
||||
@include lgn-footer-color();
|
||||
// }
|
||||
}
|
||||
|
||||
@mixin lgn-footer-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
@mixin lgn-footer-color() {
|
||||
|
||||
footer {
|
||||
background-color: lgn-color($background, footer);
|
||||
border-top: 1px solid lgn-color($foreground, footer-line);
|
||||
background-color: var(--zitadel-color-background);
|
||||
border-top: 1px solid var(--zitadel-color-footer-line);
|
||||
|
||||
a {
|
||||
color: lgn-color($background, footer-links);
|
||||
color: var(--zitadel-color-primary);
|
||||
}
|
||||
|
||||
.lgn-logo-watermark {
|
||||
background: var(--zitadel-logo-powered-by);
|
||||
background-position: auto;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ $lgn-header-margin: 1rem auto .5rem auto;
|
||||
width: 100%;
|
||||
|
||||
.lgn-logo {
|
||||
height: 43px;
|
||||
width: 160px;
|
||||
display: block;
|
||||
max-height: 100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,12 @@
|
||||
@import './header.scss';
|
||||
|
||||
@mixin lgn-header-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-header-color($color);
|
||||
}
|
||||
@mixin lgn-header-theme() {
|
||||
@include lgn-header-color();
|
||||
}
|
||||
|
||||
@mixin lgn-header-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
|
||||
@mixin lgn-header-color() {
|
||||
.lgn-logo {
|
||||
background: _lgn-get-logo-src($config);
|
||||
background-position: auto;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@function _lgn-get-logo-src($config) {
|
||||
$is-dark-theme: map-get($config, is-dark);
|
||||
@return if($is-dark-theme, url('../logo-light.svg') no-repeat, url('../logo-dark.svg') no-repeat);
|
||||
// @return if($is-dark-theme, url('../'+attr(sourcelight))/*url('../logo-light.svg')*/ no-repeat, url('../'+attr(sourcedark))/*url('../logo-dark.svg')*/ no-repeat);
|
||||
}
|
||||
|
||||
+17
-33
@@ -1,43 +1,27 @@
|
||||
@import './identity_provider.scss';
|
||||
|
||||
@mixin lgn-idp-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-idp-color($color);
|
||||
}
|
||||
@mixin lgn-idp-theme() {
|
||||
@include lgn-idp-color();
|
||||
}
|
||||
|
||||
@mixin lgn-idp-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
|
||||
.lgn-idp {
|
||||
border-color: lgn-color($foreground, divider);
|
||||
@mixin lgn-idp-color() {
|
||||
|
||||
@include lgn-idp-elevation(1, $config);
|
||||
.lgn-idp {
|
||||
border-color: var(--zitadel-color-divider);
|
||||
|
||||
&:not([disabled]):active {
|
||||
@include lgn-idp-elevation(8, $config);
|
||||
}
|
||||
@include lgn-idp-elevation(1);
|
||||
|
||||
&.google {
|
||||
color: lgn-color($foreground, google-text);
|
||||
background-color: lgn-color($background, google);
|
||||
}
|
||||
&:not([disabled]):active {
|
||||
@include lgn-idp-elevation(8);
|
||||
}
|
||||
|
||||
&.google {
|
||||
color: var(--zitadel-color-google-text);
|
||||
background-color: var(--zitadel-color-google-background);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin lgn-idp-elevation($zValue, $config, $opacity: $lgn-elevation-opacity) {
|
||||
$foreground: map-get($config, foreground);
|
||||
$elevation-color: map-get($foreground, elevation);
|
||||
$elevation-color-or-default: if(
|
||||
$elevation-color == null,
|
||||
$lgn-elevation-color,
|
||||
$elevation-color
|
||||
);
|
||||
|
||||
@include lgn-elevation($zValue, $elevation-color-or-default, $opacity);
|
||||
}
|
||||
@mixin lgn-idp-elevation($zValue, $opacity: $lgn-elevation-opacity) {
|
||||
@include lgn-elevation($zValue, rgb(0, 0, 0), $opacity);
|
||||
}
|
||||
@@ -1,58 +1,43 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './input.scss';
|
||||
|
||||
@mixin lgn-input-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-input-color($color);
|
||||
}
|
||||
@mixin lgn-input-theme() {
|
||||
@include lgn-input-color();
|
||||
}
|
||||
|
||||
@mixin lgn-input-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$warn: map-get($config, warn);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
@mixin lgn-input-color() {
|
||||
|
||||
.lgn-input:not([disabled]),
|
||||
select:not([disabled]), .lgn-select:not([disabled]) {
|
||||
border-color: lgn-color($foreground, input-border);
|
||||
border-color: var(--zitadel-color-input-border);
|
||||
}
|
||||
|
||||
.lgn-input,
|
||||
select, .lgn-select {
|
||||
color: lgn-color($foreground, text);
|
||||
background-color: lgn-color($background, input);
|
||||
color: var(--zitadel-color-text);
|
||||
background-color: var(--zitadel-color-input-background);
|
||||
|
||||
&:hover {
|
||||
border-color: lgn-color($foreground, input-border-hover);
|
||||
border-color: var(--zitadel-color-input-border-hover);
|
||||
}
|
||||
|
||||
&:active {
|
||||
@include _lgn-input-theme-property($config, 'border-color', default);
|
||||
border-color: var(--zitadel-color-input-border);
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@include _lgn-input-theme-property($config, 'border-color', default);
|
||||
border-color: var(--zitadel-color-input-border);
|
||||
}
|
||||
|
||||
// overwrite if state is warn
|
||||
&[color='warn'] {
|
||||
border-color: lgn-color($warn, default);
|
||||
border-color: var(--zitadel-color-warn);
|
||||
}
|
||||
}
|
||||
|
||||
.lgn-input::placeholder,
|
||||
select::placeholder,
|
||||
.lgn-select::placeholder {
|
||||
color: lgn-color($foreground, input-placeholder);
|
||||
color: var(--zitadel-color-input-placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin _lgn-input-theme-property($theme, $property, $hue) {
|
||||
$primary: map-get($theme, primary);
|
||||
#{$property}: lgn-color($primary, $hue);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,15 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './label.scss';
|
||||
|
||||
@mixin lgn-label-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
@mixin lgn-label-theme() {
|
||||
// @include lgn-private-check-duplicate-theme-styles($theme, 'lgn-label') {
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-label-color($color);
|
||||
}
|
||||
@include lgn-label-color();
|
||||
// }
|
||||
}
|
||||
|
||||
@mixin lgn-label-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$warn: map-get($config, warn);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
@mixin lgn-label-color() {
|
||||
|
||||
.lgn-label {
|
||||
color: lgn-color($foreground, label);
|
||||
color: var(--zitadel-color-label);
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,19 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './list.scss';
|
||||
|
||||
@mixin lgn-list-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-list-color($color);
|
||||
}
|
||||
@mixin lgn-list-theme() {
|
||||
@include lgn-list-color();
|
||||
}
|
||||
|
||||
@mixin lgn-list-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$warn: map-get($config, warn);
|
||||
|
||||
$is-dark-theme: map-get($config, is-dark);
|
||||
@mixin lgn-list-color() {
|
||||
.lgn-list, ul {
|
||||
li::before {
|
||||
color: lgn-color($primary, default);
|
||||
color: var(--zitadel-color-primary);
|
||||
}
|
||||
|
||||
li i {
|
||||
&.lgn-warn {
|
||||
color: lgn-color($warn, default);
|
||||
color: var(--zitadel-color-warn);
|
||||
}
|
||||
|
||||
&.lgn-valid {
|
||||
|
||||
+4
-15
@@ -1,23 +1,12 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './progress_bar.scss';
|
||||
|
||||
@mixin lgn-progress-bar-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-progress-bar-color($color);
|
||||
}
|
||||
@mixin lgn-progress-bar-theme() {
|
||||
@include lgn-progress-bar-color();
|
||||
}
|
||||
|
||||
@mixin lgn-progress-bar-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$warn: map-get($config, warn);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
|
||||
@mixin lgn-progress-bar-color() {
|
||||
.lgn-progress-bar {
|
||||
border-color: lgn-color($foreground, input-border);
|
||||
border-color: var(--zitadel-color-input-border);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,22 @@
|
||||
@import './qrcode.scss';
|
||||
|
||||
@mixin lgn-qrcode-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-qrcode-color($color);
|
||||
}
|
||||
@mixin lgn-qrcode-theme() {
|
||||
@include lgn-qrcode-color();
|
||||
}
|
||||
|
||||
@mixin lgn-qrcode-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
@mixin lgn-qrcode-color() {
|
||||
|
||||
.lgn-qrcode {
|
||||
svg {
|
||||
background: lgn-color($background, qrcode);
|
||||
background: var(--zitadel-color-qr-background);
|
||||
}
|
||||
|
||||
svg rect.color {
|
||||
fill: lgn-color($foreground, qrcode);
|
||||
fill: var(--zitadel-color-qr);
|
||||
}
|
||||
|
||||
svg rect.bg-color {
|
||||
fill: lgn-color($background, qrcode);
|
||||
fill: var(--zitadel-color-qr-background);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,18 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './radio.scss';
|
||||
|
||||
@mixin lgn-radio-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-radio-color($color);
|
||||
}
|
||||
@mixin lgn-radio-theme() {
|
||||
@include lgn-radio-color();
|
||||
}
|
||||
|
||||
@mixin lgn-radio-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
$warn: map-get($config, warn);
|
||||
$background: map-get($config, background);
|
||||
$foreground: map-get($config, foreground);
|
||||
|
||||
@mixin lgn-radio-color() {
|
||||
label {
|
||||
&::before {
|
||||
border-color: lgn-color($foreground, radio-border);
|
||||
border-color: var(--zitadel-color-input-border);
|
||||
}
|
||||
|
||||
&::after {
|
||||
background: lgn-color($primary, default);
|
||||
background: var(--zitadel-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +20,7 @@
|
||||
opacity: 0;
|
||||
|
||||
&:checked + label::before {
|
||||
border-color: lgn-color($primary, default);
|
||||
border-color: var(--zitadel-color-primary);
|
||||
}
|
||||
|
||||
&:focus + label {
|
||||
@@ -41,16 +30,16 @@
|
||||
|
||||
&:disabled {
|
||||
+ label::before {
|
||||
border-color: lgn-color($background, disabled-button);
|
||||
border-color: var(--zitadel-color-button-disabled-background);
|
||||
}
|
||||
|
||||
&:checked {
|
||||
+ label::before {
|
||||
color: lgn-color($background, disabled-selected-button);;
|
||||
color: var(--zitadel-color-button-selected-background);
|
||||
}
|
||||
|
||||
+ label::after {
|
||||
background: lgn-color($background, disabled-selected-button);;
|
||||
background: var(--zitadel-color-button-disabled-selected-background);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,12 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './select.scss';
|
||||
|
||||
@mixin lgn-select-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-select-color($color);
|
||||
}
|
||||
@mixin lgn-select-theme() {
|
||||
@include lgn-select-color();
|
||||
}
|
||||
|
||||
@mixin lgn-select-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$primary: map-get($config, primary);
|
||||
|
||||
$is-dark-theme: map-get($config, is-dark);
|
||||
@mixin lgn-select-color() {
|
||||
.lgn-select, select {
|
||||
background-image: svg-icon($is-dark-theme);
|
||||
background-image: var(--zitadel-icon-select);
|
||||
}
|
||||
}
|
||||
|
||||
@function svg-icon($darktheme) {
|
||||
// @return url('../select_arrow_dark.svg');
|
||||
@return if($darktheme, url('../select_arrow_dark.svg'),url('../select_arrow_light.svg'));
|
||||
// @return url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 448" enable-background="new 0 0 256 448"><path class="arrow" d="M255.9 168c0-4.2-1.6-7.9-4.8-11.2-3.2-3.2-6.9-4.8-11.2-4.8H16c-4.2 0-7.9 1.6-11.2 4.8S0 163.8 0 168c0 4.4 1.6 8.2 4.8 11.4l112 112c3.1 3.1 6.8 4.6 11.2 4.6 4.4 0 8.2-1.5 11.4-4.6l112-112c3-3.2 4.5-7 4.5-11.4z"/></svg>');
|
||||
}
|
||||
+7
-12
@@ -1,21 +1,16 @@
|
||||
@import '../theming/theming.scss';
|
||||
@import './success_label.scss';
|
||||
|
||||
@mixin lgn-success-label-theme($theme-or-color-config) {
|
||||
$theme: lgn-private-legacy-get-theme($theme-or-color-config);
|
||||
$color: lgn-get-color-config($theme);
|
||||
|
||||
@if $color != null {
|
||||
@include lgn-success-label-color($color);
|
||||
}
|
||||
@mixin lgn-success-label-theme() {
|
||||
@include lgn-success-label-color();
|
||||
}
|
||||
|
||||
@mixin lgn-success-label-color($config-or-theme) {
|
||||
$config: lgn-get-color-config($config-or-theme);
|
||||
$is-dark-theme: map-get($config, is-dark);
|
||||
@mixin lgn-success-label-color() {
|
||||
|
||||
.lgn-success-label {
|
||||
color: if($is-dark-theme, #cbf4c9, #0e6245);
|
||||
background-color: if($is-dark-theme, #4f566b, #cbf4c9);
|
||||
color: var(--zitadel-color-success);
|
||||
background-color: var(--zitadel-color-success-background);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -19,23 +19,23 @@
|
||||
@import '../success_label/success_label_theme.scss';
|
||||
@import './theming';
|
||||
|
||||
@mixin zitadel-lgn-theme($theme-or-color-config) {
|
||||
@include lgn-core-theme($theme-or-color-config);
|
||||
@include lgn-header-theme($theme-or-color-config);
|
||||
@include lgn-button-theme($theme-or-color-config);
|
||||
@include lgn-input-theme($theme-or-color-config);
|
||||
@include lgn-radio-theme($theme-or-color-config);
|
||||
@include lgn-checkbox-theme($theme-or-color-config);
|
||||
@include lgn-label-theme($theme-or-color-config);
|
||||
@include lgn-footer-theme($theme-or-color-config);
|
||||
@include lgn-a-theme($theme-or-color-config);
|
||||
@include lgn-error-theme($theme-or-color-config);
|
||||
@include lgn-qrcode-theme($theme-or-color-config);
|
||||
@include lgn-container-theme($theme-or-color-config);
|
||||
@include lgn-account-selection-theme($theme-or-color-config);
|
||||
@include lgn-avatar-theme($theme-or-color-config);
|
||||
@include lgn-select-theme($theme-or-color-config);
|
||||
@include lgn-list-theme($theme-or-color-config);
|
||||
@include lgn-idp-theme($theme-or-color-config);
|
||||
@include lgn-success-label-theme($theme-or-color-config);
|
||||
@mixin zitadel-lgn-theme() {
|
||||
@include lgn-core-theme();
|
||||
@include lgn-header-theme();
|
||||
@include lgn-button-theme();
|
||||
@include lgn-input-theme();
|
||||
@include lgn-radio-theme();
|
||||
@include lgn-checkbox-theme();
|
||||
@include lgn-label-theme();
|
||||
@include lgn-footer-theme();
|
||||
@include lgn-a-theme();
|
||||
@include lgn-error-theme();
|
||||
@include lgn-qrcode-theme();
|
||||
@include lgn-container-theme();
|
||||
@include lgn-account-selection-theme();
|
||||
@include lgn-avatar-theme();
|
||||
@include lgn-select-theme();
|
||||
@include lgn-list-theme();
|
||||
@include lgn-idp-theme();
|
||||
@include lgn-success-label-theme();
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
}
|
||||
|
||||
@function lgn-typography-config(
|
||||
$font-family: 'Lato, -apple-system, BlinkMacSystemFont, sans-serif',
|
||||
$font-family: var(--zitadel-font-family) + ", -apple-system, BlinkMacSystemFont, sans-serif",
|
||||
$display-4: lgn-typography-level(112px, 112px, 300, $letter-spacing: -0.05em),
|
||||
$display-3: lgn-typography-level(56px, 56px, 400, $letter-spacing: -0.02em),
|
||||
$display-2: lgn-typography-level(45px, 48px, 400, $letter-spacing: -0.005em),
|
||||
@@ -145,7 +145,8 @@
|
||||
// Otherwise use the shorthand `font`, because it's the least amount of bytes. Note
|
||||
// that we need to use interpolation for `font-size/line-height` in order to prevent
|
||||
// Sass from dividing the two values.
|
||||
font: $font-weight #{$font-size}/#{$line-height} $font-family;
|
||||
font: $font-weight #{$font-size}/#{$line-height} serif;
|
||||
font-family: $font-family;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
:root {
|
||||
--zitadel-color-primary: var(--zitadel-color-primary-500);
|
||||
--zitadel-color-background: var(--zitadel-color-background-500);
|
||||
--zitadel-color-secondary: var(--zitadel-color-secondary-500);
|
||||
--zitadel-color-warn: var(--zitadel-color-warn-500);
|
||||
|
||||
--zitadel-color-primary-50: #eaedfa;
|
||||
--zitadel-color-primary-100: #ccd2f2;
|
||||
--zitadel-color-primary-200: #aab4ea;
|
||||
--zitadel-color-primary-300: #8796e1;
|
||||
--zitadel-color-primary-400: #6e80da;
|
||||
--zitadel-color-primary-500: #5469d4;
|
||||
--zitadel-color-primary-600: #4d61cf;
|
||||
--zitadel-color-primary-700: #4356c9;
|
||||
--zitadel-color-primary-800: #3a4cc3;
|
||||
--zitadel-color-primary-900: #293bb9;
|
||||
--zitadel-color-primary-rgb: rgb(84, 105, 212);
|
||||
--zitadel-color-primary-contrast: var(--zitadel-color-white);
|
||||
|
||||
--zitadel-color-secondary-50: #eaedfa;
|
||||
--zitadel-color-secondary-100: #ccd2f2;
|
||||
--zitadel-color-secondary-200: #aab4ea;
|
||||
--zitadel-color-secondary-300: #8796e1;
|
||||
--zitadel-color-secondary-400: #6e80da;
|
||||
--zitadel-color-secondary-500: #5469d4;
|
||||
--zitadel-color-secondary-600: #4d61cf;
|
||||
--zitadel-color-secondary-700: #4356c9;
|
||||
--zitadel-color-secondary-800: #3a4cc3;
|
||||
--zitadel-color-secondary-900: #293bb9;
|
||||
--zitadel-color-secondary-contrast: var(--zitadel-color-white);
|
||||
|
||||
--zitadel-color-warn-50: #ffebee;
|
||||
--zitadel-color-warn-100: #ffcdd2;
|
||||
--zitadel-color-warn-200: #ef9a9a;
|
||||
--zitadel-color-warn-300: #e57373;
|
||||
--zitadel-color-warn-400: #ef5350;
|
||||
--zitadel-color-warn-500: #f44336;
|
||||
--zitadel-color-warn-600: #e53935;
|
||||
--zitadel-color-warn-700: #d32f2f;
|
||||
--zitadel-color-warn-800: #c62828;
|
||||
--zitadel-color-warn-900: #b71c1c;
|
||||
|
||||
--zitadel-font-family: 'Lato';
|
||||
|
||||
--zitadel-color-background-500: var(--zitadel-color-grey-50);
|
||||
--zitadel-color-footer-line: #e3e8ee;
|
||||
|
||||
--zitadel-color-input-background: #fafafa50;
|
||||
--zitadel-color-input-border: #00000040;
|
||||
--zitadel-color-input-border-hover: #1a1b1b;
|
||||
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
|
||||
|
||||
--zitadel-color-text: rgba(0, 0, 0, 0.87);
|
||||
--zitadel-color-label: var(--zitadel-color-grey-600);
|
||||
|
||||
|
||||
--zitadel-color-account-selector-hover: rgba(0, 0, 0, 0.02);
|
||||
--zitadel-color-account-selector-active: rgba(0, 0, 0, 0.05);
|
||||
|
||||
--zitadel-color-success: #0e6245;
|
||||
--zitadel-color-success-background: #cbf4c9;
|
||||
|
||||
--zitadel-color-divider: rgba(0, 0, 0, 0.12);
|
||||
|
||||
--zitadel-color-button-disabled: rgba(0, 0, 0, 0.26);
|
||||
--zitadel-color-button-disabled-background: rgba(0, 0, 0, 0.12);
|
||||
--zitadel-color-button-selected-background: var(--zitadel-color-grey-900);
|
||||
--zitadel-color-button-disabled-selected-background: var(--zitadel-color-grey-800);
|
||||
--zitadel-color-raised-button-background: var(--zitadel-color-white);
|
||||
|
||||
|
||||
--zitadel-color-white: #ffffff;
|
||||
--zitadel-color-black: #000000;
|
||||
--zitadel-color-grey-50: #fafafa;
|
||||
--zitadel-color-grey-100: #f5f5f5;
|
||||
--zitadel-color-grey-200: #eeeeee;
|
||||
--zitadel-color-grey-300: #e0e0e0;
|
||||
--zitadel-color-grey-400: #bdbdbd;
|
||||
--zitadel-color-grey-500: #9e9e9e;
|
||||
--zitadel-color-grey-600: #757575;
|
||||
--zitadel-color-grey-700: #616161;
|
||||
--zitadel-color-grey-800: #424242;
|
||||
--zitadel-color-grey-900: #212121;
|
||||
|
||||
--zitadel-icon-select: url('../select_arrow_light.svg');
|
||||
--zitadel-logo-powered-by: url('../logo-dark.svg');
|
||||
|
||||
--zitadel-color-google-text: #8b8d8d;
|
||||
--zitadel-color-google-background: #ffffff;
|
||||
|
||||
--zitadel-color-qr: var(--zitadel-color-white);
|
||||
--zitadel-color-qr-background: var(--zitadel-color-black);
|
||||
}
|
||||
|
||||
.lgn-dark-theme {
|
||||
--zitadel-color-primary-50: #ffffff;
|
||||
--zitadel-color-primary-100: #dde6f3;
|
||||
--zitadel-color-primary-200: #b4c9e4;
|
||||
--zitadel-color-primary-300: #7fa3d1;
|
||||
--zitadel-color-primary-400: #6992c9;
|
||||
--zitadel-color-primary-500: #5282c1;
|
||||
--zitadel-color-primary-600: #4072b4;
|
||||
--zitadel-color-primary-700: #38649d;
|
||||
--zitadel-color-primary-800: #305687;
|
||||
--zitadel-color-primary-900: #284770;
|
||||
|
||||
--zitadel-color-secondary-50: #ffffff;
|
||||
--zitadel-color-secondary-100: #dde6f3;
|
||||
--zitadel-color-secondary-200: #b4c9e4;
|
||||
--zitadel-color-secondary-300: #7fa3d1;
|
||||
--zitadel-color-secondary-400: #6992c9;
|
||||
--zitadel-color-secondary-500: #5282c1;
|
||||
--zitadel-color-secondary-600: #4072b4;
|
||||
--zitadel-color-secondary-700: #38649d;
|
||||
--zitadel-color-secondary-800: #305687;
|
||||
--zitadel-color-secondary-900: #284770;
|
||||
|
||||
--zitadel-color-warn-50: #ffebee;
|
||||
--zitadel-color-warn-100: #ffcdd2;
|
||||
--zitadel-color-warn-200: #ef9a9a;
|
||||
--zitadel-color-warn-300: #e57373;
|
||||
--zitadel-color-warn-400: #ef5350;
|
||||
--zitadel-color-warn-500: #f44336;
|
||||
--zitadel-color-warn-600: #e53935;
|
||||
--zitadel-color-warn-700: #d32f2f;
|
||||
--zitadel-color-warn-800: #c62828;
|
||||
--zitadel-color-warn-900: #b71c1c;
|
||||
|
||||
--zitadel-font-family: 'Lato';
|
||||
|
||||
--zitadel-color-background-500: var(--zitadel-color-grey-900);
|
||||
--zitadel-color-footer-line: #303131;
|
||||
|
||||
--zitadel-color-input-background: rgba(0, 0, 0, 0.2);
|
||||
--zitadel-color-input-border: #403e3e;
|
||||
--zitadel-color-input-border-hover: #aeafb1;
|
||||
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
|
||||
|
||||
--zitadel-color-text: var(--zitadel-color-white);
|
||||
--zitadel-color-label: var(--zitadel-color-grey-600);
|
||||
|
||||
--zitadel-color-account-selector-hover: rgba(255, 255, 255, 0.02);
|
||||
--zitadel-color-account-selector-active: rgba(255, 255, 255, 0.05);
|
||||
|
||||
|
||||
--zitadel-color-success: #cbf4c9;
|
||||
--zitadel-color-success-background: #4f566b;
|
||||
|
||||
--zitadel-color-divider: rgba(255, 255, 255, 0.12);
|
||||
|
||||
--zitadel-color-button-disabled: rgba(0, 0, 0, 0.26);
|
||||
--zitadel-color-button-disabled-background: rgba(255, 255, 255, 0.12);
|
||||
--zitadel-color-button-selected-background: var(--zitadel-color-grey-900);
|
||||
--zitadel-color-button-disabled-selected-background: var(--zitadel-color-grey-800);
|
||||
--zitadel-color-raised-button-background: var(--zitadel-color-grey-800);
|
||||
|
||||
|
||||
/*--zitadel-color-label: var(--zitadel-color-grey-600); same */
|
||||
--zitadel-icon-select: url('../select_arrow_dark.svg');
|
||||
--zitadel-logo-powered-by: url('../logo-light.svg');
|
||||
|
||||
|
||||
--zitadel-color-google-text: #8b8d8d;
|
||||
--zitadel-color-google-background: #ffffff;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// This file is meant to show off a possible starting point for an organisation whitelabeling
|
||||
@import 'main.scss';
|
||||
@import 'bundle.scss';
|
||||
|
||||
@import './styles/theming/all';
|
||||
|
||||
// Include non-theme styles for core. -> mainly background of the login
|
||||
|
||||
@@ -123,13 +123,6 @@ $dark-warn: lgn-palette($lgn-alternative-warn);
|
||||
$light-theme: lgn-light-theme($light-primary, $light-accent, $light-warn);
|
||||
$dark-theme: lgn-dark-theme($dark-primary, $dark-accent, $dark-warn);
|
||||
|
||||
$light-theme: lgn-light-theme((
|
||||
color: (
|
||||
primary: $light-primary,
|
||||
accent: $light-accent,
|
||||
)
|
||||
));
|
||||
|
||||
// Include all theme styles for the components.
|
||||
@include zitadel-lgn-theme($dark-theme);
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@import './styles/theming/all';
|
||||
@import 'styles/vars';
|
||||
@import 'main.scss';
|
||||
@import 'bundle.scss';
|
||||
|
||||
// Include non-theme styles for core. -> mainly background of the login
|
||||
@include lgn-core();
|
||||
@@ -14,20 +16,13 @@ $dark-warn: lgn-palette($lgn-warn);
|
||||
$light-theme: lgn-light-theme($light-primary, $light-accent, $light-warn);
|
||||
$dark-theme: lgn-dark-theme($dark-primary, $dark-accent, $dark-warn);
|
||||
|
||||
$light-theme: lgn-light-theme((
|
||||
color: (
|
||||
primary: $light-primary,
|
||||
accent: $light-accent,
|
||||
)
|
||||
));
|
||||
|
||||
// Include all theme styles for the components.
|
||||
@include zitadel-lgn-theme($dark-theme);
|
||||
@include zitadel-lgn-theme();
|
||||
|
||||
.lgn-dark-theme {
|
||||
@include zitadel-lgn-theme($dark-theme);
|
||||
}
|
||||
//.lgn-dark-theme {
|
||||
// @include zitadel-lgn-theme($dark-theme);
|
||||
//}
|
||||
|
||||
.lgn-light-theme {
|
||||
@include zitadel-lgn-theme($light-theme);
|
||||
}
|
||||
//.lgn-light-theme {
|
||||
// @include zitadel-lgn-theme($light-theme);
|
||||
//}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,22 +0,0 @@
|
||||
body {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
body .lgn-grow {
|
||||
flex: 1;
|
||||
}
|
||||
body.waiting * {
|
||||
cursor: wait !important;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.text-align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=main.css.map */
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"sourceRoot":"","sources":["../../scss/main.scss"],"names":[],"mappings":"AAAA;EACI;EACA;EACA;EACA;;AAEA;EACI;;AAGJ;EACI;;;AAIR;EACI;;;AAGJ;EACI","file":"main.css"}
|
||||
@@ -0,0 +1,13 @@
|
||||
:root {
|
||||
--primary-color: #222324;
|
||||
--secondary-color: #ffffff;
|
||||
--warn-color: #ffffff;
|
||||
--primary-color-dark: #222324;
|
||||
--secondary-color-dark: #ffffff;
|
||||
--warn-color-dark: #ffffff;
|
||||
--logo-url: 'logo-light.svg';
|
||||
--logo-url-dark: 'logo-dark.svg';
|
||||
--icon-url: 'logo-light.svg';
|
||||
--icon-url-dark: 'logo-dark.svg';
|
||||
--font-url: '';
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -1,5 +1,11 @@
|
||||
{{define "footer"}}
|
||||
<footer>
|
||||
{{ if hasWatermark .LabelPolicy }}
|
||||
<span class="watermark" >
|
||||
<span class="powered">{{t "Footer.PoweredBy"}}</span>
|
||||
<span class="lgn-logo-watermark" sourcelight="logo-light.svg" sourcedark="logo-dark.svg" alt="logo"></span>
|
||||
</span>
|
||||
{{end}}
|
||||
<span class="fill-space"></span>
|
||||
<a href="{{t "Footer.TosLink"}}" rel="noopener noreferrer" target="_blank" alt="TOS">{{t "Footer.Tos"}}</a>
|
||||
<a href="{{t "Footer.PrivacyLink"}}" rel="noopener noreferrer" target="_blank" alt="Privacy Policy">{{t "Footer.Privacy"}}</a>
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
{{define "header"}}
|
||||
<header class="lgn-header">
|
||||
<div class="lgn-logo" height="43px" width="160px" sourcelight="logo-light.svg" sourcedark="logo-dark.svg" alt="logo" ></div>
|
||||
{{ if hasCustomPolicy .LabelPolicy }}
|
||||
{{ $logo := customLogoResource .OrgID .LabelPolicy .DarkMode }}
|
||||
{{if $logo}}
|
||||
<img class="lgn-logo" src="{{$logo}}" alt="Logo">
|
||||
{{end}}
|
||||
{{ else }}
|
||||
|
||||
{{if .DarkMode }}
|
||||
<img class="lgn-logo" src="{{ resourceThemeUrl "logo-light.svg" .Theme }}" alt="Logo">
|
||||
{{else}}
|
||||
<img class="lgn-logo" src="{{ resourceThemeUrl "logo-dark.svg" .Theme }}" alt="Logo">
|
||||
{{end}}
|
||||
{{end}}
|
||||
</header>
|
||||
{{end}}
|
||||
@@ -7,11 +7,11 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
<link rel="stylesheet" href="{{ resourceThemeUrl "css/main.css" .Theme }}" type="text/css">
|
||||
<link rel="stylesheet" href="{{ resourceThemeUrl "css/bundle.css" .Theme }}" type="text/css">
|
||||
<link rel="stylesheet" href="{{ resourceThemeUrl "css/zitadel.css" .Theme }}" type="text/css">
|
||||
<link rel="icon" type="image/x-icon" href="{{ resourceThemeUrl "favicon.ico" .Theme }}">
|
||||
|
||||
{{ if hasCustomPolicy .LabelPolicy }}
|
||||
<link rel="stylesheet" href="{{ variablesCssFileUrl .OrgID .LabelPolicy}}" type="text/css">
|
||||
{{ end}}
|
||||
<link rel="stylesheet" href="{{ resourceThemeUrl "../../fonts/lgn-icons/css/lgn-icon-font.css" .Theme }}">
|
||||
|
||||
<title>{{ .Title }}</title>
|
||||
@@ -32,6 +32,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="{{ resourceUrl "scripts/avatar.js" }}"></script>
|
||||
</body>
|
||||
<footer>
|
||||
{{template "footer" .}}
|
||||
|
||||
@@ -40,5 +40,4 @@
|
||||
|
||||
<script src="{{ resourceUrl "scripts/form_submit.js" }}"></script>
|
||||
<script src="{{ resourceUrl "scripts/default_form_validation.js" }}"></script>
|
||||
<script src="{{ resourceUrl "scripts/avatar.js" }}"></script>
|
||||
|
||||
|
||||
@@ -24,13 +24,18 @@
|
||||
<div class="lgn-account-selection">
|
||||
{{ if .Users }}
|
||||
{{ $displayLoginNameSuffix := and .OrgID (not .DisplayLoginNameSuffix)}}
|
||||
{{ $orgID := .OrgID }}
|
||||
{{ range $user := .Users }}
|
||||
{{ $sessionState := (printf "UserSelection.SessionState%v" $user.UserSessionState) }}
|
||||
<button type="submit" name="userID" value="{{$user.UserID}}" class="lgn-account"
|
||||
{{if not $user.SelectionPossible}}disabled title="{{t "Errors.User.NotAllowedOrg"}}"{{end}}>
|
||||
<div class="left">
|
||||
<div class="lgn-avatar" displayname="{{$user.DisplayName}}">
|
||||
<span class="initials">A</span>
|
||||
<div class="lgn-avatar" {{if not $user.AvatarKey}}loginname="{{$user.LoginName}}"{{end}}>
|
||||
{{if $user.AvatarKey}}
|
||||
<img class="avatar-img" src="{{ avatarResource $orgID $user.AvatarKey }}" alt="user-avatar">
|
||||
{{else}}
|
||||
<span class="initials">A</span>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="lgn-names">
|
||||
@@ -58,6 +63,4 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script src="{{ resourceUrl "scripts/avatar.js" }}"></script>
|
||||
|
||||
{{template "main-bottom" .}}
|
||||
@@ -4,14 +4,19 @@
|
||||
<div class="lgn-profile-image"></div>
|
||||
<div class="lgn-names">
|
||||
<div class="inline-block">
|
||||
<div class="lgn-avatar lgn-primary" displayname="{{.DisplayName}}">
|
||||
<span class="initials lgn-primary">A</span>
|
||||
<div class="lgn-avatar lgn-primary" {{if not .AvatarKey}}loginname="{{.LoginName}}"{{end}}>
|
||||
{{if .AvatarKey}}
|
||||
<img class="avatar-img" src="{{ avatarResource .OrgID .AvatarKey }}" alt="user-avatar">
|
||||
{{else}}
|
||||
<span class="initials lgn-primary">A</span>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="lgn-loginname">
|
||||
<p>{{if .DisplayLoginNameSuffix}}{{.LoginName}}{{else}}{{.UserName}}{{end}}</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user