mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-08 19:37:41 +00:00
Merge branch 'main' into next
# Conflicts: # cmd/start/start.go # internal/auth/repository/eventsourcing/eventstore/auth_request.go # internal/auth/repository/eventsourcing/repository.go # internal/command/main_test.go # internal/command/quota.go # internal/command/quota_model.go # internal/command/quota_model_test.go
This commit is contained in:
commit
dee9d8d3a7
36
.github/workflows/build.yml
vendored
36
.github/workflows/build.yml
vendored
@ -11,31 +11,30 @@ permissions:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
core:
|
core:
|
||||||
uses: ./.github/workflows/core.yml
|
uses: ./.github/workflows/core.yml
|
||||||
with:
|
with:
|
||||||
node_version: '18'
|
node_version: "20"
|
||||||
buf_version: 'latest'
|
buf_version: "latest"
|
||||||
go_version: '1.21'
|
go_version: "1.21"
|
||||||
|
|
||||||
console:
|
console:
|
||||||
uses: ./.github/workflows/console.yml
|
uses: ./.github/workflows/console.yml
|
||||||
with:
|
with:
|
||||||
node_version: '18'
|
node_version: "20"
|
||||||
buf_version: 'latest'
|
buf_version: "latest"
|
||||||
|
|
||||||
version:
|
version:
|
||||||
uses: ./.github/workflows/version.yml
|
uses: ./.github/workflows/version.yml
|
||||||
with:
|
with:
|
||||||
semantic_version: '19.0.2'
|
semantic_version: "19.0.2"
|
||||||
dry_run: true
|
dry_run: true
|
||||||
|
|
||||||
compile:
|
compile:
|
||||||
needs: [core, console, version]
|
needs: [core, console, version]
|
||||||
uses: ./.github/workflows/compile.yml
|
uses: ./.github/workflows/compile.yml
|
||||||
with:
|
with:
|
||||||
go_version: '1.21'
|
go_version: "1.21"
|
||||||
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
||||||
console_cache_key: ${{ needs.console.outputs.cache_key }}
|
console_cache_key: ${{ needs.console.outputs.cache_key }}
|
||||||
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
||||||
@ -46,7 +45,7 @@ jobs:
|
|||||||
needs: core
|
needs: core
|
||||||
uses: ./.github/workflows/core-unit-test.yml
|
uses: ./.github/workflows/core-unit-test.yml
|
||||||
with:
|
with:
|
||||||
go_version: '1.21'
|
go_version: "1.21"
|
||||||
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
||||||
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
||||||
|
|
||||||
@ -54,7 +53,7 @@ jobs:
|
|||||||
needs: core
|
needs: core
|
||||||
uses: ./.github/workflows/core-integration-test.yml
|
uses: ./.github/workflows/core-integration-test.yml
|
||||||
with:
|
with:
|
||||||
go_version: '1.21'
|
go_version: "1.21"
|
||||||
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
||||||
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
||||||
|
|
||||||
@ -62,10 +61,10 @@ jobs:
|
|||||||
needs: [core, console]
|
needs: [core, console]
|
||||||
uses: ./.github/workflows/lint.yml
|
uses: ./.github/workflows/lint.yml
|
||||||
with:
|
with:
|
||||||
go_version: '1.21'
|
go_version: "1.21"
|
||||||
node_version: '18'
|
node_version: "18"
|
||||||
buf_version: 'latest'
|
buf_version: "latest"
|
||||||
go_lint_version: 'v1.53.2'
|
go_lint_version: "v1.53.2"
|
||||||
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
core_cache_key: ${{ needs.core.outputs.cache_key }}
|
||||||
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
core_cache_path: ${{ needs.core.outputs.cache_path }}
|
||||||
|
|
||||||
@ -77,7 +76,7 @@ jobs:
|
|||||||
packages: write
|
packages: write
|
||||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
with:
|
with:
|
||||||
build_image_name: 'ghcr.io/zitadel/zitadel-build'
|
build_image_name: "ghcr.io/zitadel/zitadel-build"
|
||||||
|
|
||||||
e2e:
|
e2e:
|
||||||
uses: ./.github/workflows/e2e.yml
|
uses: ./.github/workflows/e2e.yml
|
||||||
@ -90,12 +89,13 @@ jobs:
|
|||||||
contents: write
|
contents: write
|
||||||
issues: write
|
issues: write
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
needs: [version, core-unit-test, core-integration-test, lint, container, e2e]
|
needs:
|
||||||
|
[version, core-unit-test, core-integration-test, lint, container, e2e]
|
||||||
if: ${{ needs.version.outputs.published == 'true' && github.event_name == 'workflow_dispatch' }}
|
if: ${{ needs.version.outputs.published == 'true' && github.event_name == 'workflow_dispatch' }}
|
||||||
secrets:
|
secrets:
|
||||||
GCR_JSON_KEY_BASE64: ${{ secrets.GCR_JSON_KEY_BASE64 }}
|
GCR_JSON_KEY_BASE64: ${{ secrets.GCR_JSON_KEY_BASE64 }}
|
||||||
with:
|
with:
|
||||||
build_image_name: ${{ needs.container.outputs.build_image }}
|
build_image_name: ${{ needs.container.outputs.build_image }}
|
||||||
semantic_version: '19.0.2'
|
semantic_version: "19.0.2"
|
||||||
image_name: 'ghcr.io/zitadel/zitadel'
|
image_name: "ghcr.io/zitadel/zitadel"
|
||||||
google_image_name: "europe-docker.pkg.dev/zitadel-common/zitadel-repo/zitadel"
|
google_image_name: "europe-docker.pkg.dev/zitadel-common/zitadel-repo/zitadel"
|
||||||
|
@ -595,7 +595,7 @@ DefaultInstance:
|
|||||||
MaxAgeDays: 0 # ZITADEL_DEFAULTINSTANCE_PASSWORDAGEPOLICY_MAXAGEDAYS
|
MaxAgeDays: 0 # ZITADEL_DEFAULTINSTANCE_PASSWORDAGEPOLICY_MAXAGEDAYS
|
||||||
DomainPolicy:
|
DomainPolicy:
|
||||||
UserLoginMustBeDomain: false # ZITADEL_DEFAULTINSTANCE_DOMAINPOLICY_USERLOGINMUSTBEDOMAIN
|
UserLoginMustBeDomain: false # ZITADEL_DEFAULTINSTANCE_DOMAINPOLICY_USERLOGINMUSTBEDOMAIN
|
||||||
ValidateOrgDomains: true # ZITADEL_DEFAULTINSTANCE_DOMAINPOLICY_VALIDATEORGDOMAINS
|
ValidateOrgDomains: false # ZITADEL_DEFAULTINSTANCE_DOMAINPOLICY_VALIDATEORGDOMAINS
|
||||||
SMTPSenderAddressMatchesInstanceDomain: false # ZITADEL_DEFAULTINSTANCE_DOMAINPOLICY_SMTPSENDERADDRESSMATCHESINSTANCEDOMAIN
|
SMTPSenderAddressMatchesInstanceDomain: false # ZITADEL_DEFAULTINSTANCE_DOMAINPOLICY_SMTPSENDERADDRESSMATCHESINSTANCEDOMAIN
|
||||||
LoginPolicy:
|
LoginPolicy:
|
||||||
AllowUsernamePassword: true # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_ALLOWUSERNAMEPASSWORD
|
AllowUsernamePassword: true # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_ALLOWUSERNAMEPASSWORD
|
||||||
@ -604,7 +604,7 @@ DefaultInstance:
|
|||||||
ForceMFA: false # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_FORCEMFA
|
ForceMFA: false # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_FORCEMFA
|
||||||
HidePasswordReset: false # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_HIDEPASSWORDRESET
|
HidePasswordReset: false # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_HIDEPASSWORDRESET
|
||||||
IgnoreUnknownUsernames: false # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_IGNOREUNKNOWNUSERNAMES
|
IgnoreUnknownUsernames: false # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_IGNOREUNKNOWNUSERNAMES
|
||||||
AllowDomainDiscovery: false # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_ALLOWDOMAINDISCOVERY
|
AllowDomainDiscovery: true # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_ALLOWDOMAINDISCOVERY
|
||||||
# 1 is allowed, 0 is not allowed
|
# 1 is allowed, 0 is not allowed
|
||||||
PasswordlessType: 1 # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_PASSWORDLESSTYPE
|
PasswordlessType: 1 # ZITADEL_DEFAULTINSTANCE_LOGINPOLICY_PASSWORDLESSTYPE
|
||||||
# DefaultRedirectURL is empty by default because we use the Console UI
|
# DefaultRedirectURL is empty by default because we use the Console UI
|
||||||
@ -761,6 +761,8 @@ DefaultInstance:
|
|||||||
Greeting: Hello {{.DisplayName}},
|
Greeting: Hello {{.DisplayName}},
|
||||||
Text: The password of your user has changed. If this change was not done by you, please be advised to immediately reset your password.
|
Text: The password of your user has changed. If this change was not done by you, please be advised to immediately reset your password.
|
||||||
ButtonText: Login
|
ButtonText: Login
|
||||||
|
Features:
|
||||||
|
- FeatureLoginDefaultOrg: true
|
||||||
|
|
||||||
Quotas:
|
Quotas:
|
||||||
# Items take a slice of quota configurations, whereas, for each unit type and instance, one or zero quotas may exist.
|
# Items take a slice of quota configurations, whereas, for each unit type and instance, one or zero quotas may exist.
|
||||||
@ -819,6 +821,7 @@ InternalAuthZ:
|
|||||||
- "iam.flow.read"
|
- "iam.flow.read"
|
||||||
- "iam.flow.write"
|
- "iam.flow.write"
|
||||||
- "iam.flow.delete"
|
- "iam.flow.delete"
|
||||||
|
- "iam.feature.write"
|
||||||
- "org.read"
|
- "org.read"
|
||||||
- "org.global.read"
|
- "org.global.read"
|
||||||
- "org.create"
|
- "org.create"
|
||||||
|
@ -23,6 +23,7 @@ func MustNewConfig(v *viper.Viper) *Config {
|
|||||||
mapstructure.StringToTimeDurationHookFunc(),
|
mapstructure.StringToTimeDurationHookFunc(),
|
||||||
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
||||||
mapstructure.StringToSliceHookFunc(","),
|
mapstructure.StringToSliceHookFunc(","),
|
||||||
|
hook.StringToFeatureHookFunc(),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
logging.OnError(err).Fatal("unable to read default config")
|
logging.OnError(err).Fatal("unable to read default config")
|
||||||
|
@ -24,6 +24,7 @@ type FirstInstance struct {
|
|||||||
Org command.InstanceOrgSetup
|
Org command.InstanceOrgSetup
|
||||||
MachineKeyPath string
|
MachineKeyPath string
|
||||||
PatPath string
|
PatPath string
|
||||||
|
Features map[domain.Feature]any
|
||||||
|
|
||||||
instanceSetup command.InstanceSetup
|
instanceSetup command.InstanceSetup
|
||||||
userEncryptionKey *crypto.KeyConfig
|
userEncryptionKey *crypto.KeyConfig
|
||||||
|
@ -43,6 +43,7 @@ func MustNewConfig(v *viper.Viper) *Config {
|
|||||||
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
||||||
mapstructure.StringToSliceHookFunc(","),
|
mapstructure.StringToSliceHookFunc(","),
|
||||||
database.DecodeHook,
|
database.DecodeHook,
|
||||||
|
hook.StringToFeatureHookFunc(),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
logging.OnError(err).Fatal("unable to read default config")
|
logging.OnError(err).Fatal("unable to read default config")
|
||||||
@ -99,6 +100,7 @@ func MustNewSteps(v *viper.Viper) *Steps {
|
|||||||
mapstructure.StringToTimeDurationHookFunc(),
|
mapstructure.StringToTimeDurationHookFunc(),
|
||||||
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
mapstructure.StringToTimeHookFunc(time.RFC3339),
|
||||||
mapstructure.StringToSliceHookFunc(","),
|
mapstructure.StringToSliceHookFunc(","),
|
||||||
|
hook.StringToFeatureHookFunc(),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
logging.OnError(err).Fatal("unable to read steps")
|
logging.OnError(err).Fatal("unable to read steps")
|
||||||
|
@ -92,6 +92,7 @@ func MustNewConfig(v *viper.Viper) *Config {
|
|||||||
database.DecodeHook,
|
database.DecodeHook,
|
||||||
actions.HTTPConfigDecodeHook,
|
actions.HTTPConfigDecodeHook,
|
||||||
systemAPIUsersDecodeHook,
|
systemAPIUsersDecodeHook,
|
||||||
|
hook.StringToFeatureHookFunc(),
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
logging.OnError(err).Fatal("unable to read config")
|
logging.OnError(err).Fatal("unable to read config")
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/cmd/build"
|
"github.com/zitadel/zitadel/cmd/build"
|
||||||
"github.com/zitadel/zitadel/cmd/key"
|
"github.com/zitadel/zitadel/cmd/key"
|
||||||
cmd_tls "github.com/zitadel/zitadel/cmd/tls"
|
cmd_tls "github.com/zitadel/zitadel/cmd/tls"
|
||||||
|
"github.com/zitadel/zitadel/feature"
|
||||||
"github.com/zitadel/zitadel/internal/actions"
|
"github.com/zitadel/zitadel/internal/actions"
|
||||||
admin_es "github.com/zitadel/zitadel/internal/admin/repository/eventsourcing"
|
admin_es "github.com/zitadel/zitadel/internal/admin/repository/eventsourcing"
|
||||||
"github.com/zitadel/zitadel/internal/api"
|
"github.com/zitadel/zitadel/internal/api"
|
||||||
@ -40,7 +41,7 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/api/grpc/session/v2"
|
"github.com/zitadel/zitadel/internal/api/grpc/session/v2"
|
||||||
"github.com/zitadel/zitadel/internal/api/grpc/settings/v2"
|
"github.com/zitadel/zitadel/internal/api/grpc/settings/v2"
|
||||||
"github.com/zitadel/zitadel/internal/api/grpc/system"
|
"github.com/zitadel/zitadel/internal/api/grpc/system"
|
||||||
"github.com/zitadel/zitadel/internal/api/grpc/user/v2"
|
user_v2 "github.com/zitadel/zitadel/internal/api/grpc/user/v2"
|
||||||
http_util "github.com/zitadel/zitadel/internal/api/http"
|
http_util "github.com/zitadel/zitadel/internal/api/http"
|
||||||
"github.com/zitadel/zitadel/internal/api/http/middleware"
|
"github.com/zitadel/zitadel/internal/api/http/middleware"
|
||||||
"github.com/zitadel/zitadel/internal/api/idp"
|
"github.com/zitadel/zitadel/internal/api/idp"
|
||||||
@ -356,7 +357,7 @@ func startAPIs(
|
|||||||
if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, keys.User, config.ExternalSecure, config.AuditLogRetention)); err != nil {
|
if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, keys.User, config.ExternalSecure, config.AuditLogRetention)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := apis.RegisterService(ctx, user.CreateServer(commands, queries, keys.User, keys.IDPConfig, idp.CallbackURL(config.ExternalSecure))); err != nil {
|
if err := apis.RegisterService(ctx, user_v2.CreateServer(commands, queries, keys.User, keys.IDPConfig, idp.CallbackURL(config.ExternalSecure), idp.SAMLRootURL(config.ExternalSecure))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := apis.RegisterService(ctx, session.CreateServer(commands, queries, permissionCheck)); err != nil {
|
if err := apis.RegisterService(ctx, session.CreateServer(commands, queries, permissionCheck)); err != nil {
|
||||||
@ -375,7 +376,7 @@ func startAPIs(
|
|||||||
|
|
||||||
apis.RegisterHandlerOnPrefix(idp.HandlerPrefix, idp.NewHandler(commands, queries, keys.IDPConfig, config.ExternalSecure, instanceInterceptor.Handler))
|
apis.RegisterHandlerOnPrefix(idp.HandlerPrefix, idp.NewHandler(commands, queries, keys.IDPConfig, config.ExternalSecure, instanceInterceptor.Handler))
|
||||||
|
|
||||||
userAgentInterceptor, err := middleware.NewUserAgentHandler(config.UserAgentCookie, keys.UserAgentCookieKey, id.SonyFlakeGenerator(), config.ExternalSecure, login.EndpointResources, login.EndpointExternalLoginCallbackFormPost)
|
userAgentInterceptor, err := middleware.NewUserAgentHandler(config.UserAgentCookie, keys.UserAgentCookieKey, id.SonyFlakeGenerator(), config.ExternalSecure, login.EndpointResources, login.EndpointExternalLoginCallbackFormPost, login.EndpointSAMLACS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -412,7 +413,27 @@ func startAPIs(
|
|||||||
}
|
}
|
||||||
apis.RegisterHandlerOnPrefix(console.HandlerPrefix, c)
|
apis.RegisterHandlerOnPrefix(console.HandlerPrefix, c)
|
||||||
|
|
||||||
l, err := login.CreateLogin(config.Login, commands, queries, authRepo, store, console.HandlerPrefix+"/", op.AuthCallbackURL(oidcProvider), provider.AuthCallbackURL(samlProvider), config.ExternalSecure, userAgentInterceptor, op.NewIssuerInterceptor(oidcProvider.IssuerFromRequest).Handler, provider.NewIssuerInterceptor(samlProvider.IssuerFromRequest).Handler, instanceInterceptor.Handler, assetsCache.Handler, limitingAccessInterceptor.WithoutLimiting().Handle, keys.User, keys.IDPConfig, keys.CSRFCookieKey)
|
l, err := login.CreateLogin(
|
||||||
|
config.Login,
|
||||||
|
commands,
|
||||||
|
queries,
|
||||||
|
authRepo,
|
||||||
|
store,
|
||||||
|
console.HandlerPrefix+"/",
|
||||||
|
op.AuthCallbackURL(oidcProvider),
|
||||||
|
provider.AuthCallbackURL(samlProvider),
|
||||||
|
config.ExternalSecure,
|
||||||
|
userAgentInterceptor,
|
||||||
|
op.NewIssuerInterceptor(oidcProvider.IssuerFromRequest).Handler,
|
||||||
|
provider.NewIssuerInterceptor(samlProvider.IssuerFromRequest).Handler,
|
||||||
|
instanceInterceptor.Handler,
|
||||||
|
assetsCache.Handler,
|
||||||
|
limitingAccessInterceptor.WithoutLimiting().Handle,
|
||||||
|
keys.User,
|
||||||
|
keys.IDPConfig,
|
||||||
|
keys.CSRFCookieKey,
|
||||||
|
feature.NewCheck(eventstore),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to start login: %w", err)
|
return fmt.Errorf("unable to start login: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
"@angular/router": "^16.2.0",
|
"@angular/router": "^16.2.0",
|
||||||
"@angular/service-worker": "^16.2.0",
|
"@angular/service-worker": "^16.2.0",
|
||||||
"@ctrl/ngx-codemirror": "^6.1.0",
|
"@ctrl/ngx-codemirror": "^6.1.0",
|
||||||
"@grpc/grpc-js": "^1.8.14",
|
"@grpc/grpc-js": "^1.9.3",
|
||||||
"@ngx-translate/core": "^14.0.0",
|
"@ngx-translate/core": "^14.0.0",
|
||||||
"angular-oauth2-oidc": "^15.0.1",
|
"angular-oauth2-oidc": "^15.0.1",
|
||||||
"angularx-qrcode": "^16.0.0",
|
"angularx-qrcode": "^16.0.0",
|
||||||
@ -41,8 +41,8 @@
|
|||||||
"libphonenumber-js": "^1.10.30",
|
"libphonenumber-js": "^1.10.30",
|
||||||
"material-design-icons-iconfont": "^6.1.1",
|
"material-design-icons-iconfont": "^6.1.1",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"opentype.js": "^1.3.4",
|
|
||||||
"ngx-color": "^9.0.0",
|
"ngx-color": "^9.0.0",
|
||||||
|
"opentype.js": "^1.3.4",
|
||||||
"rxjs": "~7.8.0",
|
"rxjs": "~7.8.0",
|
||||||
"tinycolor2": "^1.6.0",
|
"tinycolor2": "^1.6.0",
|
||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
@ -62,17 +62,17 @@
|
|||||||
"@bufbuild/buf": "^1.23.1",
|
"@bufbuild/buf": "^1.23.1",
|
||||||
"@types/file-saver": "^2.0.2",
|
"@types/file-saver": "^2.0.2",
|
||||||
"@types/google-protobuf": "^3.15.3",
|
"@types/google-protobuf": "^3.15.3",
|
||||||
"@types/jasmine": "~4.3.3",
|
"@types/jasmine": "~4.3.6",
|
||||||
"@types/jasminewd2": "~2.0.10",
|
"@types/jasminewd2": "~2.0.10",
|
||||||
"@types/jsonwebtoken": "^9.0.1",
|
"@types/jsonwebtoken": "^9.0.1",
|
||||||
"@types/node": "^18.15.11",
|
"@types/node": "^20.7.0",
|
||||||
"@types/opentype.js": "^1.3.4",
|
"@types/opentype.js": "^1.3.4",
|
||||||
"@types/qrcode": "^1.5.0",
|
"@types/qrcode": "^1.5.2",
|
||||||
"@types/uuid": "^9.0.2",
|
"@types/uuid": "^9.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||||
"@typescript-eslint/parser": "^5.60.1",
|
"@typescript-eslint/parser": "^5.60.1",
|
||||||
"codelyzer": "^6.0.2",
|
"codelyzer": "^6.0.2",
|
||||||
"eslint": "^8.44.0",
|
"eslint": "^8.50.0",
|
||||||
"jasmine-core": "~4.6.0",
|
"jasmine-core": "~4.6.0",
|
||||||
"jasmine-spec-reporter": "~7.0.0",
|
"jasmine-spec-reporter": "~7.0.0",
|
||||||
"karma": "^6.4.2",
|
"karma": "^6.4.2",
|
||||||
@ -80,7 +80,7 @@
|
|||||||
"karma-coverage-istanbul-reporter": "^3.0.3",
|
"karma-coverage-istanbul-reporter": "^3.0.3",
|
||||||
"karma-jasmine": "^5.1.0",
|
"karma-jasmine": "^5.1.0",
|
||||||
"karma-jasmine-html-reporter": "^2.1.0",
|
"karma-jasmine-html-reporter": "^2.1.0",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^3.0.3",
|
||||||
"prettier-plugin-organize-imports": "^3.2.2",
|
"prettier-plugin-organize-imports": "^3.2.2",
|
||||||
"protractor": "~7.0.0",
|
"protractor": "~7.0.0",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
|
@ -158,14 +158,6 @@ const routes: Routes = [
|
|||||||
requiresAll: true,
|
requiresAll: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: 'domains',
|
|
||||||
loadChildren: () => import('./pages/domains/domains.module'),
|
|
||||||
canActivate: [AuthGuard, RoleGuard],
|
|
||||||
data: {
|
|
||||||
roles: ['org.read'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: 'org-settings',
|
path: 'org-settings',
|
||||||
loadChildren: () => import('./pages/org-settings/org-settings.module'),
|
loadChildren: () => import('./pages/org-settings/org-settings.module'),
|
||||||
|
@ -9,7 +9,10 @@ import { GrpcAuthService } from '../services/grpc-auth.service';
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class UserGuard {
|
export class UserGuard {
|
||||||
constructor(private authService: GrpcAuthService, private router: Router) {}
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
|
private router: Router,
|
||||||
|
) {}
|
||||||
|
|
||||||
public canActivate(
|
public canActivate(
|
||||||
route: ActivatedRouteSnapshot,
|
route: ActivatedRouteSnapshot,
|
||||||
|
@ -18,7 +18,11 @@ export class AccountsCardComponent implements OnInit {
|
|||||||
public sessions: Session.AsObject[] = [];
|
public sessions: Session.AsObject[] = [];
|
||||||
public loadingUsers: boolean = false;
|
public loadingUsers: boolean = false;
|
||||||
public UserState: any = UserState;
|
public UserState: any = UserState;
|
||||||
constructor(public authService: AuthenticationService, private router: Router, private userService: GrpcAuthService) {
|
constructor(
|
||||||
|
public authService: AuthenticationService,
|
||||||
|
private router: Router,
|
||||||
|
private userService: GrpcAuthService,
|
||||||
|
) {
|
||||||
this.userService
|
this.userService
|
||||||
.listMyUserSessions()
|
.listMyUserSessions()
|
||||||
.then((sessions) => {
|
.then((sessions) => {
|
||||||
|
@ -22,7 +22,10 @@ export class AddKeyDialogComponent {
|
|||||||
public type!: KeyType;
|
public type!: KeyType;
|
||||||
public dateControl: UntypedFormControl = new UntypedFormControl('', []);
|
public dateControl: UntypedFormControl = new UntypedFormControl('', []);
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<AddKeyDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AddKeyDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.types = [KeyType.KEY_TYPE_JSON];
|
this.types = [KeyType.KEY_TYPE_JSON];
|
||||||
this.type = KeyType.KEY_TYPE_JSON;
|
this.type = KeyType.KEY_TYPE_JSON;
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
|
@ -14,7 +14,10 @@ export class AddMemberRolesDialogComponent {
|
|||||||
public allRoles: string[] = [];
|
public allRoles: string[] = [];
|
||||||
public selectedRoles: string[] = [];
|
public selectedRoles: string[] = [];
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<AddMemberRolesDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AddMemberRolesDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.allRoles = Object.assign([], data.allRoles);
|
this.allRoles = Object.assign([], data.allRoles);
|
||||||
this.selectedRoles = Object.assign([], data.selectedRoles);
|
this.selectedRoles = Object.assign([], data.selectedRoles);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,10 @@ export class AddTokenDialogComponent {
|
|||||||
public startDate: Date = new Date();
|
public startDate: Date = new Date();
|
||||||
public dateControl: UntypedFormControl = new UntypedFormControl('', []);
|
public dateControl: UntypedFormControl = new UntypedFormControl('', []);
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<AddTokenDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AddTokenDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
this.startDate.setDate(today.getDate() + 1);
|
this.startDate.setDate(today.getDate() + 1);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,11 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-family: 'Lato', -apple-system, BlinkMacSystemFont, sans-serif;
|
font-family:
|
||||||
|
'Lato',
|
||||||
|
-apple-system,
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
sans-serif;
|
||||||
// box-shadow: 0 0 3px #0000001a;
|
// box-shadow: 0 0 3px #0000001a;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
|
@ -70,7 +70,10 @@ export class ChangesComponent implements OnInit, OnDestroy {
|
|||||||
);
|
);
|
||||||
public changes!: ListChanges;
|
public changes!: ListChanges;
|
||||||
private destroyed$: Subject<void> = new Subject();
|
private destroyed$: Subject<void> = new Subject();
|
||||||
constructor(private mgmtUserService: ManagementService, private authUserService: GrpcAuthService) {}
|
constructor(
|
||||||
|
private mgmtUserService: ManagementService,
|
||||||
|
private authUserService: GrpcAuthService,
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.init();
|
this.init();
|
||||||
|
@ -16,7 +16,10 @@ export class DisplayJsonDialogComponent {
|
|||||||
public payload: any = '';
|
public payload: any = '';
|
||||||
public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true));
|
public opened$ = this.dialogRef.afterOpened().pipe(mapTo(true));
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<DisplayJsonDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<DisplayJsonDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.event = data.event;
|
this.event = data.event;
|
||||||
if ((data.event as Event) && data.event.payload) {
|
if ((data.event as Event) && data.event.payload) {
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class AddDomainDialogComponent {
|
export class AddDomainDialogComponent {
|
||||||
public newdomain: string = '';
|
public newdomain: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<AddDomainDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AddDomainDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
67
console/src/app/modules/domains/domains.component.html
Normal file
67
console/src/app/modules/domains/domains.component.html
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<ng-container *ngIf="['org.write$'] | hasRole as canwrite$">
|
||||||
|
<div class="domain-top-view">
|
||||||
|
<div>
|
||||||
|
<div class="domain-title-row">
|
||||||
|
<h2>{{ 'ORG.DOMAINS.TITLE' | translate }}</h2>
|
||||||
|
<a
|
||||||
|
mat-icon-button
|
||||||
|
href="https://zitadel.com/docs/guides/manage/console/organizations#how-zitadel-handles-usernames"
|
||||||
|
rel="noreferrer"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<i class="las la-info-circle"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.DESCRIPTION' | translate }}</p>
|
||||||
|
</div>
|
||||||
|
<span class="fill-space"></span>
|
||||||
|
|
||||||
|
<button
|
||||||
|
[disabled]="(canwrite$ | async) === false"
|
||||||
|
matTooltip="Add domain"
|
||||||
|
mat-raised-button
|
||||||
|
color="primary"
|
||||||
|
class="cnsl-action-button"
|
||||||
|
(click)="addNewDomain()"
|
||||||
|
>
|
||||||
|
<mat-icon>add</mat-icon>
|
||||||
|
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
||||||
|
<cnsl-action-keys (actionTriggered)="addNewDomain()"> </cnsl-action-keys>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<cnsl-card *ngFor="let domain of domains" class="domain-card">
|
||||||
|
<div class="domain">
|
||||||
|
<span class="title">{{ domain.domainName }}</span>
|
||||||
|
|
||||||
|
<i matTooltip="verified" *ngIf="domain.isVerified" class="verified las la-check-circle"></i>
|
||||||
|
<i matTooltip="primary" *ngIf="domain.isPrimary" class="primary las la-star"></i>
|
||||||
|
<a
|
||||||
|
*ngIf="domain.isVerified && !domain.isPrimary && (canwrite$ | async)"
|
||||||
|
class="primaryset"
|
||||||
|
(click)="setPrimary(domain)"
|
||||||
|
>{{ 'ORG.DOMAINS.SETPRIMARY' | translate }}</a
|
||||||
|
>
|
||||||
|
|
||||||
|
<span class="fill-space"></span>
|
||||||
|
<button
|
||||||
|
mat-icon-button
|
||||||
|
[disabled]="(canwrite$ | async) === false || domain.isVerified"
|
||||||
|
*ngIf="verifyOrgDomains"
|
||||||
|
(click)="verifyDomain(domain)"
|
||||||
|
>
|
||||||
|
<i class="las la-pen"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="domain-rem-button"
|
||||||
|
[disabled]="(canwrite$ | async) === false || domain.isPrimary"
|
||||||
|
matTooltip="Remove domain"
|
||||||
|
color="warn"
|
||||||
|
mat-icon-button
|
||||||
|
(click)="removeDomain(domain.domainName)"
|
||||||
|
>
|
||||||
|
<i class="las la-trash"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</cnsl-card>
|
||||||
|
</ng-container>
|
@ -1,7 +1,6 @@
|
|||||||
.domain-top-view {
|
.domain-top-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-top: 2rem;
|
|
||||||
|
|
||||||
.domain-title-row {
|
.domain-title-row {
|
||||||
display: flex;
|
display: flex;
|
@ -19,6 +19,7 @@ export class DomainsComponent implements OnInit {
|
|||||||
public domains: Domain.AsObject[] = [];
|
public domains: Domain.AsObject[] = [];
|
||||||
public primaryDomain: string = '';
|
public primaryDomain: string = '';
|
||||||
public InfoSectionType: any = InfoSectionType;
|
public InfoSectionType: any = InfoSectionType;
|
||||||
|
public verifyOrgDomains: boolean | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private mgmtService: ManagementService,
|
private mgmtService: ManagementService,
|
||||||
@ -38,6 +39,10 @@ export class DomainsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public loadDomains(): void {
|
public loadDomains(): void {
|
||||||
|
this.mgmtService.getDomainPolicy().then((result) => {
|
||||||
|
this.verifyOrgDomains = result.policy?.validateOrgDomains;
|
||||||
|
});
|
||||||
|
|
||||||
this.mgmtService.listOrgDomains().then((result) => {
|
this.mgmtService.listOrgDomains().then((result) => {
|
||||||
this.domains = result.resultList;
|
this.domains = result.resultList;
|
||||||
this.primaryDomain = this.domains.find((domain) => domain.isPrimary)?.domainName ?? '';
|
this.primaryDomain = this.domains.find((domain) => domain.isPrimary)?.domainName ?? '';
|
||||||
@ -68,13 +73,14 @@ export class DomainsComponent implements OnInit {
|
|||||||
.addOrgDomain(domainName)
|
.addOrgDomain(domainName)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.toast.showInfo('ORG.TOAST.DOMAINADDED', true);
|
this.toast.showInfo('ORG.TOAST.DOMAINADDED', true);
|
||||||
|
if (this.verifyOrgDomains) {
|
||||||
this.verifyDomain({
|
this.verifyDomain({
|
||||||
domainName: domainName,
|
domainName: domainName,
|
||||||
validationType: DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED,
|
validationType: DomainValidationType.DOMAIN_VALIDATION_TYPE_UNSPECIFIED,
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
} else {
|
||||||
this.loadDomains();
|
this.loadDomains();
|
||||||
}, 1000);
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
this.toast.showError(error);
|
this.toast.showError(error);
|
||||||
@ -120,10 +126,8 @@ export class DomainsComponent implements OnInit {
|
|||||||
width: '500px',
|
width: '500px',
|
||||||
});
|
});
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe((reload: boolean) => {
|
dialogRef.afterClosed().subscribe(() => {
|
||||||
if (reload) {
|
|
||||||
this.loadDomains();
|
this.loadDomains();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,13 +14,11 @@ import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.mod
|
|||||||
|
|
||||||
import { AddDomainDialogModule } from './add-domain-dialog/add-domain-dialog.module';
|
import { AddDomainDialogModule } from './add-domain-dialog/add-domain-dialog.module';
|
||||||
import { DomainVerificationComponent } from './domain-verification/domain-verification.component';
|
import { DomainVerificationComponent } from './domain-verification/domain-verification.component';
|
||||||
import { DomainsRoutingModule } from './domains-routing.module';
|
|
||||||
import { DomainsComponent } from './domains.component';
|
import { DomainsComponent } from './domains.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [DomainsComponent, DomainVerificationComponent],
|
declarations: [DomainsComponent, DomainVerificationComponent],
|
||||||
imports: [
|
imports: [
|
||||||
DomainsRoutingModule,
|
|
||||||
AddDomainDialogModule,
|
AddDomainDialogModule,
|
||||||
CommonModule,
|
CommonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
@ -36,5 +34,6 @@ import { DomainsComponent } from './domains.component';
|
|||||||
InfoSectionModule,
|
InfoSectionModule,
|
||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
],
|
],
|
||||||
|
exports: [DomainsComponent],
|
||||||
})
|
})
|
||||||
export default class DomainsModule {}
|
export default class DomainsModule {}
|
@ -24,7 +24,10 @@ export class FilterOrgComponent extends FilterComponent implements OnInit {
|
|||||||
|
|
||||||
public states: OrgState[] = [OrgState.ORG_STATE_ACTIVE, OrgState.ORG_STATE_INACTIVE, OrgState.ORG_STATE_REMOVED];
|
public states: OrgState[] = [OrgState.ORG_STATE_ACTIVE, OrgState.ORG_STATE_INACTIVE, OrgState.ORG_STATE_REMOVED];
|
||||||
|
|
||||||
constructor(router: Router, protected override route: ActivatedRoute) {
|
constructor(
|
||||||
|
router: Router,
|
||||||
|
protected override route: ActivatedRoute,
|
||||||
|
) {
|
||||||
super(router, route);
|
super(router, route);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,10 @@ export class FilterComponent implements OnDestroy {
|
|||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private router: Router, protected route: ActivatedRoute) {
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
) {
|
||||||
const changes$ = this.filterChanged.asObservable();
|
const changes$ = this.filterChanged.asObservable();
|
||||||
changes$.pipe(takeUntil(this.destroy$)).subscribe((queries) => {
|
changes$.pipe(takeUntil(this.destroy$)).subscribe((queries) => {
|
||||||
const filters: Array<FilterSearchQueryAsObject | {}> | undefined = queries
|
const filters: Array<FilterSearchQueryAsObject | {}> | undefined = queries
|
||||||
|
@ -195,7 +195,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-container *ngIf="user">
|
<ng-container *ngIf="user && user.id">
|
||||||
<div class="account-card-wrapper">
|
<div class="account-card-wrapper">
|
||||||
<button
|
<button
|
||||||
cdkOverlayOrigin
|
cdkOverlayOrigin
|
||||||
|
@ -14,7 +14,10 @@ import { InfoSectionType } from '../info-section/info-section.component';
|
|||||||
export class InfoDialogComponent {
|
export class InfoDialogComponent {
|
||||||
public confirm: string = '';
|
public confirm: string = '';
|
||||||
InfoSectionType: any = InfoSectionType;
|
InfoSectionType: any = InfoSectionType;
|
||||||
constructor(public dialogRef: MatDialogRef<InfoDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<InfoDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
||||||
|
@ -9,5 +9,8 @@ export const OVERLAY_DATA = new InjectionToken<any>('OVERLAY_DATA');
|
|||||||
styleUrls: ['./info-overlay.component.scss'],
|
styleUrls: ['./info-overlay.component.scss'],
|
||||||
})
|
})
|
||||||
export class InfoOverlayComponent {
|
export class InfoOverlayComponent {
|
||||||
constructor(public workflowService: OverlayWorkflowService, @Inject(OVERLAY_DATA) public data: any) {}
|
constructor(
|
||||||
|
public workflowService: OverlayWorkflowService,
|
||||||
|
@Inject(OVERLAY_DATA) public data: any,
|
||||||
|
) {}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,10 @@ export class MembershipsDataSource extends DataSource<Membership.AsObject> {
|
|||||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||||
|
|
||||||
constructor(private auth: GrpcAuthService, private service: ManagementService) {
|
constructor(
|
||||||
|
private auth: GrpcAuthService,
|
||||||
|
private service: ManagementService,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class NameDialogComponent {
|
export class NameDialogComponent {
|
||||||
public name: string = '';
|
public name: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<NameDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<NameDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.name = data.name ?? '';
|
this.name = data.name ?? '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,11 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
background: none;
|
background: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: 'Lato', -apple-system, BlinkMacSystemFont, sans-serif;
|
font-family:
|
||||||
|
'Lato',
|
||||||
|
-apple-system,
|
||||||
|
BlinkMacSystemFont,
|
||||||
|
sans-serif;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 27px;
|
height: 27px;
|
||||||
|
|
||||||
|
@ -177,17 +177,6 @@
|
|||||||
</a>
|
</a>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
|
||||||
<a
|
|
||||||
class="nav-item"
|
|
||||||
[routerLinkActive]="['active']"
|
|
||||||
[routerLink]="['/domains']"
|
|
||||||
[routerLinkActiveOptions]="{ exact: true }"
|
|
||||||
>
|
|
||||||
<span class="label">{{ 'MENU.DOMAINS' | translate }}</span>
|
|
||||||
</a>
|
|
||||||
</ng-template>
|
|
||||||
|
|
||||||
<ng-template cnslHasRole [hasRole]="['org.read']">
|
<ng-template cnslHasRole [hasRole]="['org.read']">
|
||||||
<a
|
<a
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
|
@ -11,7 +11,10 @@ import { ONBOARDING_EVENTS } from 'src/app/utils/onboarding';
|
|||||||
export class OnboardingComponent {
|
export class OnboardingComponent {
|
||||||
public actions = this.adminService.progressEvents;
|
public actions = this.adminService.progressEvents;
|
||||||
|
|
||||||
constructor(public adminService: AdminService, public themeService: ThemeService) {
|
constructor(
|
||||||
|
public adminService: AdminService,
|
||||||
|
public themeService: ThemeService,
|
||||||
|
) {
|
||||||
this.adminService.loadEvents.next(ONBOARDING_EVENTS);
|
this.adminService.loadEvents.next(ONBOARDING_EVENTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,10 @@ export class OrgContextComponent implements OnInit {
|
|||||||
@Output() public closedCard: EventEmitter<void> = new EventEmitter();
|
@Output() public closedCard: EventEmitter<void> = new EventEmitter();
|
||||||
@Output() public setOrg: EventEmitter<Org.AsObject> = new EventEmitter();
|
@Output() public setOrg: EventEmitter<Org.AsObject> = new EventEmitter();
|
||||||
|
|
||||||
constructor(public authService: AuthenticationService, private auth: GrpcAuthService) {
|
constructor(
|
||||||
|
public authService: AuthenticationService,
|
||||||
|
private auth: GrpcAuthService,
|
||||||
|
) {
|
||||||
this.filterControl.valueChanges.pipe(debounceTime(500)).subscribe((value) => {
|
this.filterControl.valueChanges.pipe(debounceTime(500)).subscribe((value) => {
|
||||||
this.loadOrgs(value.trim().toLowerCase());
|
this.loadOrgs(value.trim().toLowerCase());
|
||||||
});
|
});
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
<h2>{{ 'POLICY.DOMAIN_POLICY.TITLE' | translate }}</h2>
|
<h2>{{ 'POLICY.DOMAIN_POLICY.TITLE' | translate }}</h2>
|
||||||
<cnsl-info-section *ngIf="isDefault"> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section>
|
<cnsl-info-section *ngIf="isDefault"> {{ 'POLICY.DEFAULTLABEL' | translate }}</cnsl-info-section>
|
||||||
|
|
||||||
<!-- <ng-template cnslHasRole [hasRole]="['domain.policy.delete']"> -->
|
|
||||||
<button
|
<button
|
||||||
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
*ngIf="serviceType === PolicyComponentServiceType.MGMT && !isDefault"
|
||||||
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
matTooltip="{{ 'POLICY.RESET' | translate }}"
|
||||||
@ -26,7 +25,6 @@
|
|||||||
>
|
>
|
||||||
{{ 'POLICY.RESET' | translate }}
|
{{ 'POLICY.RESET' | translate }}
|
||||||
</button>
|
</button>
|
||||||
<!-- </ng-template> -->
|
|
||||||
|
|
||||||
<div class="domain-policy-content" *ngIf="domainData">
|
<div class="domain-policy-content" *ngIf="domainData">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -13,7 +13,10 @@ export class GeneralSettingsComponent implements OnInit {
|
|||||||
public defaultLanguageOptions: string[] = [];
|
public defaultLanguageOptions: string[] = [];
|
||||||
|
|
||||||
public loading: boolean = false;
|
public loading: boolean = false;
|
||||||
constructor(private service: AdminService, private toast: ToastService) {}
|
constructor(
|
||||||
|
private service: AdminService,
|
||||||
|
private toast: ToastService,
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
|
@ -20,7 +20,10 @@ export class DialogAddTypeComponent {
|
|||||||
public availableMfaTypes: Array<MultiFactorType | SecondFactorType> = [];
|
public availableMfaTypes: Array<MultiFactorType | SecondFactorType> = [];
|
||||||
public newMfaType!: MultiFactorType | SecondFactorType;
|
public newMfaType!: MultiFactorType | SecondFactorType;
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<DialogAddTypeComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<DialogAddTypeComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.availableMfaTypes = data.types;
|
this.availableMfaTypes = data.types;
|
||||||
this.newMfaType = data.types && data.types[0] ? data.types[0] : undefined;
|
this.newMfaType = data.types && data.types[0] ? data.types[0] : undefined;
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,11 @@ export class FactorTableComponent {
|
|||||||
|
|
||||||
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
||||||
|
|
||||||
constructor(public translate: TranslateService, private toast: ToastService, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
public translate: TranslateService,
|
||||||
|
private toast: ToastService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
public removeMfa(type: MultiFactorType | SecondFactorType): void {
|
public removeMfa(type: MultiFactorType | SecondFactorType): void {
|
||||||
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
const dialogRef = this.dialog.open(WarnDialogComponent, {
|
||||||
|
@ -36,7 +36,11 @@ export class NotificationPolicyComponent implements OnInit {
|
|||||||
|
|
||||||
public isDefault: boolean = false;
|
public isDefault: boolean = false;
|
||||||
private hasNotificationPolicy: boolean = false;
|
private hasNotificationPolicy: boolean = false;
|
||||||
constructor(private toast: ToastService, private injector: Injector, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private toast: ToastService,
|
||||||
|
private injector: Injector,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
switch (this.serviceType) {
|
switch (this.serviceType) {
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class PasswordDialogComponent {
|
export class PasswordDialogComponent {
|
||||||
public password: string = '';
|
public password: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<PasswordDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<PasswordDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {}
|
||||||
|
|
||||||
closeDialog(password: string = ''): void {
|
closeDialog(password: string = ''): void {
|
||||||
this.dialogRef.close(password);
|
this.dialogRef.close(password);
|
||||||
|
@ -27,7 +27,11 @@ export class PasswordComplexityPolicyComponent implements OnInit {
|
|||||||
public loading: boolean = false;
|
public loading: boolean = false;
|
||||||
public InfoSectionType: any = InfoSectionType;
|
public InfoSectionType: any = InfoSectionType;
|
||||||
|
|
||||||
constructor(private toast: ToastService, private injector: Injector, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private toast: ToastService,
|
||||||
|
private injector: Injector,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
switch (this.serviceType) {
|
switch (this.serviceType) {
|
||||||
|
@ -26,7 +26,11 @@ export class PasswordLockoutPolicyComponent implements OnInit {
|
|||||||
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
||||||
public InfoSectionType: any = InfoSectionType;
|
public InfoSectionType: any = InfoSectionType;
|
||||||
|
|
||||||
constructor(private toast: ToastService, private injector: Injector, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private toast: ToastService,
|
||||||
|
private injector: Injector,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
switch (this.serviceType) {
|
switch (this.serviceType) {
|
||||||
|
@ -54,7 +54,9 @@
|
|||||||
|
|
||||||
::ng-deep .chrome-picker {
|
::ng-deep .chrome-picker {
|
||||||
border-radius: 0.5rem !important;
|
border-radius: 0.5rem !important;
|
||||||
box-shadow: 0 0 1px #00000020, 0 1px 3px #00000020 !important;
|
box-shadow:
|
||||||
|
0 0 1px #00000020,
|
||||||
|
0 1px 3px #00000020 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
::ng-deep .saturation {
|
::ng-deep .saturation {
|
||||||
|
@ -29,7 +29,11 @@ export class SecretGeneratorComponent implements OnInit {
|
|||||||
SecretGeneratorType.SECRET_GENERATOR_TYPE_OTP_EMAIL,
|
SecretGeneratorType.SECRET_GENERATOR_TYPE_OTP_EMAIL,
|
||||||
];
|
];
|
||||||
|
|
||||||
constructor(private service: AdminService, private toast: ToastService, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private service: AdminService,
|
||||||
|
private toast: ToastService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
|
@ -20,7 +20,10 @@ export class SecurityPolicyComponent implements OnInit {
|
|||||||
|
|
||||||
@Input() public originsControl: UntypedFormControl = new UntypedFormControl({ value: [], disabled: true });
|
@Input() public originsControl: UntypedFormControl = new UntypedFormControl({ value: [], disabled: true });
|
||||||
|
|
||||||
constructor(private service: AdminService, private toast: ToastService) {}
|
constructor(
|
||||||
|
private service: AdminService,
|
||||||
|
private toast: ToastService,
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.fetchData();
|
this.fetchData();
|
||||||
|
@ -246,7 +246,8 @@ export class ProviderAppleComponent {
|
|||||||
return (e) => {
|
return (e) => {
|
||||||
const keyBase64 = e.target?.result;
|
const keyBase64 = e.target?.result;
|
||||||
if (keyBase64 && typeof keyBase64 === 'string') {
|
if (keyBase64 && typeof keyBase64 === 'string') {
|
||||||
const cropped = keyBase64.replace('data:application/octet-stream;base64,', '');
|
const contentType = file.type || 'application/octet-stream';
|
||||||
|
const cropped = keyBase64.replace(`data:${contentType};base64,`, '');
|
||||||
this.privateKey?.setValue(cropped);
|
this.privateKey?.setValue(cropped);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,10 @@ export class SearchOrgAutocompleteComponent implements OnInit, OnDestroy {
|
|||||||
@Output() public selectionChanged: EventEmitter<Org.AsObject> = new EventEmitter();
|
@Output() public selectionChanged: EventEmitter<Org.AsObject> = new EventEmitter();
|
||||||
|
|
||||||
private unsubscribed$: Subject<void> = new Subject();
|
private unsubscribed$: Subject<void> = new Subject();
|
||||||
constructor(public authService: AuthenticationService, private auth: GrpcAuthService) {
|
constructor(
|
||||||
|
public authService: AuthenticationService,
|
||||||
|
private auth: GrpcAuthService,
|
||||||
|
) {
|
||||||
this.myControl.valueChanges
|
this.myControl.valueChanges
|
||||||
.pipe(
|
.pipe(
|
||||||
takeUntil(this.unsubscribed$),
|
takeUntil(this.unsubscribed$),
|
||||||
|
@ -57,7 +57,11 @@ export class SearchUserAutocompleteComponent implements OnInit, AfterContentChec
|
|||||||
@Input() public singleOutput: boolean = false;
|
@Input() public singleOutput: boolean = false;
|
||||||
|
|
||||||
private unsubscribed$: Subject<void> = new Subject();
|
private unsubscribed$: Subject<void> = new Subject();
|
||||||
constructor(private userService: ManagementService, private toast: ToastService, private cdref: ChangeDetectorRef) {}
|
constructor(
|
||||||
|
private userService: ManagementService,
|
||||||
|
private toast: ToastService,
|
||||||
|
private cdref: ChangeDetectorRef,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
if (this.target === UserTarget.EXTERNAL) {
|
if (this.target === UserTarget.EXTERNAL) {
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
<ng-container *ngIf="currentSetting === 'login'">
|
<ng-container *ngIf="currentSetting === 'login'">
|
||||||
<cnsl-login-policy [serviceType]="serviceType"></cnsl-login-policy>
|
<cnsl-login-policy [serviceType]="serviceType"></cnsl-login-policy>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="currentSetting === 'domain'">
|
<ng-container *ngIf="currentSetting === 'verified_domains'">
|
||||||
|
<cnsl-domains></cnsl-domains>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container *ngIf="currentSetting === 'domain' && (['iam.policy.write'] | hasRole | async) === true">
|
||||||
<cnsl-domain-policy [serviceType]="serviceType"></cnsl-domain-policy>
|
<cnsl-domain-policy [serviceType]="serviceType"></cnsl-domain-policy>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="currentSetting === 'idp'">
|
<ng-container *ngIf="currentSetting === 'idp'">
|
||||||
|
@ -5,6 +5,7 @@ import { TranslateModule } from '@ngx-translate/core';
|
|||||||
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
import { HasRolePipeModule } from 'src/app/pipes/has-role-pipe/has-role-pipe.module';
|
||||||
|
|
||||||
import { CardModule } from '../card/card.module';
|
import { CardModule } from '../card/card.module';
|
||||||
|
import DomainsModule from '../domains/domains.module';
|
||||||
import { DomainPolicyModule } from '../policies/domain-policy/domain-policy.module';
|
import { DomainPolicyModule } from '../policies/domain-policy/domain-policy.module';
|
||||||
import { GeneralSettingsModule } from '../policies/general-settings/general-settings.module';
|
import { GeneralSettingsModule } from '../policies/general-settings/general-settings.module';
|
||||||
import { IdpSettingsModule } from '../policies/idp-settings/idp-settings.module';
|
import { IdpSettingsModule } from '../policies/idp-settings/idp-settings.module';
|
||||||
@ -40,6 +41,7 @@ import { SettingsListComponent } from './settings-list.component';
|
|||||||
PrivacyPolicyModule,
|
PrivacyPolicyModule,
|
||||||
MessageTextsPolicyModule,
|
MessageTextsPolicyModule,
|
||||||
SecurityPolicyModule,
|
SecurityPolicyModule,
|
||||||
|
DomainsModule,
|
||||||
LoginTextsPolicyModule,
|
LoginTextsPolicyModule,
|
||||||
DomainPolicyModule,
|
DomainPolicyModule,
|
||||||
TranslateModule,
|
TranslateModule,
|
||||||
|
@ -43,13 +43,22 @@ export const LOGIN: SidenavSetting = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const VERIFIED_DOMAINS: SidenavSetting = {
|
||||||
|
id: 'verified_domains',
|
||||||
|
i18nKey: 'SETTINGS.LIST.VERIFIED_DOMAINS',
|
||||||
|
groupI18nKey: 'SETTINGS.GROUPS.DOMAIN',
|
||||||
|
requiredRoles: {
|
||||||
|
[PolicyComponentServiceType.MGMT]: ['org.read'],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const DOMAIN: SidenavSetting = {
|
export const DOMAIN: SidenavSetting = {
|
||||||
id: 'domain',
|
id: 'domain',
|
||||||
i18nKey: 'SETTINGS.LIST.DOMAIN',
|
i18nKey: 'SETTINGS.LIST.DOMAIN',
|
||||||
groupI18nKey: 'SETTINGS.GROUPS.DOMAIN',
|
groupI18nKey: 'SETTINGS.GROUPS.DOMAIN',
|
||||||
requiredRoles: {
|
requiredRoles: {
|
||||||
[PolicyComponentServiceType.MGMT]: ['policy.read'],
|
[PolicyComponentServiceType.MGMT]: ['iam.policy.write'],
|
||||||
[PolicyComponentServiceType.ADMIN]: ['iam.policy.read'],
|
[PolicyComponentServiceType.ADMIN]: ['iam.policy.write'],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -240,7 +240,10 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
border: 1px solid $border-color;
|
border: 1px solid $border-color;
|
||||||
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
box-shadow:
|
||||||
|
0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
||||||
|
0 8px 10px 1px rgba(0, 0, 0, 0.14),
|
||||||
|
0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cdk-drag-placeholder {
|
.cdk-drag-placeholder {
|
||||||
|
@ -16,7 +16,10 @@ export class ShowKeyDialogComponent {
|
|||||||
public keyResponse!: AddMachineKeyResponse.AsObject | AddAppKeyResponse.AsObject;
|
public keyResponse!: AddMachineKeyResponse.AsObject | AddAppKeyResponse.AsObject;
|
||||||
public InfoSectionType: any = InfoSectionType;
|
public InfoSectionType: any = InfoSectionType;
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<ShowKeyDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<ShowKeyDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.keyResponse = data.key;
|
this.keyResponse = data.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,10 @@ export class ShowTokenDialogComponent {
|
|||||||
public copied: string = '';
|
public copied: string = '';
|
||||||
InfoSectionType: any = InfoSectionType;
|
InfoSectionType: any = InfoSectionType;
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<ShowTokenDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<ShowTokenDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.tokenResponse = data.token;
|
this.tokenResponse = data.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,11 +28,6 @@
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
(click)="value = setting.id"
|
(click)="value = setting.id"
|
||||||
*ngIf="
|
|
||||||
!setting.requiredRoles ||
|
|
||||||
(setting.requiredRoles.mgmt && (setting.requiredRoles.mgmt | hasRole | async)) ||
|
|
||||||
(setting.requiredRoles.admin && (setting.requiredRoles.admin | hasRole | async))
|
|
||||||
"
|
|
||||||
class="sidenav-setting-list-element hide-on-mobile"
|
class="sidenav-setting-list-element hide-on-mobile"
|
||||||
[ngClass]="{ active: currentSetting === setting.id, show: currentSetting === undefined }"
|
[ngClass]="{ active: currentSetting === setting.id, show: currentSetting === undefined }"
|
||||||
[attr.data-e2e]="'sidenav-element-' + setting.id"
|
[attr.data-e2e]="'sidenav-element-' + setting.id"
|
||||||
|
@ -30,7 +30,10 @@ export class SidenavComponent implements ControlValueAccessor, OnInit {
|
|||||||
@Input() public queryParam: string = '';
|
@Input() public queryParam: string = '';
|
||||||
|
|
||||||
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
||||||
constructor(private router: Router, private route: ActivatedRoute) {}
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (!this.value) {
|
if (!this.value) {
|
||||||
|
@ -16,7 +16,10 @@ export class UserGrantRoleDialogComponent {
|
|||||||
|
|
||||||
public selectedRoleKeys: string[] = [];
|
public selectedRoleKeys: string[] = [];
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<UserGrantRoleDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<UserGrantRoleDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.projectId = data.projectId;
|
this.projectId = data.projectId;
|
||||||
this.grantId = data.grantId;
|
this.grantId = data.grantId;
|
||||||
this.selectedRoleKeysList = data.selectedRoleKeysList;
|
this.selectedRoleKeysList = data.selectedRoleKeysList;
|
||||||
|
@ -31,7 +31,10 @@ export class UserGrantsDataSource extends DataSource<UserGrantAsObject> {
|
|||||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||||
|
|
||||||
constructor(private authService: GrpcAuthService, private userService: ManagementService) {
|
constructor(
|
||||||
|
private authService: GrpcAuthService,
|
||||||
|
private userService: ManagementService,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<a
|
<a
|
||||||
actions
|
actions
|
||||||
*ngIf="disableWrite === false && selection.hasValue() === false"
|
*ngIf="disableWrite === false && selection.hasValue() === false && routerLink"
|
||||||
matTooltip="{{ 'GRANTS.ADD' | translate }}"
|
matTooltip="{{ 'GRANTS.ADD' | translate }}"
|
||||||
color="primary"
|
color="primary"
|
||||||
class="cnsl-action-button"
|
class="cnsl-action-button"
|
||||||
|
@ -56,7 +56,7 @@ export class UserGrantsComponent implements OnInit, AfterViewInit {
|
|||||||
@ViewChild('input') public filter!: MatInput;
|
@ViewChild('input') public filter!: MatInput;
|
||||||
|
|
||||||
public projectRoleOptions: Role.AsObject[] = [];
|
public projectRoleOptions: Role.AsObject[] = [];
|
||||||
public routerLink: any = [''];
|
public routerLink: any = undefined;
|
||||||
|
|
||||||
public loadedId: string = '';
|
public loadedId: string = '';
|
||||||
public loadedProjectId: string = '';
|
public loadedProjectId: string = '';
|
||||||
|
@ -14,7 +14,10 @@ import { InfoSectionType } from '../info-section/info-section.component';
|
|||||||
export class WarnDialogComponent {
|
export class WarnDialogComponent {
|
||||||
public confirm: string = '';
|
public confirm: string = '';
|
||||||
InfoSectionType: any = InfoSectionType;
|
InfoSectionType: any = InfoSectionType;
|
||||||
constructor(public dialogRef: MatDialogRef<WarnDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<WarnDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
||||||
|
@ -150,7 +150,10 @@
|
|||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
background-color: $primary-color;
|
background-color: $primary-color;
|
||||||
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
box-shadow:
|
||||||
|
0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
||||||
|
0 8px 10px 1px rgba(0, 0, 0, 0.14),
|
||||||
|
0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
||||||
|
|
||||||
i {
|
i {
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
|
@ -13,7 +13,10 @@ export class AppCreateComponent {
|
|||||||
public projectId: string = '';
|
public projectId: string = '';
|
||||||
public ProjectAutocompleteType: any = ProjectAutocompleteType;
|
public ProjectAutocompleteType: any = ProjectAutocompleteType;
|
||||||
|
|
||||||
constructor(private router: Router, breadcrumbService: BreadcrumbService) {
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
breadcrumbService: BreadcrumbService,
|
||||||
|
) {
|
||||||
const bread: Breadcrumb = {
|
const bread: Breadcrumb = {
|
||||||
type: BreadcrumbType.ORG,
|
type: BreadcrumbType.ORG,
|
||||||
routerLink: ['/org'],
|
routerLink: ['/org'],
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
|
||||||
|
|
||||||
import { DomainsComponent } from './domains.component';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: DomainsComponent,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [RouterModule.forChild(routes)],
|
|
||||||
exports: [RouterModule],
|
|
||||||
})
|
|
||||||
export class DomainsRoutingModule {}
|
|
@ -1,69 +0,0 @@
|
|||||||
<div class="max-width-container">
|
|
||||||
<ng-container *ngIf="['org.write$'] | hasRole as canwrite$">
|
|
||||||
<div class="domain-top-view">
|
|
||||||
<div>
|
|
||||||
<div class="domain-title-row">
|
|
||||||
<h1>{{ 'ORG.DOMAINS.TITLE' | translate }}</h1>
|
|
||||||
<a
|
|
||||||
mat-icon-button
|
|
||||||
href="https://zitadel.com/docs/guides/manage/console/organizations#how-zitadel-handles-usernames"
|
|
||||||
rel="noreferrer"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<i class="las la-info-circle"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<p class="desc cnsl-secondary-text">{{ 'ORG.DOMAINS.DESCRIPTION' | translate }}</p>
|
|
||||||
</div>
|
|
||||||
<span class="fill-space"></span>
|
|
||||||
|
|
||||||
<button
|
|
||||||
[disabled]="(canwrite$ | async) === false"
|
|
||||||
matTooltip="Add domain"
|
|
||||||
mat-raised-button
|
|
||||||
color="primary"
|
|
||||||
class="cnsl-action-button"
|
|
||||||
(click)="addNewDomain()"
|
|
||||||
>
|
|
||||||
<mat-icon>add</mat-icon>
|
|
||||||
<span>{{ 'ACTIONS.NEW' | translate }}</span>
|
|
||||||
<cnsl-action-keys (actionTriggered)="addNewDomain()"> </cnsl-action-keys>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<cnsl-card *ngFor="let domain of domains" class="domain-card">
|
|
||||||
<div class="domain">
|
|
||||||
<span class="title">{{ domain.domainName }}</span>
|
|
||||||
|
|
||||||
<i matTooltip="verified" *ngIf="domain.isVerified" class="verified las la-check-circle"></i>
|
|
||||||
<i matTooltip="primary" *ngIf="domain.isPrimary" class="primary las la-star"></i>
|
|
||||||
<a
|
|
||||||
*ngIf="domain.isVerified && !domain.isPrimary && (canwrite$ | async)"
|
|
||||||
class="primaryset"
|
|
||||||
(click)="setPrimary(domain)"
|
|
||||||
>{{ 'ORG.DOMAINS.SETPRIMARY' | translate }}</a
|
|
||||||
>
|
|
||||||
|
|
||||||
<span class="fill-space"></span>
|
|
||||||
<button
|
|
||||||
mat-icon-button
|
|
||||||
[disabled]="(canwrite$ | async) === false || domain.isVerified"
|
|
||||||
*ngIf="canwrite$ | async"
|
|
||||||
(click)="verifyDomain(domain)"
|
|
||||||
>
|
|
||||||
<i class="las la-pen"></i>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="domain-rem-button"
|
|
||||||
[disabled]="(canwrite$ | async) === false || domain.isPrimary"
|
|
||||||
matTooltip="Remove domain"
|
|
||||||
color="warn"
|
|
||||||
mat-icon-button
|
|
||||||
(click)="removeDomain(domain.domainName)"
|
|
||||||
>
|
|
||||||
<i class="las la-trash"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</cnsl-card>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
|
@ -21,7 +21,11 @@ export class HomeComponent {
|
|||||||
|
|
||||||
public dark: boolean = true;
|
public dark: boolean = true;
|
||||||
|
|
||||||
constructor(public authService: GrpcAuthService, breadcrumbService: BreadcrumbService, public themeService: ThemeService) {
|
constructor(
|
||||||
|
public authService: GrpcAuthService,
|
||||||
|
breadcrumbService: BreadcrumbService,
|
||||||
|
public themeService: ThemeService,
|
||||||
|
) {
|
||||||
const bread: Breadcrumb = {
|
const bread: Breadcrumb = {
|
||||||
type: BreadcrumbType.ORG,
|
type: BreadcrumbType.ORG,
|
||||||
routerLink: ['/org'],
|
routerLink: ['/org'],
|
||||||
|
@ -23,7 +23,10 @@ export class IamViewsComponent implements AfterViewInit {
|
|||||||
|
|
||||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||||
constructor(private adminService: AdminService, private breadcrumbService: BreadcrumbService) {
|
constructor(
|
||||||
|
private adminService: AdminService,
|
||||||
|
private breadcrumbService: BreadcrumbService,
|
||||||
|
) {
|
||||||
this.loadViews();
|
this.loadViews();
|
||||||
|
|
||||||
const breadcrumbs = [
|
const breadcrumbs = [
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<ng-container *ngIf="settingsList | async as list">
|
||||||
<cnsl-settings-list
|
<cnsl-settings-list
|
||||||
[selectedId]="id"
|
[selectedId]="id"
|
||||||
[serviceType]="PolicyComponentServiceType.ADMIN"
|
[serviceType]="PolicyComponentServiceType.ADMIN"
|
||||||
[settingsList]="settingsList"
|
[settingsList]="list"
|
||||||
></cnsl-settings-list>
|
></cnsl-settings-list>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { Component, OnDestroy } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute, Params } from '@angular/router';
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
import { Subject, takeUntil } from 'rxjs';
|
import { Observable, of, Subject, takeUntil } from 'rxjs';
|
||||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||||
import { SidenavSetting } from 'src/app/modules/sidenav/sidenav.component';
|
import { SidenavSetting } from 'src/app/modules/sidenav/sidenav.component';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||||
|
|
||||||
|
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||||
import {
|
import {
|
||||||
BRANDING,
|
BRANDING,
|
||||||
COMPLEXITY,
|
COMPLEXITY,
|
||||||
@ -27,10 +28,10 @@ import {
|
|||||||
templateUrl: './instance-settings.component.html',
|
templateUrl: './instance-settings.component.html',
|
||||||
styleUrls: ['./instance-settings.component.scss'],
|
styleUrls: ['./instance-settings.component.scss'],
|
||||||
})
|
})
|
||||||
export class InstanceSettingsComponent implements OnDestroy {
|
export class InstanceSettingsComponent implements OnInit, OnDestroy {
|
||||||
public id: string = '';
|
public id: string = '';
|
||||||
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
||||||
public settingsList: SidenavSetting[] = [
|
public defaultSettingsList: SidenavSetting[] = [
|
||||||
GENERAL,
|
GENERAL,
|
||||||
// notifications
|
// notifications
|
||||||
// { showWarn: true, ...NOTIFICATIONS },
|
// { showWarn: true, ...NOTIFICATIONS },
|
||||||
@ -53,8 +54,14 @@ export class InstanceSettingsComponent implements OnDestroy {
|
|||||||
SECURITY,
|
SECURITY,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
public settingsList: Observable<SidenavSetting[]> = of([]);
|
||||||
|
|
||||||
private destroy$: Subject<void> = new Subject();
|
private destroy$: Subject<void> = new Subject();
|
||||||
constructor(breadcrumbService: BreadcrumbService, activatedRoute: ActivatedRoute) {
|
constructor(
|
||||||
|
breadcrumbService: BreadcrumbService,
|
||||||
|
activatedRoute: ActivatedRoute,
|
||||||
|
public authService: GrpcAuthService,
|
||||||
|
) {
|
||||||
const breadcrumbs = [
|
const breadcrumbs = [
|
||||||
new Breadcrumb({
|
new Breadcrumb({
|
||||||
type: BreadcrumbType.INSTANCE,
|
type: BreadcrumbType.INSTANCE,
|
||||||
@ -72,6 +79,10 @@ export class InstanceSettingsComponent implements OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.settingsList = this.authService.isAllowedMapper(this.defaultSettingsList, (setting) => setting.requiredRoles.admin);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.destroy$.next();
|
this.destroy$.next();
|
||||||
this.destroy$.complete();
|
this.destroy$.complete();
|
||||||
|
@ -8,9 +8,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="fill-space"></span>
|
<span class="fill-space"></span>
|
||||||
</div>
|
</div>
|
||||||
|
<ng-container *ngIf="settingsList | async as list">
|
||||||
<cnsl-settings-list
|
<cnsl-settings-list
|
||||||
[selectedId]="id"
|
[selectedId]="id"
|
||||||
[serviceType]="PolicyComponentServiceType.MGMT"
|
[serviceType]="PolicyComponentServiceType.MGMT"
|
||||||
[settingsList]="settingsList"
|
[settingsList]="list"
|
||||||
></cnsl-settings-list>
|
></cnsl-settings-list>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute, Params } from '@angular/router';
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
import { take } from 'rxjs';
|
import { Observable, of, take } from 'rxjs';
|
||||||
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
import { PolicyComponentServiceType } from 'src/app/modules/policies/policy-component-types.enum';
|
||||||
import { SidenavSetting } from 'src/app/modules/sidenav/sidenav.component';
|
import { SidenavSetting } from 'src/app/modules/sidenav/sidenav.component';
|
||||||
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
import { Breadcrumb, BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
|
||||||
|
|
||||||
|
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
|
||||||
import {
|
import {
|
||||||
BRANDING,
|
BRANDING,
|
||||||
COMPLEXITY,
|
COMPLEXITY,
|
||||||
@ -16,6 +17,7 @@ import {
|
|||||||
MESSAGETEXTS,
|
MESSAGETEXTS,
|
||||||
NOTIFICATION_POLICY,
|
NOTIFICATION_POLICY,
|
||||||
PRIVACYPOLICY,
|
PRIVACYPOLICY,
|
||||||
|
VERIFIED_DOMAINS,
|
||||||
} from '../../modules/settings-list/settings';
|
} from '../../modules/settings-list/settings';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -23,15 +25,17 @@ import {
|
|||||||
templateUrl: './org-settings.component.html',
|
templateUrl: './org-settings.component.html',
|
||||||
styleUrls: ['./org-settings.component.scss'],
|
styleUrls: ['./org-settings.component.scss'],
|
||||||
})
|
})
|
||||||
export class OrgSettingsComponent {
|
export class OrgSettingsComponent implements OnInit {
|
||||||
public id: string = '';
|
public id: string = '';
|
||||||
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
public PolicyComponentServiceType: any = PolicyComponentServiceType;
|
||||||
public settingsList: SidenavSetting[] = [
|
|
||||||
|
private defaultSettingsList: SidenavSetting[] = [
|
||||||
LOGIN,
|
LOGIN,
|
||||||
IDP,
|
IDP,
|
||||||
COMPLEXITY,
|
COMPLEXITY,
|
||||||
LOCKOUT,
|
LOCKOUT,
|
||||||
NOTIFICATION_POLICY,
|
NOTIFICATION_POLICY,
|
||||||
|
VERIFIED_DOMAINS,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
BRANDING,
|
BRANDING,
|
||||||
MESSAGETEXTS,
|
MESSAGETEXTS,
|
||||||
@ -39,7 +43,13 @@ export class OrgSettingsComponent {
|
|||||||
PRIVACYPOLICY,
|
PRIVACYPOLICY,
|
||||||
];
|
];
|
||||||
|
|
||||||
constructor(breadcrumbService: BreadcrumbService, activatedRoute: ActivatedRoute) {
|
public settingsList: Observable<Array<SidenavSetting>> = of([]);
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
breadcrumbService: BreadcrumbService,
|
||||||
|
activatedRoute: ActivatedRoute,
|
||||||
|
public authService: GrpcAuthService,
|
||||||
|
) {
|
||||||
const breadcrumbs = [
|
const breadcrumbs = [
|
||||||
new Breadcrumb({
|
new Breadcrumb({
|
||||||
type: BreadcrumbType.ORG,
|
type: BreadcrumbType.ORG,
|
||||||
@ -55,4 +65,10 @@ export class OrgSettingsComponent {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.settingsList = this.authService
|
||||||
|
.isAllowedMapper(this.defaultSettingsList, (setting) => setting.requiredRoles.mgmt)
|
||||||
|
.pipe(take(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class AuthMethodDialogComponent {
|
export class AuthMethodDialogComponent {
|
||||||
public authmethod: string = '';
|
public authmethod: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<AuthMethodDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AuthMethodDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
this.authmethod = data.initialAuthMethod;
|
this.authmethod = data.initialAuthMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class AppSecretDialogComponent {
|
export class AppSecretDialogComponent {
|
||||||
public copied: string = '';
|
public copied: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<AppSecretDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<AppSecretDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
||||||
|
@ -17,7 +17,10 @@ export class ProjectGrantsDataSource extends DataSource<GrantedProject.AsObject>
|
|||||||
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
private loadingSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
public loading$: Observable<boolean> = this.loadingSubject.asObservable();
|
||||||
|
|
||||||
constructor(private mgmtService: ManagementService, private toast: ToastService) {
|
constructor(
|
||||||
|
private mgmtService: ManagementService,
|
||||||
|
private toast: ToastService,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,11 @@ export class AuthPasswordlessComponent implements OnInit, OnDestroy {
|
|||||||
public AuthFactorState: any = AuthFactorState;
|
public AuthFactorState: any = AuthFactorState;
|
||||||
public error: string = '';
|
public error: string = '';
|
||||||
|
|
||||||
constructor(private service: GrpcAuthService, private toast: ToastService, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private service: GrpcAuthService,
|
||||||
|
private toast: ToastService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.getPasswordless();
|
this.getPasswordless();
|
||||||
|
@ -42,7 +42,11 @@ export class AuthUserMfaComponent implements OnInit, OnDestroy {
|
|||||||
public otpSmsDisabled$ = new BehaviorSubject<boolean>(true);
|
public otpSmsDisabled$ = new BehaviorSubject<boolean>(true);
|
||||||
public otpEmailDisabled$ = new BehaviorSubject<boolean>(true);
|
public otpEmailDisabled$ = new BehaviorSubject<boolean>(true);
|
||||||
|
|
||||||
constructor(private service: GrpcAuthService, private toast: ToastService, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private service: GrpcAuthService,
|
||||||
|
private toast: ToastService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.getMFAs();
|
this.getMFAs();
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class CodeDialogComponent {
|
export class CodeDialogComponent {
|
||||||
public code: string = '';
|
public code: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<CodeDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<CodeDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {}
|
||||||
|
|
||||||
closeDialog(code: string = ''): void {
|
closeDialog(code: string = ''): void {
|
||||||
this.dialogRef.close(code);
|
this.dialogRef.close(code);
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class ResendEmailDialogComponent {
|
export class ResendEmailDialogComponent {
|
||||||
public email: string = '';
|
public email: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<ResendEmailDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<ResendEmailDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {
|
||||||
if (data.email) {
|
if (data.email) {
|
||||||
this.email = data.email;
|
this.email = data.email;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,10 @@ export class ContactComponent {
|
|||||||
public UserState: any = UserState;
|
public UserState: any = UserState;
|
||||||
|
|
||||||
public EditDialogType: any = EditDialogType;
|
public EditDialogType: any = EditDialogType;
|
||||||
constructor(private dialog: MatDialog, private authService: GrpcAuthService) {}
|
constructor(
|
||||||
|
private dialog: MatDialog,
|
||||||
|
private authService: GrpcAuthService,
|
||||||
|
) {}
|
||||||
|
|
||||||
async emitDeletePhone(): Promise<void> {
|
async emitDeletePhone(): Promise<void> {
|
||||||
const { resultList } = await this.authService.listMyMultiFactors();
|
const { resultList } = await this.authService.listMyMultiFactors();
|
||||||
|
@ -29,7 +29,10 @@ export class DetailFormComponent implements OnDestroy, OnChanges {
|
|||||||
|
|
||||||
private sub: Subscription = new Subscription();
|
private sub: Subscription = new Subscription();
|
||||||
|
|
||||||
constructor(private fb: UntypedFormBuilder, private dialog: MatDialog) {
|
constructor(
|
||||||
|
private fb: UntypedFormBuilder,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {
|
||||||
this.profileForm = this.fb.group({
|
this.profileForm = this.fb.group({
|
||||||
userName: [{ value: '', disabled: true }, [requiredValidator]],
|
userName: [{ value: '', disabled: true }, [requiredValidator]],
|
||||||
firstName: [{ value: '', disabled: this.disabled }, requiredValidator],
|
firstName: [{ value: '', disabled: this.disabled }, requiredValidator],
|
||||||
|
@ -35,7 +35,10 @@ export class ExternalIdpsComponent implements OnInit, OnDestroy {
|
|||||||
'actions',
|
'actions',
|
||||||
];
|
];
|
||||||
|
|
||||||
constructor(private toast: ToastService, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private toast: ToastService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.getData(10, 0);
|
this.getData(10, 0);
|
||||||
|
@ -11,7 +11,10 @@ import {
|
|||||||
})
|
})
|
||||||
export class MachineSecretDialogComponent {
|
export class MachineSecretDialogComponent {
|
||||||
public copied: string = '';
|
public copied: string = '';
|
||||||
constructor(public dialogRef: MatDialogRef<MachineSecretDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) {}
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<MachineSecretDialogComponent>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||||
|
) {}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
this.dialogRef.close(false);
|
this.dialogRef.close(false);
|
||||||
|
@ -37,7 +37,11 @@ export class PasswordlessComponent implements OnInit, OnDestroy {
|
|||||||
public AuthFactorState: any = AuthFactorState;
|
public AuthFactorState: any = AuthFactorState;
|
||||||
public error: string = '';
|
public error: string = '';
|
||||||
|
|
||||||
constructor(private service: ManagementService, private toast: ToastService, private dialog: MatDialog) {}
|
constructor(
|
||||||
|
private service: ManagementService,
|
||||||
|
private toast: ToastService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.getPasswordless();
|
this.getPasswordless();
|
||||||
|
@ -78,7 +78,7 @@
|
|||||||
|
|
||||||
<ng-container *ngIf="currentSetting === 'general'">
|
<ng-container *ngIf="currentSetting === 'general'">
|
||||||
<ng-template cnslHasRole [hasRole]="['user.read$', 'user.read:' + user.id]">
|
<ng-template cnslHasRole [hasRole]="['user.read$', 'user.read:' + user.id]">
|
||||||
<cnsl-card *ngIf="user.human" title="{{ 'USER.PROFILE.TITLE' | translate }}">
|
<cnsl-card *ngIf="user.human" title="{{ user.preferredLoginName }} - {{ 'USER.PROFILE.TITLE' | translate }}">
|
||||||
<cnsl-detail-form
|
<cnsl-detail-form
|
||||||
[preferredLoginName]="user.preferredLoginName"
|
[preferredLoginName]="user.preferredLoginName"
|
||||||
[disabled]="(canWrite$ | async) === false"
|
[disabled]="(canWrite$ | async) === false"
|
||||||
|
@ -32,7 +32,11 @@ export class UserMfaComponent implements OnInit, OnDestroy {
|
|||||||
public AuthFactorState: any = AuthFactorState;
|
public AuthFactorState: any = AuthFactorState;
|
||||||
|
|
||||||
public error: string = '';
|
public error: string = '';
|
||||||
constructor(private mgmtUserService: ManagementService, private dialog: MatDialog, private toast: ToastService) {}
|
constructor(
|
||||||
|
private mgmtUserService: ManagementService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
private toast: ToastService,
|
||||||
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.getMFAs();
|
this.getMFAs();
|
||||||
|
@ -14,7 +14,11 @@ export class UserListComponent {
|
|||||||
public Type: any = Type;
|
public Type: any = Type;
|
||||||
public type: Type = Type.TYPE_HUMAN;
|
public type: Type = Type.TYPE_HUMAN;
|
||||||
|
|
||||||
constructor(public translate: TranslateService, activatedRoute: ActivatedRoute, breadcrumbService: BreadcrumbService) {
|
constructor(
|
||||||
|
public translate: TranslateService,
|
||||||
|
activatedRoute: ActivatedRoute,
|
||||||
|
breadcrumbService: BreadcrumbService,
|
||||||
|
) {
|
||||||
activatedRoute.queryParams.pipe(take(1)).subscribe((params: Params) => {
|
activatedRoute.queryParams.pipe(take(1)).subscribe((params: Params) => {
|
||||||
const { type } = params;
|
const { type } = params;
|
||||||
if (type && type === 'human') {
|
if (type && type === 'human') {
|
||||||
|
@ -124,6 +124,20 @@
|
|||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container matColumnDef="preferredLoginName">
|
||||||
|
<th
|
||||||
|
mat-header-cell
|
||||||
|
*matHeaderCellDef
|
||||||
|
mat-sort-header
|
||||||
|
[ngClass]="{ 'search-active': this.userSearchKey === UserListSearchKey.DISPLAY_NAME }"
|
||||||
|
>
|
||||||
|
{{ 'USER.PROFILE.PREFERREDLOGINNAME' | translate }}
|
||||||
|
</th>
|
||||||
|
<td mat-cell *matCellDef="let user" [routerLink]="user.id ? ['/users', user.id] : null">
|
||||||
|
<span *ngIf="user.human">{{ user.preferredLoginName }}</span>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="username">
|
<ng-container matColumnDef="username">
|
||||||
<th
|
<th
|
||||||
mat-header-cell
|
mat-header-cell
|
||||||
|
@ -51,7 +51,7 @@ export class UserTableComponent implements OnInit {
|
|||||||
@Input() public displayedColumnsHuman: string[] = [
|
@Input() public displayedColumnsHuman: string[] = [
|
||||||
'select',
|
'select',
|
||||||
'displayName',
|
'displayName',
|
||||||
'username',
|
'preferredLoginName',
|
||||||
'email',
|
'email',
|
||||||
'state',
|
'state',
|
||||||
'creationDate',
|
'creationDate',
|
||||||
@ -194,6 +194,10 @@ export class UserTableComponent implements OnInit {
|
|||||||
case 'username':
|
case 'username':
|
||||||
sortingField = UserFieldName.USER_FIELD_NAME_USER_NAME;
|
sortingField = UserFieldName.USER_FIELD_NAME_USER_NAME;
|
||||||
break;
|
break;
|
||||||
|
case 'preferredLoginName':
|
||||||
|
// TODO: replace with preferred username sorting once implemented
|
||||||
|
sortingField = UserFieldName.USER_FIELD_NAME_USER_NAME;
|
||||||
|
break;
|
||||||
case 'email':
|
case 'email':
|
||||||
sortingField = UserFieldName.USER_FIELD_NAME_EMAIL;
|
sortingField = UserFieldName.USER_FIELD_NAME_EMAIL;
|
||||||
break;
|
break;
|
||||||
|
@ -390,7 +390,10 @@ export class AdminService {
|
|||||||
public progressTotal: BehaviorSubject<number> = new BehaviorSubject(0);
|
public progressTotal: BehaviorSubject<number> = new BehaviorSubject(0);
|
||||||
public progressAllDone: BehaviorSubject<boolean> = new BehaviorSubject(true);
|
public progressAllDone: BehaviorSubject<boolean> = new BehaviorSubject(true);
|
||||||
|
|
||||||
constructor(private readonly grpcService: GrpcService, private storageService: StorageService) {
|
constructor(
|
||||||
|
private readonly grpcService: GrpcService,
|
||||||
|
private storageService: StorageService,
|
||||||
|
) {
|
||||||
this.progressEvents$.subscribe(this.progressEvents);
|
this.progressEvents$.subscribe(this.progressEvents);
|
||||||
|
|
||||||
this.hideOnboarding =
|
this.hideOnboarding =
|
||||||
|
@ -71,7 +71,11 @@ export const ENDPOINT = {
|
|||||||
})
|
})
|
||||||
export class AssetService {
|
export class AssetService {
|
||||||
private accessToken: string = '';
|
private accessToken: string = '';
|
||||||
constructor(private envService: EnvironmentService, private http: HttpClient, private storageService: StorageService) {
|
constructor(
|
||||||
|
private envService: EnvironmentService,
|
||||||
|
private http: HttpClient,
|
||||||
|
private storageService: StorageService,
|
||||||
|
) {
|
||||||
const aT = this.storageService.getItem(accessTokenStorageKey);
|
const aT = this.storageService.getItem(accessTokenStorageKey);
|
||||||
if (aT) {
|
if (aT) {
|
||||||
this.accessToken = aT;
|
this.accessToken = aT;
|
||||||
|
@ -12,7 +12,10 @@ export class AuthenticationService {
|
|||||||
private _authenticated: boolean = false;
|
private _authenticated: boolean = false;
|
||||||
private readonly _authenticationChanged: BehaviorSubject<boolean> = new BehaviorSubject(this.authenticated);
|
private readonly _authenticationChanged: BehaviorSubject<boolean> = new BehaviorSubject(this.authenticated);
|
||||||
|
|
||||||
constructor(private oauthService: OAuthService, private statehandler: StatehandlerService) {}
|
constructor(
|
||||||
|
private oauthService: OAuthService,
|
||||||
|
private statehandler: StatehandlerService,
|
||||||
|
) {}
|
||||||
|
|
||||||
public initConfig(data: AuthConfig): void {
|
public initConfig(data: AuthConfig): void {
|
||||||
this.authConfig = data;
|
this.authConfig = data;
|
||||||
|
@ -36,7 +36,10 @@ export class EnvironmentService {
|
|||||||
private environment$: Observable<Environment>;
|
private environment$: Observable<Environment>;
|
||||||
private wellKnown$: Observable<WellKnown>;
|
private wellKnown$: Observable<WellKnown>;
|
||||||
|
|
||||||
constructor(private http: HttpClient, private exhaustedSvc: ExhaustedService) {
|
constructor(
|
||||||
|
private http: HttpClient,
|
||||||
|
private exhaustedSvc: ExhaustedService,
|
||||||
|
) {
|
||||||
this.environment$ = this.createEnvironment();
|
this.environment$ = this.createEnvironment();
|
||||||
this.wellKnown$ = this.createWellKnown(this.environment$);
|
this.wellKnown$ = this.createWellKnown(this.environment$);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user