fix(console): apply labelpolicy if icon is provided, signout page (#4499)

* label policy as observable

* signedout policy via state

* add caching

* disable loading spinner on signedout

* cleanup

* catch error

* update deps

* move policy to localstorage

* handle labelpolicy for users without org

Co-authored-by: Livio Spring <livio.a@gmail.com>
Co-authored-by: Fabi <38692350+hifabienne@users.noreply.github.com>
This commit is contained in:
Max Peintner 2022-10-17 14:09:34 +02:00 committed by GitHub
parent bb16852e84
commit da51b481ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 355 additions and 536 deletions

View File

@ -31,7 +31,7 @@
"codemirror": "^5.65.8", "codemirror": "^5.65.8",
"cors": "^2.8.5", "cors": "^2.8.5",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"google-proto-files": "^3.0.0", "google-proto-files": "^3.0.2",
"google-protobuf": "^3.19.4", "google-protobuf": "^3.19.4",
"grpc-web": "^1.4.1", "grpc-web": "^1.4.1",
"libphonenumber-js": "^1.10.6", "libphonenumber-js": "^1.10.6",
@ -40,7 +40,7 @@
"ng-qrcode": "^7.0.0", "ng-qrcode": "^7.0.0",
"ngx-color": "^8.0.3", "ngx-color": "^8.0.3",
"ngx-quicklink": "^0.3.0", "ngx-quicklink": "^0.3.0",
"rxjs": "~7.5.2", "rxjs": "~7.5.7",
"tinycolor2": "^1.4.2", "tinycolor2": "^1.4.2",
"tslib": "^2.2.0", "tslib": "^2.2.0",
"uuid": "^9.0.0", "uuid": "^9.0.0",
@ -59,14 +59,14 @@
"@types/jasmine": "~4.3.0", "@types/jasmine": "~4.3.0",
"@types/jasminewd2": "~2.0.10", "@types/jasminewd2": "~2.0.10",
"@types/jsonwebtoken": "^8.5.5", "@types/jsonwebtoken": "^8.5.5",
"@types/node": "^18.7.16", "@types/node": "^18.8.1",
"@typescript-eslint/eslint-plugin": "5.38.1", "@typescript-eslint/eslint-plugin": "5.39.0",
"@typescript-eslint/parser": "5.36.1", "@typescript-eslint/parser": "5.39.0",
"codelyzer": "^6.0.0", "codelyzer": "^6.0.0",
"eslint": "^8.24.0", "eslint": "^8.24.0",
"jasmine-core": "~4.4.0", "jasmine-core": "~4.4.0",
"jasmine-spec-reporter": "~7.0.0", "jasmine-spec-reporter": "~7.0.0",
"karma": "~6.4.0", "karma": "~6.4.1",
"karma-chrome-launcher": "~3.1.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2", "karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~5.1.0", "karma-jasmine": "~5.1.0",
@ -3588,9 +3588,9 @@
"dev": true "dev": true
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "18.7.16", "version": "18.8.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.2.tgz",
"integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" "integrity": "sha512-cRMwIgdDN43GO4xMWAfJAecYn8wV4JbsOGHNfNUIDiuYkUYAR5ec4Rj7IO2SAhFPEfpPtLtUTbbny/TCT7aDwA=="
}, },
"node_modules/@types/parse-json": { "node_modules/@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
@ -3679,14 +3679,14 @@
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz",
"integrity": "sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ==", "integrity": "sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.38.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/type-utils": "5.38.1", "@typescript-eslint/type-utils": "5.39.0",
"@typescript-eslint/utils": "5.38.1", "@typescript-eslint/utils": "5.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
"regexpp": "^3.2.0", "regexpp": "^3.2.0",
@ -3710,73 +3710,16 @@
} }
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz",
"integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz",
"integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz",
"integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz",
"integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", "integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.38.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.38.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.38.1", "@typescript-eslint/typescript-estree": "5.39.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
}, },
@ -3791,32 +3734,15 @@
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz",
"integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.38.1",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.39.0.tgz",
"integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", "integrity": "sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.36.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.36.1", "@typescript-eslint/typescript-estree": "5.39.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -3836,13 +3762,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz",
"integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", "integrity": "sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.36.1" "@typescript-eslint/visitor-keys": "5.39.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -3853,13 +3779,13 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz",
"integrity": "sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw==", "integrity": "sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "5.38.1", "@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/utils": "5.38.1", "@typescript-eslint/utils": "5.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
@ -3879,73 +3805,16 @@
} }
} }
}, },
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz",
"integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz",
"integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz",
"integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz",
"integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", "integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.38.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.38.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.38.1", "@typescript-eslint/typescript-estree": "5.39.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
}, },
@ -3960,27 +3829,10 @@
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
} }
}, },
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz",
"integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.38.1",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz",
"integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", "integrity": "sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -3991,13 +3843,13 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz",
"integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", "integrity": "sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.36.1", "@typescript-eslint/visitor-keys": "5.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -4116,12 +3968,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz",
"integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", "integrity": "sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -7803,12 +7655,6 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true "dev": true
}, },
"node_modules/functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
"dev": true
},
"node_modules/gauge": { "node_modules/gauge": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
@ -7956,9 +7802,9 @@
} }
}, },
"node_modules/google-proto-files": { "node_modules/google-proto-files": {
"version": "3.0.1", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-3.0.1.tgz", "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-3.0.2.tgz",
"integrity": "sha512-YRDk4sihC20A2Rb9jpuSPV+Agfsr4TTNV50ISTBNiQZQHUxff7I4awg+dMIEfR8ZmYMqYC2nS++Z3HH42WUzwg==", "integrity": "sha512-NJOCeNrhH4cScdi+XdCGaqNclqOrt+Qsc8xzOjgwYfcksg1HXBnTCxBhiFvqbavv2vIYmHpm3Ri1QL9xW+UgoQ==",
"dependencies": { "dependencies": {
"protobufjs": "^7.0.0", "protobufjs": "^7.0.0",
"walkdir": "^0.4.0" "walkdir": "^0.4.0"
@ -9323,9 +9169,9 @@
} }
}, },
"node_modules/karma": { "node_modules/karma": {
"version": "6.4.0", "version": "6.4.1",
"resolved": "https://registry.npmjs.org/karma/-/karma-6.4.0.tgz", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz",
"integrity": "sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w==", "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@colors/colors": "1.5.0", "@colors/colors": "1.5.0",
@ -13029,9 +12875,9 @@
} }
}, },
"node_modules/rxjs": { "node_modules/rxjs": {
"version": "7.5.6", "version": "7.5.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
"integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
"dependencies": { "dependencies": {
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }
@ -17984,9 +17830,9 @@
"dev": true "dev": true
}, },
"@types/node": { "@types/node": {
"version": "18.7.16", "version": "18.8.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.16.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.2.tgz",
"integrity": "sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==" "integrity": "sha512-cRMwIgdDN43GO4xMWAfJAecYn8wV4JbsOGHNfNUIDiuYkUYAR5ec4Rj7IO2SAhFPEfpPtLtUTbbny/TCT7aDwA=="
}, },
"@types/parse-json": { "@types/parse-json": {
"version": "4.0.0", "version": "4.0.0",
@ -18075,14 +17921,14 @@
} }
}, },
"@typescript-eslint/eslint-plugin": { "@typescript-eslint/eslint-plugin": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz",
"integrity": "sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ==", "integrity": "sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.38.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/type-utils": "5.38.1", "@typescript-eslint/type-utils": "5.39.0",
"@typescript-eslint/utils": "5.38.1", "@typescript-eslint/utils": "5.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ignore": "^5.2.0", "ignore": "^5.2.0",
"regexpp": "^3.2.0", "regexpp": "^3.2.0",
@ -18090,168 +17936,86 @@
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz",
"integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1"
}
},
"@typescript-eslint/types": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz",
"integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz",
"integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/utils": { "@typescript-eslint/utils": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz",
"integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", "integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.38.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.38.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.38.1", "@typescript-eslint/typescript-estree": "5.39.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
} }
},
"@typescript-eslint/visitor-keys": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz",
"integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.38.1",
"eslint-visitor-keys": "^3.3.0"
}
} }
} }
}, },
"@typescript-eslint/parser": { "@typescript-eslint/parser": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.39.0.tgz",
"integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", "integrity": "sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/scope-manager": "5.36.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.36.1", "@typescript-eslint/typescript-estree": "5.39.0",
"debug": "^4.3.4" "debug": "^4.3.4"
} }
}, },
"@typescript-eslint/scope-manager": { "@typescript-eslint/scope-manager": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz",
"integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", "integrity": "sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.36.1" "@typescript-eslint/visitor-keys": "5.39.0"
} }
}, },
"@typescript-eslint/type-utils": { "@typescript-eslint/type-utils": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz",
"integrity": "sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw==", "integrity": "sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/typescript-estree": "5.38.1", "@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/utils": "5.38.1", "@typescript-eslint/utils": "5.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"tsutils": "^3.21.0" "tsutils": "^3.21.0"
}, },
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz",
"integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1"
}
},
"@typescript-eslint/types": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz",
"integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz",
"integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.38.1",
"@typescript-eslint/visitor-keys": "5.38.1",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
"semver": "^7.3.7",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/utils": { "@typescript-eslint/utils": {
"version": "5.38.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz",
"integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", "integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/json-schema": "^7.0.9", "@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.38.1", "@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.38.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.38.1", "@typescript-eslint/typescript-estree": "5.39.0",
"eslint-scope": "^5.1.1", "eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0" "eslint-utils": "^3.0.0"
} }
},
"@typescript-eslint/visitor-keys": {
"version": "5.38.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz",
"integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.38.1",
"eslint-visitor-keys": "^3.3.0"
}
} }
} }
}, },
"@typescript-eslint/types": { "@typescript-eslint/types": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz",
"integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", "integrity": "sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==",
"dev": true "dev": true
}, },
"@typescript-eslint/typescript-estree": { "@typescript-eslint/typescript-estree": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz",
"integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", "integrity": "sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.36.1", "@typescript-eslint/visitor-keys": "5.39.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -18317,12 +18081,12 @@
} }
}, },
"@typescript-eslint/visitor-keys": { "@typescript-eslint/visitor-keys": {
"version": "5.36.1", "version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz",
"integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", "integrity": "sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@typescript-eslint/types": "5.36.1", "@typescript-eslint/types": "5.39.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
} }
}, },
@ -21134,12 +20898,6 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true "dev": true
}, },
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
"dev": true
},
"gauge": { "gauge": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
@ -21248,9 +21006,9 @@
} }
}, },
"google-proto-files": { "google-proto-files": {
"version": "3.0.1", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-3.0.1.tgz", "resolved": "https://registry.npmjs.org/google-proto-files/-/google-proto-files-3.0.2.tgz",
"integrity": "sha512-YRDk4sihC20A2Rb9jpuSPV+Agfsr4TTNV50ISTBNiQZQHUxff7I4awg+dMIEfR8ZmYMqYC2nS++Z3HH42WUzwg==", "integrity": "sha512-NJOCeNrhH4cScdi+XdCGaqNclqOrt+Qsc8xzOjgwYfcksg1HXBnTCxBhiFvqbavv2vIYmHpm3Ri1QL9xW+UgoQ==",
"requires": { "requires": {
"protobufjs": "^7.0.0", "protobufjs": "^7.0.0",
"walkdir": "^0.4.0" "walkdir": "^0.4.0"
@ -22318,9 +22076,9 @@
} }
}, },
"karma": { "karma": {
"version": "6.4.0", "version": "6.4.1",
"resolved": "https://registry.npmjs.org/karma/-/karma-6.4.0.tgz", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz",
"integrity": "sha512-s8m7z0IF5g/bS5ONT7wsOavhW4i4aFkzD4u4wgzAQWT4HGUeWI3i21cK2Yz6jndMAeHETp5XuNsRoyGJZXVd4w==", "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@colors/colors": "1.5.0", "@colors/colors": "1.5.0",
@ -25021,9 +24779,9 @@
} }
}, },
"rxjs": { "rxjs": {
"version": "7.5.6", "version": "7.5.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.7.tgz",
"integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", "integrity": "sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==",
"requires": { "requires": {
"tslib": "^2.1.0" "tslib": "^2.1.0"
} }

View File

@ -35,7 +35,7 @@
"codemirror": "^5.65.8", "codemirror": "^5.65.8",
"cors": "^2.8.5", "cors": "^2.8.5",
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"google-proto-files": "^3.0.0", "google-proto-files": "^3.0.2",
"google-protobuf": "^3.19.4", "google-protobuf": "^3.19.4",
"grpc-web": "^1.4.1", "grpc-web": "^1.4.1",
"libphonenumber-js": "^1.10.6", "libphonenumber-js": "^1.10.6",
@ -44,7 +44,7 @@
"ng-qrcode": "^7.0.0", "ng-qrcode": "^7.0.0",
"ngx-color": "^8.0.3", "ngx-color": "^8.0.3",
"ngx-quicklink": "^0.3.0", "ngx-quicklink": "^0.3.0",
"rxjs": "~7.5.2", "rxjs": "~7.5.7",
"tinycolor2": "^1.4.2", "tinycolor2": "^1.4.2",
"tslib": "^2.2.0", "tslib": "^2.2.0",
"uuid": "^9.0.0", "uuid": "^9.0.0",
@ -63,14 +63,14 @@
"@types/jasmine": "~4.3.0", "@types/jasmine": "~4.3.0",
"@types/jasminewd2": "~2.0.10", "@types/jasminewd2": "~2.0.10",
"@types/jsonwebtoken": "^8.5.5", "@types/jsonwebtoken": "^8.5.5",
"@types/node": "^18.7.16", "@types/node": "^18.8.1",
"@typescript-eslint/eslint-plugin": "5.38.1", "@typescript-eslint/eslint-plugin": "5.39.0",
"@typescript-eslint/parser": "5.36.1", "@typescript-eslint/parser": "5.39.0",
"codelyzer": "^6.0.0", "codelyzer": "^6.0.0",
"eslint": "^8.24.0", "eslint": "^8.24.0",
"jasmine-core": "~4.4.0", "jasmine-core": "~4.4.0",
"jasmine-spec-reporter": "~7.0.0", "jasmine-spec-reporter": "~7.0.0",
"karma": "~6.4.0", "karma": "~6.4.1",
"karma-chrome-launcher": "~3.1.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2", "karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~5.1.0", "karma-jasmine": "~5.1.0",
@ -79,4 +79,4 @@
"protractor": "~7.0.0", "protractor": "~7.0.0",
"typescript": "^4.8.4" "typescript": "^4.8.4"
} }
} }

View File

@ -5,7 +5,6 @@
[org]="org" [org]="org"
[user]="$any(user)" [user]="$any(user)"
[isDarkTheme]="componentCssClass === 'dark-theme'" [isDarkTheme]="componentCssClass === 'dark-theme'"
[labelpolicy]="labelpolicy"
(changedActiveOrg)="changedOrg($event)" (changedActiveOrg)="changedOrg($event)"
></cnsl-header> ></cnsl-header>
@ -17,7 +16,6 @@
[org]="org" [org]="org"
[user]="$any(user)" [user]="$any(user)"
[isDarkTheme]="componentCssClass === 'dark-theme'" [isDarkTheme]="componentCssClass === 'dark-theme'"
[labelpolicy]="labelpolicy"
></cnsl-nav> ></cnsl-nav>
</ng-container> </ng-container>
@ -27,5 +25,5 @@
</div> </div>
</div> </div>
<span class="fill-space"></span> <span class="fill-space"></span>
<cnsl-footer [privateLabelPolicy]="labelpolicy"></cnsl-footer> <cnsl-footer></cnsl-footer>
</div> </div>

View File

@ -8,11 +8,11 @@ import { DomSanitizer } from '@angular/platform-browser';
import { ActivatedRoute, Router, RouterOutlet } from '@angular/router'; import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';
import { LangChangeEvent, TranslateService } from '@ngx-translate/core'; import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
import { Observable, of, Subject } from 'rxjs'; import { Observable, of, Subject } from 'rxjs';
import { map, take, takeUntil } from 'rxjs/operators'; import { map, takeUntil } from 'rxjs/operators';
import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations'; import { accountCard, adminLineAnimation, navAnimations, routeAnimations, toolbarAnimation } from './animations';
import { Org } from './proto/generated/zitadel/org_pb'; import { Org } from './proto/generated/zitadel/org_pb';
import { LabelPolicy, PrivacyPolicy } from './proto/generated/zitadel/policy_pb'; import { PrivacyPolicy } from './proto/generated/zitadel/policy_pb';
import { AuthenticationService } from './services/authentication.service'; import { AuthenticationService } from './services/authentication.service';
import { GrpcAuthService } from './services/grpc-auth.service'; import { GrpcAuthService } from './services/grpc-auth.service';
import { KeyboardShortcutsService } from './services/keyboard-shortcuts/keyboard-shortcuts.service'; import { KeyboardShortcutsService } from './services/keyboard-shortcuts/keyboard-shortcuts.service';
@ -47,7 +47,6 @@ export class AppComponent implements OnDestroy {
public showProjectSection: boolean = false; public showProjectSection: boolean = false;
private destroy$: Subject<void> = new Subject(); private destroy$: Subject<void> = new Subject();
public labelpolicy: LabelPolicy.AsObject | undefined = undefined;
public language: string = 'en'; public language: string = 'en';
public privacyPolicy!: PrivacyPolicy.AsObject; public privacyPolicy!: PrivacyPolicy.AsObject;
@ -69,7 +68,6 @@ export class AppComponent implements OnDestroy {
private activatedRoute: ActivatedRoute, private activatedRoute: ActivatedRoute,
@Inject(DOCUMENT) private document: Document, @Inject(DOCUMENT) private document: Document,
) { ) {
this.themeService.loadPrivateLabelling(true);
console.log( console.log(
'%cWait!', '%cWait!',
'text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; color: #5469D4; font-size: 50px', 'text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; color: #5469D4; font-size: 50px',
@ -187,8 +185,10 @@ export class AppComponent implements OnDestroy {
this.getProjectCount(); this.getProjectCount();
this.authService.activeOrgChanged.pipe(takeUntil(this.destroy$)).subscribe((org) => { this.authService.activeOrgChanged.pipe(takeUntil(this.destroy$)).subscribe((org) => {
this.org = org; if (org) {
this.getProjectCount(); this.org = org;
this.getProjectCount();
}
}); });
this.authenticationService.authenticationChanged.pipe(takeUntil(this.destroy$)).subscribe((authenticated) => { this.authenticationService.authenticationChanged.pipe(takeUntil(this.destroy$)).subscribe((authenticated) => {
@ -197,10 +197,7 @@ export class AppComponent implements OnDestroy {
.getActiveOrg() .getActiveOrg()
.then(async (org) => { .then(async (org) => {
this.org = org; this.org = org;
const policy = await this.themeService.loadPrivateLabelling();
if (policy) {
this.labelpolicy = policy;
}
// TODO add when console storage is implemented // TODO add when console storage is implemented
// this.startIntroWorkflow(); // this.startIntroWorkflow();
}) })
@ -252,7 +249,6 @@ export class AppComponent implements OnDestroy {
} }
public changedOrg(org: Org.AsObject): void { public changedOrg(org: Org.AsObject): void {
this.themeService.loadPrivateLabelling();
this.router.navigate(['/org']); this.router.navigate(['/org']);
} }

View File

@ -64,6 +64,9 @@ export class AccountsCardComponent implements OnInit {
} }
public logout(): void { public logout(): void {
const lP = JSON.stringify(this.userService.labelpolicy.getValue());
localStorage.setItem('labelPolicyOnSignout', lP);
this.authService.signout(); this.authService.signout();
this.closedCard.emit(); this.closedCard.emit();
} }

View File

@ -11,22 +11,24 @@
</a> </a>
</div> </div>
<div class="footer-socials" *ngIf="!privateLabelPolicy || privateLabelPolicy?.disableWatermark === false"> <div class="footer-socials" *ngIf="authService.labelpolicy | async as lP">
<a target="_blank" rel="noreferrer" href="https://github.com/zitadel"> <ng-container *ngIf="lP?.disableWatermark === false">
<i class="text-3xl lab la-github"></i> <a target="_blank" rel="noreferrer" href="https://github.com/zitadel">
</a> <i class="text-3xl lab la-github"></i>
<a target="_blank" rel="noreferrer" href="https://twitter.com/zitadel"> </a>
<i class="text-3xl lab la-twitter"></i> <a target="_blank" rel="noreferrer" href="https://twitter.com/zitadel">
</a> <i class="text-3xl lab la-twitter"></i>
<a target="_blank" rel="noreferrer" href="https://www.linkedin.com/company/zitadel/"> </a>
<i class="text-3xl lab la-linkedin"></i> <a target="_blank" rel="noreferrer" href="https://www.linkedin.com/company/zitadel/">
</a> <i class="text-3xl lab la-linkedin"></i>
<a target="_blank" rel="noreferrer" href="https://zitadel.com/chat"> </a>
<i class="text-3xl lab la-discord"></i> <a target="_blank" rel="noreferrer" href="https://zitadel.com/chat">
</a> <i class="text-3xl lab la-discord"></i>
<a target="_blank" rel="noreferrer" href="https://www.youtube.com/channel/UCUAWJUNYaRn1yIVrZxEfsuA"> </a>
<i class="text-3xl lab la-youtube"></i> <a target="_blank" rel="noreferrer" href="https://www.youtube.com/channel/UCUAWJUNYaRn1yIVrZxEfsuA">
</a> <i class="text-3xl lab la-youtube"></i>
</a>
</ng-container>
</div> </div>
<div class="theme"> <div class="theme">

View File

@ -9,8 +9,7 @@ import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
}) })
export class FooterComponent { export class FooterComponent {
public policy?: PrivacyPolicy.AsObject; public policy?: PrivacyPolicy.AsObject;
@Input() public privateLabelPolicy?: LabelPolicy.AsObject; constructor(public authService: GrpcAuthService) {
constructor(authService: GrpcAuthService) {
authService.getMyPrivacyPolicy().then((policyResp) => { authService.getMyPrivacyPolicy().then((policyResp) => {
if (policyResp.policy) { if (policyResp.policy) {
this.policy = policyResp.policy; this.policy = policyResp.policy;

View File

@ -1,26 +1,27 @@
<mat-toolbar class="header-wrapper"> <mat-toolbar class="header-wrapper">
<div class="header-content"> <div class="header-content">
<a <div *ngIf="authService.labelPolicyLoading$ | async; else logo" class="logo-placeholder">
class="title custom" <mat-spinner [diameter]="20"></mat-spinner>
[routerLink]="['/']" </div>
*ngIf="org && labelpolicy && labelpolicy.disableWatermark; else defaultHome" <ng-template #logo>
> <a class="title custom" [routerLink]="['/']" *ngIf="authService.labelpolicy | async as lP; else defaultHome">
<img
class="logo"
alt="home logo"
*ngIf="isDarkTheme; else customlighttheme"
[src]="labelpolicy.iconUrlDark ? labelpolicy.iconUrlDark : './assets/images/zitadel-logo-solo-light.svg'"
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-light.svg')"
/>
<ng-template #customlighttheme>
<img <img
alt="home logo"
class="logo" class="logo"
[src]="labelpolicy.iconUrl ? labelpolicy.iconUrl : './assets/images/zitadel-logo-solo-dark.svg'" alt="home logo"
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-dark.svg')" *ngIf="isDarkTheme; else customlighttheme"
[src]="lP.iconUrlDark ? lP.iconUrlDark : './assets/images/zitadel-logo-solo-light.svg'"
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-light.svg')"
/> />
</ng-template> <ng-template #customlighttheme>
</a> <img
alt="home logo"
class="logo"
[src]="lP.iconUrl ? lP.iconUrl : './assets/images/zitadel-logo-solo-dark.svg'"
(error)="errorHandler($event, './assets/images/zitadel-logo-solo-dark.svg')"
/>
</ng-template>
</a>
</ng-template>
<ng-template #defaultHome> <ng-template #defaultHome>
<a class="title" [routerLink]="authService.zitadelPermissions.getValue().length === 0 ? ['/users', 'me'] : ['/']"> <a class="title" [routerLink]="authService.zitadelPermissions.getValue().length === 0 ? ['/users', 'me'] : ['/']">

View File

@ -181,6 +181,16 @@
} }
} }
.logo-placeholder {
height: 40px;
width: 40px;
border-radius: 50%;
background-color: if($is-dark-theme, #00000020, #00000010);
display: flex;
align-items: center;
justify-content: center;
}
.title { .title {
text-decoration: none; text-decoration: none;
color: white; color: white;

View File

@ -22,7 +22,6 @@ export class HeaderComponent implements OnDestroy {
@Input() public isDarkTheme: boolean = true; @Input() public isDarkTheme: boolean = true;
@Input() public user?: User.AsObject; @Input() public user?: User.AsObject;
@Input() public labelpolicy?: LabelPolicy.AsObject;
public showOrgContext: boolean = false; public showOrgContext: boolean = false;
public orgs$: Observable<Org.AsObject[]> = of([]); public orgs$: Observable<Org.AsObject[]> = of([]);

View File

@ -6,10 +6,10 @@ import { UntypedFormControl } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { BehaviorSubject, map, Observable, Subject, take } from 'rxjs'; import { BehaviorSubject, map, Observable, Subject, take } from 'rxjs';
import { Org } from 'src/app/proto/generated/zitadel/org_pb'; import { Org } from 'src/app/proto/generated/zitadel/org_pb';
import { LabelPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
import { User } from 'src/app/proto/generated/zitadel/user_pb'; import { User } from 'src/app/proto/generated/zitadel/user_pb';
import { AuthenticationService } from 'src/app/services/authentication.service'; import { AuthenticationService } from 'src/app/services/authentication.service';
import { BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service'; import { BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { KeyboardShortcutsService } from 'src/app/services/keyboard-shortcuts/keyboard-shortcuts.service'; import { KeyboardShortcutsService } from 'src/app/services/keyboard-shortcuts/keyboard-shortcuts.service';
import { ManagementService } from 'src/app/services/mgmt.service'; import { ManagementService } from 'src/app/services/mgmt.service';
@ -73,7 +73,6 @@ export class NavComponent implements OnDestroy {
@Input() public isDarkTheme: boolean = true; @Input() public isDarkTheme: boolean = true;
@Input() public user!: User.AsObject; @Input() public user!: User.AsObject;
@Input() public labelpolicy?: LabelPolicy.AsObject;
public isHandset$: Observable<boolean> = this.breakpointObserver.observe('(max-width: 599px)').pipe( public isHandset$: Observable<boolean> = this.breakpointObserver.observe('(max-width: 599px)').pipe(
map((result) => { map((result) => {
return result.matches; return result.matches;
@ -91,6 +90,7 @@ export class NavComponent implements OnDestroy {
public customerPortalLink: string = ''; public customerPortalLink: string = '';
constructor( constructor(
public authService: GrpcAuthService,
public authenticationService: AuthenticationService, public authenticationService: AuthenticationService,
public breadcrumbService: BreadcrumbService, public breadcrumbService: BreadcrumbService,
public mgmtService: ManagementService, public mgmtService: ManagementService,

View File

@ -57,7 +57,6 @@ export class OrgTableComponent {
private router: Router, private router: Router,
private toast: ToastService, private toast: ToastService,
private _liveAnnouncer: LiveAnnouncer, private _liveAnnouncer: LiveAnnouncer,
private themeService: ThemeService,
) { ) {
this.requestOrgs$.next({ limit: this.initialLimit, offset: 0, queries: this.searchQueries }); this.requestOrgs$.next({ limit: this.initialLimit, offset: 0, queries: this.searchQueries });
this.authService.getActiveOrg().then((org) => (this.activeOrg = org)); this.authService.getActiveOrg().then((org) => (this.activeOrg = org));
@ -137,7 +136,6 @@ export class OrgTableComponent {
public setAndNavigateToOrg(org: Org.AsObject): void { public setAndNavigateToOrg(org: Org.AsObject): void {
this.authService.setActiveOrg(org); this.authService.setActiveOrg(org);
this.themeService.loadPrivateLabelling();
this.router.navigate(['/org']); this.router.navigate(['/org']);
} }

View File

@ -1,13 +1,23 @@
<div class="signed-out-wrap"> <div class="signed-out-wrap">
<div class="block"> <div class="block">
<div class="signed-out-header"> <div class="signed-out-header">
<img alt="zitadel logo" *ngIf="dark; else lighttheme" src="./assets/images/zitadel-logo-light.svg" /> <ng-container *ngIf="labelpolicy; else zitadelLogo">
<ng-template #lighttheme> <img alt="logo" *ngIf="dark && labelpolicy.logoUrlDark; else lighttheme" [src]="labelpolicy.logoUrlDark" />
<img alt="zitadel logo" src="./assets/images/zitadel-logo-dark.svg" /> <ng-template #lighttheme>
<img *ngIf="labelpolicy.logoUrl; else zitadelLogo" alt="logo" [src]="labelpolicy.logoUrl" />
</ng-template>
</ng-container>
<ng-template #zitadelLogo>
<img alt="zitadel logo" *ngIf="dark; else zitadellighttheme" src="./assets/images/zitadel-logo-light.svg" />
<ng-template #zitadellighttheme>
<img alt="zitadel logo" src="./assets/images/zitadel-logo-dark.svg" />
</ng-template>
</ng-template> </ng-template>
<p class="cnsl-secondary-text">{{ 'USER.SIGNEDOUT' | translate }}</p> <p class="cnsl-secondary-text">{{ 'USER.SIGNEDOUT' | translate }}</p>
<button <a
class="cnsl-action-button" class="cnsl-action-button"
matTooltip="{{ 'ACTIONS.LOGIN' | translate }}" matTooltip="{{ 'ACTIONS.LOGIN' | translate }}"
color="primary" color="primary"
@ -16,7 +26,7 @@
> >
<i class="las la-sign-in-alt"></i> <i class="las la-sign-in-alt"></i>
<span>{{ 'USER.SIGNEDOUT_BTN' | translate }}</span> <span>{{ 'USER.SIGNEDOUT_BTN' | translate }}</span>
</button> </a>
</div> </div>
</div> </div>
</div> </div>

View File

@ -18,8 +18,7 @@
p { p {
text-align: center; text-align: center;
font-size: 14px; font-size: 14px;
margin: 0; margin: 2rem 0 3rem 0;
margin-bottom: 3rem;
} }
img { img {

View File

@ -1,5 +1,8 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { LabelPolicy } from 'src/app/proto/generated/zitadel/policy_pb';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ThemeService } from 'src/app/services/theme.service'; import { ThemeService } from 'src/app/services/theme.service';
const LABELPOLICY_LOCALSTORAGE_KEY = 'labelPolicyOnSignout';
@Component({ @Component({
selector: 'cnsl-signedout', selector: 'cnsl-signedout',
@ -9,10 +12,25 @@ import { ThemeService } from 'src/app/services/theme.service';
export class SignedoutComponent { export class SignedoutComponent {
public dark: boolean = true; public dark: boolean = true;
constructor(themeService: ThemeService) { public labelpolicy?: LabelPolicy.AsObject;
themeService.loadPrivateLabelling(); public queryParams = { state: '' };
constructor(themeService: ThemeService, authService: GrpcAuthService) {
const theme = localStorage.getItem('theme'); const theme = localStorage.getItem('theme');
this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true; this.dark = theme === 'dark-theme' ? true : theme === 'light-theme' ? false : true;
const lP = localStorage.getItem(LABELPOLICY_LOCALSTORAGE_KEY);
if (lP) {
const parsed = JSON.parse(lP);
localStorage.removeItem(LABELPOLICY_LOCALSTORAGE_KEY);
if (parsed) {
this.labelpolicy = parsed;
themeService.applyLabelPolicy(parsed);
authService.labelpolicy.next(parsed);
authService.labelPolicyLoading$.next(false);
}
} else {
authService.labelPolicyLoading$.next(false);
}
} }
} }

View File

@ -1,6 +1,7 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { AuthConfig, OAuthService } from 'angular-oauth2-oidc'; import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
import { BehaviorSubject, from, lastValueFrom, Observable } from 'rxjs'; import { BehaviorSubject, from, lastValueFrom, Observable } from 'rxjs';
import { GrpcAuthService } from './grpc-auth.service';
import { StatehandlerService } from './statehandler/statehandler.service'; import { StatehandlerService } from './statehandler/statehandler.service';

View File

@ -9,8 +9,10 @@ import {
finalize, finalize,
map, map,
mergeMap, mergeMap,
pairwise,
switchMap, switchMap,
take, take,
tap,
timeout, timeout,
withLatestFrom, withLatestFrom,
} from 'rxjs/operators'; } from 'rxjs/operators';
@ -103,15 +105,17 @@ import { ChangeQuery } from '../proto/generated/zitadel/change_pb';
import { MetadataQuery } from '../proto/generated/zitadel/metadata_pb'; import { MetadataQuery } from '../proto/generated/zitadel/metadata_pb';
import { ListQuery } from '../proto/generated/zitadel/object_pb'; import { ListQuery } from '../proto/generated/zitadel/object_pb';
import { Org, OrgFieldName, OrgQuery } from '../proto/generated/zitadel/org_pb'; import { Org, OrgFieldName, OrgQuery } from '../proto/generated/zitadel/org_pb';
import { LabelPolicy } from '../proto/generated/zitadel/policy_pb';
import { Gender, MembershipQuery, User, WebAuthNVerification } from '../proto/generated/zitadel/user_pb'; import { Gender, MembershipQuery, User, WebAuthNVerification } from '../proto/generated/zitadel/user_pb';
import { GrpcService } from './grpc.service'; import { GrpcService } from './grpc.service';
import { StorageKey, StorageLocation, StorageService } from './storage.service'; import { StorageKey, StorageLocation, StorageService } from './storage.service';
import { ThemeService } from './theme.service';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
}) })
export class GrpcAuthService { export class GrpcAuthService {
private _activeOrgChanged: Subject<Org.AsObject> = new Subject(); private _activeOrgChanged: Subject<Org.AsObject | undefined> = new Subject();
public user!: Observable<User.AsObject | undefined>; public user!: Observable<User.AsObject | undefined>;
public userSubject: BehaviorSubject<User.AsObject | undefined> = new BehaviorSubject<User.AsObject | undefined>(undefined); public userSubject: BehaviorSubject<User.AsObject | undefined> = new BehaviorSubject<User.AsObject | undefined>(undefined);
private triggerPermissionsRefresh: Subject<void> = new Subject(); private triggerPermissionsRefresh: Subject<void> = new Subject();
@ -132,18 +136,47 @@ export class GrpcAuthService {
), ),
), ),
); );
public labelpolicy$!: Observable<LabelPolicy.AsObject>;
public labelpolicy: BehaviorSubject<LabelPolicy.AsObject | undefined> = new BehaviorSubject<
LabelPolicy.AsObject | undefined
>(undefined);
labelPolicyLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
public zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]); public zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
private cachedOrgs: Org.AsObject[] = []; private cachedOrgs: Org.AsObject[] = [];
private cachedLabelPolicies: { [orgId: string]: LabelPolicy.AsObject } = {};
constructor( constructor(
private readonly grpcService: GrpcService, private readonly grpcService: GrpcService,
private oauthService: OAuthService, private oauthService: OAuthService,
private storage: StorageService, private storage: StorageService,
themeService: ThemeService,
) { ) {
this.zitadelPermissions$.subscribe(this.zitadelPermissions); this.zitadelPermissions$.subscribe(this.zitadelPermissions);
this.labelpolicy$ = this.activeOrgChanged.pipe(
switchMap((org) => {
this.labelPolicyLoading$.next(true);
return from(this.getMyLabelPolicy(org ? org.id : ''));
}),
filter((policy) => !!policy),
);
this.labelpolicy$.subscribe({
next: (policy) => {
themeService.applyLabelPolicy(policy);
this.labelpolicy.next(policy);
this.labelPolicyLoading$.next(false);
},
error: (error) => {
console.error(error);
this.labelPolicyLoading$.next(false);
},
});
this.user = merge( this.user = merge(
of(this.oauthService.getAccessToken()).pipe(filter((token) => (token ? true : false))), of(this.oauthService.getAccessToken()).pipe(filter((token) => (token ? true : false))),
this.oauthService.events.pipe( this.oauthService.events.pipe(
@ -225,10 +258,12 @@ export class GrpcAuthService {
const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.local); const org = this.storage.getItem<Org.AsObject>(StorageKey.organization, StorageLocation.local);
if (org && orgs.find((tmp) => tmp.id === org.id)) { if (org && orgs.find((tmp) => tmp.id === org.id)) {
this.storage.setItem(StorageKey.organization, org, StorageLocation.session); this.storage.setItem(StorageKey.organization, org, StorageLocation.session);
return org; this.setActiveOrg(org);
return Promise.resolve(org);
} }
if (orgs.length === 0) { if (orgs.length === 0) {
this._activeOrgChanged.next(undefined);
return Promise.reject(new Error('No organizations found!')); return Promise.reject(new Error('No organizations found!'));
} }
const orgToSet = orgs.find((element) => element.id !== '0' && element.name !== ''); const orgToSet = orgs.find((element) => element.id !== '0' && element.name !== '');
@ -241,7 +276,7 @@ export class GrpcAuthService {
} }
} }
public get activeOrgChanged(): Observable<Org.AsObject> { public get activeOrgChanged(): Observable<Org.AsObject | undefined> {
return this._activeOrgChanged; return this._activeOrgChanged;
} }
@ -605,8 +640,24 @@ export class GrpcAuthService {
return this.grpcService.auth.listMyUserChanges(req, null).then((resp) => resp.toObject()); return this.grpcService.auth.listMyUserChanges(req, null).then((resp) => resp.toObject());
} }
public getMyLabelPolicy(): Promise<GetMyLabelPolicyResponse.AsObject> { public getMyLabelPolicy(orgIdForCache?: string): Promise<LabelPolicy.AsObject> {
return this.grpcService.auth.getMyLabelPolicy(new GetMyLabelPolicyRequest(), null).then((resp) => resp.toObject()); if (orgIdForCache && this.cachedLabelPolicies[orgIdForCache]) {
return Promise.resolve(this.cachedLabelPolicies[orgIdForCache]);
} else {
return this.grpcService.auth
.getMyLabelPolicy(new GetMyLabelPolicyRequest(), null)
.then((resp) => resp.toObject())
.then((resp) => {
if (resp.policy) {
if (orgIdForCache) {
this.cachedLabelPolicies[orgIdForCache] = resp.policy;
}
return Promise.resolve(resp.policy);
} else {
return Promise.reject();
}
});
}
} }
public getMyPrivacyPolicy(): Promise<GetMyPrivacyPolicyResponse.AsObject> { public getMyPrivacyPolicy(): Promise<GetMyPrivacyPolicyResponse.AsObject> {

View File

@ -13,16 +13,28 @@ export interface Color {
contrastColor: string; contrastColor: string;
} }
const DARK_PRIMARY = '#bbbafa';
const PRIMARY = '#5469d4';
const DARK_WARN = '#ff3b5b';
const WARN = '#cd3d56';
const DARK_BACKGROUND = '#111827';
const BACKGROUND = '#fafafa';
const DARK_TEXT = '#ffffff';
const TEXT = '#000000';
@Injectable() @Injectable()
export class ThemeService { export class ThemeService {
private _darkTheme: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true); private _darkTheme: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
public isDarkTheme: Observable<boolean> = this._darkTheme.asObservable(); public isDarkTheme: Observable<boolean> = this._darkTheme.asObservable();
public loading: boolean = false;
private primaryColorPalette: Color[] = []; private primaryColorPalette: Color[] = [];
private warnColorPalette: Color[] = []; private warnColorPalette: Color[] = [];
private backgroundColorPalette: Color[] = []; private backgroundColorPalette: Color[] = [];
constructor(private authService: GrpcAuthService) { constructor() {
const theme = localStorage.getItem('theme'); const theme = localStorage.getItem('theme');
if (theme) { if (theme) {
if (theme === 'light-theme') { if (theme === 'light-theme') {
@ -31,6 +43,7 @@ export class ThemeService {
this.setDarkTheme(true); this.setDarkTheme(true);
} }
} }
this.applyLabelPolicy(); // apply default
} }
setDarkTheme(isDarkTheme: boolean): void { setDarkTheme(isDarkTheme: boolean): void {
@ -116,105 +129,68 @@ export class ThemeService {
} }
public setDefaultColors = () => { public setDefaultColors = () => {
const darkPrimary = '#bbbafa'; this.savePrimaryColor(DARK_PRIMARY, true);
const lightPrimary = '#5469d4'; this.savePrimaryColor(PRIMARY, false);
const darkWarn = '#ff3b5b'; this.saveWarnColor(DARK_WARN, true);
const lightWarn = '#cd3d56'; this.saveWarnColor(WARN, false);
const darkBackground = '#111827'; this.saveBackgroundColor(DARK_BACKGROUND, true);
const lightBackground = '#fafafa'; this.saveBackgroundColor(BACKGROUND, false);
const darkText = '#ffffff'; this.saveTextColor(DARK_TEXT, true);
const lightText = '#000000'; this.saveTextColor(TEXT, false);
this.savePrimaryColor(darkPrimary, true);
this.savePrimaryColor(lightPrimary, false);
this.saveWarnColor(darkWarn, true);
this.saveWarnColor(lightWarn, false);
this.saveBackgroundColor(darkBackground, true);
this.saveBackgroundColor(lightBackground, false);
this.saveTextColor(darkText, true);
this.saveTextColor(lightText, false);
}; };
public loadPrivateLabelling(forceDefault: boolean = false): Promise<LabelPolicy.AsObject | undefined> { public applyLabelPolicy(labelpolicy?: LabelPolicy.AsObject) {
if (forceDefault) { if (labelpolicy) {
this.setDefaultColors(); const darkPrimary = labelpolicy?.primaryColorDark ?? DARK_PRIMARY;
return Promise.resolve(undefined); const lightPrimary = labelpolicy?.primaryColor ?? PRIMARY;
const darkWarn = labelpolicy?.warnColorDark ?? DARK_WARN;
const lightWarn = labelpolicy?.warnColor ?? WARN;
let darkBackground = labelpolicy?.backgroundColorDark ?? DARK_BACKGROUND;
let lightBackground = labelpolicy?.backgroundColor ?? BACKGROUND;
let darkText = labelpolicy?.fontColorDark ?? DARK_TEXT;
let lightText = labelpolicy?.fontColor ?? TEXT;
this.savePrimaryColor(darkPrimary, true);
this.savePrimaryColor(lightPrimary, false);
this.saveWarnColor(darkWarn, true);
this.saveWarnColor(lightWarn, false);
if (darkBackground && !this.isDark(darkBackground)) {
console.info(
`Background (${darkBackground}) is not dark enough for a dark theme. Falling back to zitadel background`,
);
darkBackground = '#111827';
}
this.saveBackgroundColor(darkBackground || '#111827', true);
if (lightBackground && !this.isLight(lightBackground)) {
console.info(
`Background (${lightBackground}) is not light enough for a light theme. Falling back to zitadel background`,
);
lightBackground = '#fafafa';
}
this.saveBackgroundColor(lightBackground || '#fafafa', false);
if (darkText && !this.isLight(darkText)) {
console.info(`Text color (${darkText}) is not light enough for a dark theme. Falling back to zitadel's text color`);
darkText = '#ffffff';
}
this.saveTextColor(darkText || '#ffffff', true);
if (lightText && !this.isDark(lightText)) {
console.info(`Text color (${lightText}) is not dark enough for a light theme. Falling back to zitadel's text color`);
lightText = '#000000';
}
this.saveTextColor(lightText || '#000000', false);
} else { } else {
const isDark = (color: string) => this.isDark(color); this.setDefaultColors();
const isLight = (color: string) => this.isLight(color);
return this.authService
.getMyLabelPolicy()
.then((lpresp) => {
const labelpolicy = lpresp.policy;
const darkPrimary = labelpolicy?.primaryColorDark || '#bbbafa';
const lightPrimary = labelpolicy?.primaryColor || '#5469d4';
const darkWarn = labelpolicy?.warnColorDark || '#ff3b5b';
const lightWarn = labelpolicy?.warnColor || '#cd3d56';
let darkBackground = labelpolicy?.backgroundColorDark;
let lightBackground = labelpolicy?.backgroundColor;
let darkText = labelpolicy?.fontColorDark ?? '#ffffff';
let lightText = labelpolicy?.fontColor ?? '#000000';
this.savePrimaryColor(darkPrimary, true);
this.savePrimaryColor(lightPrimary, false);
this.saveWarnColor(darkWarn, true);
this.saveWarnColor(lightWarn, false);
if (darkBackground && !isDark(darkBackground)) {
console.info(
`Background (${darkBackground}) is not dark enough for a dark theme. Falling back to zitadel background`,
);
darkBackground = '#111827';
}
this.saveBackgroundColor(darkBackground || '#111827', true);
if (lightBackground && !isLight(lightBackground)) {
console.info(
`Background (${lightBackground}) is not light enough for a light theme. Falling back to zitadel background`,
);
lightBackground = '#fafafa';
}
this.saveBackgroundColor(lightBackground || '#fafafa', false);
if (darkText && !isLight(darkText)) {
console.info(
`Text color (${darkText}) is not light enough for a dark theme. Falling back to zitadel's text color`,
);
darkText = '#ffffff';
}
this.saveTextColor(darkText || '#ffffff', true);
if (lightText && !isDark(lightText)) {
console.info(
`Text color (${lightText}) is not dark enough for a light theme. Falling back to zitadel's text color`,
);
lightText = '#000000';
}
this.saveTextColor(lightText || '#000000', false);
if (labelpolicy) {
return labelpolicy;
} else {
return Promise.reject();
}
})
.catch((error) => {
console.error('could not load private labelling policy!', error);
this.setDefaultColors();
return Promise.reject();
});
} }
} }
} }